Making a making a hitbox more accurate?

So im making a hitbox system and im running into some really weird errors. The first is im using a touched event to detect and damage the player but the touched event doesnt fire because the hitbox is only in the game for 0.1 secs so it doesnt fire the touched event, therefore doesn’t damage the player, is there any way to fix this? The second is I weld the hitbox to the players hrp but by using that method the player can just spin around and damage anything around it which is why i dont wanna use welding. Whats the best way to make a hitbox? I already have the damage system down, im just wondering whats the best way to make the hitbox more accurate at touch and how to fix the problems i have above.

4 Likes

Hi!

For what exactly are you using this “hitbox” for? I’m not completely sure what you’re asking, or what scenario you’re talking about.

If you’re looking for players in specific region then you should check out FindPartsInRegion3.

If you’re looking for damaging players with a tool then you could either;
Check when a part hits the tool Handle (useful in a sword, for example)
Check what the player has clicked on and damage a player in a script without any physical parts (useful in a gun, for example)
Or
Weld an invisible, CanCollide = false part to the handle and damage players when hit (useful for a flamethrower, for example).

If you dont want a player to be able spin really fast and kill all the humanoid around them then perhaps you should add some kind of pause after hitting a player, using debounce for example:

--This is a rough mockup of code!
local gamePlayers = game:GetService("Players")
local debounce = false

Handle.Touched:Connect(part)
    if not debounce and gamePlayers:GetPlayerFromCharacter(part.Parent) then
        debounce = true
        delay(.5, function() debounce = false end)
        -- damage player
    end
end

Let me know if any of these helped, and if not please describe what you need in more detail!

Assuming your hitbox is a part with CanCollide false, you can call Part:GetTouchingParts as long as you have a function connected to its Touched event. The cool part is that the function binded can be empty, aka function() end.
There is another game that I have asked this question to which involves hitboxes, and they use magnitude checks instead of actual hitboxes to detect hits, which is inaccurate but still fast.

local hitbox = --Part
--Using Part:GetTouchingParts
local newHitbox = hitbox:Clone()
newHitbox.CFrame = --wherever its supposed to be
local localHumanoid = --local player's humanoid

newHitbox.Touched:Connect(function() end)
local alreadyHit= {[localHumanoid] = true}

for _,hit in pairs(newHitbox:GetTouchingParts()) do
	if HumanoidWasFound() and not alreadyHit[humanoid] then
		humanoid:TakeDamage(--[[damage]])
		alreadyHit[humanoid] = true
	end
end
newHitbox:Destroy()
--Using magnitude checks

local newHitbox = hitbox:Clone()
newHitbox.CFrame = --wherever its supposed to be
local distance = --number

for _,player in pairs(Players:GetPlayers()) do
	if player ~= LocalPlayer and CharacterWasFound() and HumanoidWasFound() then

		--you can also just check for the torso or even create custom
		--hurtboxes if you want it to be faster
		for _,part in pairs(character:GetChildren()) do
			if part:IsA("BasePart") and (part.Position - newHitbox.Position).Magnitude <= distance then
				humanoid:TakeDamage(--[[damage]])
				break
			end
		end
	end
end
newHitbox:Destroy()		

I should note that both snippets deal damage on a per hitbox per character per frame basis, and that both would need to be used and optimized for a connection to RunService most likely.

Quick plug:

12 Likes