Best way to detect punch hits?

I see developers do it alot of different ways but the two most popular I see are hitboxes and magnitude checks, which one is better for detecting players in range and dealing damage to them, hitboxes or magnitude? In your fighting games or projects which one do you use?

1 Like

Hitboxes vs Distance

Hitboxes are the most common and useful, but easily broken system of hit detection. Most games like Street Fighter use it and the die hard fans study the hitboxes like its a new species. However, these games are infamous for broken or poorly fitted hitboxes.

The Distance choice may be a bit tougher and hard to use for compensation of lag, and may be more strenuous on the server, and perhaps using Player:DistanceFromCharacter() would be better than .magnitude,However you would have to make sure they’re also looking at the object.

I think this would be a better question of what are you aiming to do? Perhaps a fighting game would be useful to use hitboxes but something like hitting NPCs could be handy by using distance? If you’re just looking to find characters in a range, such as AoE, distance would be the better of the two. In my own, I’m using hitboxes but it’ll be more to determine what they hit rather than if they hit. Im no scripter so I wouldn’t take what I say as truth but maybe it’ll help

1 Like

(ArmLimb).Touched is the simplest and most straight forward. Unless you want more range out of your attacks, I’d just do this method, if not, use hitboxes.

1 Like

In the case of one thing hitting another thing, I typically go for hit boxes. They feel like the most appropriate technique for me as far as the systems go - aesthetics, damaging, all that. I try to avoid magnitude unless I absolutely cannot get hit boxes to function or I need to compensate for any specific variable. At times, I may even use the two of them at once - hit box for hits and magnitude for verification.

On a separate but unrelated note, I actually don’t use the magnitude of the distance between two positions. I instead use the function Player:DistanceFromCharacter. This passes my check to the backend (CPP over Lua implementation) and if for any reason the structure of a humanoid updates, I don’t need to change anything. The only thing I need to ensure is that the return value is non-zero.

Remember: HumanoidRootPart didn’t always exist. Checking for the existence of a root and grabbing the magnitude of the vector between one root and another can be considered reinventing the wheel for DistanceFromCharacter.

4 Likes

That’s a bit overkill. Firstly DistanceFromCharacter gets the magnitude from the players head to a vector3. Why not compare distances from the center of the character, the humanoidRootPart or Torso? Secondly if the player’s character is nil or their head is missing then DistanceFromCharacter returns 0… so open those arms up for bugs and unwanted features. Also validating with a non-zero value is also a bug - why should it flag false when the compared part is directly in the same position as the head?

I’m not entirely sure what point you’re trying to make here. I’ve already stated why I prefer this method. Telling me that my method is overkill without explaining why is a little much.

Non-problem. Even then, the same issues are present if you check between roots. The only bug to face is if you improperly handle that 0.

Distance > 0

1 Like

I assume using :DistanceFromCharacter is faster too right since its a inbuilt c++ function

2 Likes

lol I know this is just super random and called after like 2 years, but here’s what I got:

I work with a lot of models that contain like a 100+ parts so detecting collision is kinda weird

		NewThing.Touched:Connect(function(hit) -- Damage part for Shards
			if hit:FindFirstAncestorOfClass("Model") and hit:FindFirstAncestorOfClass("Model"):FindFirstChildOfClass("Humanoid") and NewThing:GetAttribute("AlreadyTouched") == false and not hit:IsDescendantOf(player.Character) then
				print(hit:FindFirstAncestorOfClass("Model") and hit:FindFirstAncestorOfClass("Model"):FindFirstChildOfClass("Humanoid").Name)
				NewThing:SetAttribute("AlreadyTouched", true)
				hit:FindFirstAncestorOfClass("Model"):FindFirstChildOfClass("Humanoid"):TakeDamage(20)
			else
				-- something else
			end
		end)

This does it for me.
if It hits another part then it just doesn’t care and continues to search for the model that has the humanoid as