Blocking Issues

Making a melee combat system. I am using this script to detect when the opponent is blocking, so the attacker cancels his animation and doesn’t do damage.

hitbox.OnHit:Connect(function(hit)
			if state == 2 then
				if hit.Name == "BlockPart" then
					stunned = true
					hitbox:HitStop()
					stopAnims()
					blockSound:Play()

I am using raycast hitbox, for those who don’t know what it is, it’s really irrelevant, you can imagine this as a basic touch event.

As You can see in this video, blocking sometimes doesn’t work and the opponent gets damaged. This happens because sometimes the ray (hitpart) hits the opponent’s body first, and only then blockpart (miliseconds difference). This mostly happens when the attack starts when the sword is already touching the body. I don’t want to make sword cancollide, because it brings other issues + it doesn’t solve this problem, I already tried.

I would much appreciate if you could explain how you handle blocking in your games, or offer solution on how to fix it in my case^

2 Likes

Look amazing and good job!!

for your future game!!

1 Like

Thanks ^^ If I figure out the blocking it will be even better xD

1 Like

LOL this will be even better lolll

I guess what the solution could be is instead of using a part make some sort of a custom made state, like a set attribute and if the NPC/player has the attribute the attack gets redirected to the block effects instead of damaging

1 Like

That won’t work, because I want the attacker to be blocked only if he’s attacking from front. So for example you block, but someone attacks you from behind, you should still take damage

There’s a feature for that as well, its called dot product. You can hook it up and only redirect to blocking if in front of the player.

1 Like

I’ll try to experiment with this tomorrow, but I’d like to achieve something more precise to the sword movement. Watch this video starting from 5:33.
[Video deleted]

As you can see, if the sword hits directly the shield, the attack gets blocked, in all other cases it doesn’t, which allows for players to bypass blocks by clever sword movement.

1 Like

If it hits the body instead of the blockpart first, something is probably wrong with your raycast.
I would check what’s going on with the rays but if you don’t feel like so, you can wait with damaging the player and then check if the attack was blocked.

local lastBlock = {}

hitbox.OnHit:Connect(function(hit)
  if hit.Name == 'Body' then
    task.wait(.2)
    if lastBlock[attacker] and tick() - lastBlock[attacker] < .4 then return end

    -- damage handling
  
  elseif hit.Name == 'Blockpart' then
    lastBlock[attacker] = tick()
  end
end

Remember about initializing lastBlock in PlayerAdded and removing player key in PlayerRemoving.

1 Like

Here’s how RayCast Hitbox works. The green circles you see are attachments. Every frame a ray is fired from all of the attachments. Once one of the rays hits something with a humanoid, none of the rays will hit anymore (to avoid doing multiple damages on one hit).

This is not so different to the regular .Touched Event, as if any pixel of the part touches another part, the event will fire.

There is nothing wrong with a ray, I see no other way of firing a ray and hit being accurate. If for example I fire a ray only from the middle of the sword, nothing will happen if the tip of the sword touches.

I can’t use your method, because if it hits the body, it won’t detect hits with the blockpart anymore, as the rays will stop firing on body hit.

Btw here’s the recourse I use for ray firing, if you want a more detailed explanation of how it works - Raycast Hitbox 4.01: For all your melee needs! - Resources / Community Resources - DevForum | Roblox

why don’t you get rid of the blockpart and just set an attribute on the enemy or other players model like Character:SetAttribute('Blocking', true) when they are blocking and when they stop or not blocking Character:SetAttribute('Blocking', nil)
check it with

if Character:GetAttribute('Blocking') then
     -- currently blocking
else
     -- not blocking
end

on and you will want to do this from a server script on set and unset that way all clients can see and also the server can see the attribute

Because as explained above, I want the attack to be blocked only if the sword hits the blocker’s sword or shield at the time of blocking. If I do it your way the attack will be blocked even when attacking from behind or any direction

not if you detect the hit on the other sword or shield first then check if the player or character is blocking

the way your doing it you would need to run 2 sets of raycast one to check for the blocking block first the other for the hit

I actually found a way to do this. I still keep detecting block the same way I was detecting before, but I added one thing.

If the ray touches the body, with :GetPartsInPart, I check if sword is touching a blockpart too. If yes, get blocked, if no, do the damage.

Thus achieving sword accurate hitbox. Thanks everyone for trying to help!

Oh, alright.
This part of your thread confused me:
This happens because sometimes the ray (hitpart) hits the opponent’s body first, and only then blockpart (miliseconds difference)