Hitbox only detects hits randomly

I have a script where a hitbox will spawn in front of the player and detect any humanoid inside, after which they will take damage. However, for some reason it only detects the player sometimes/randomly. I’ve put a print script at each spot in the detection line and it always comes out as random.

Video:


(sorry for low quality, the file was too big)

Here’s the punch script:

local chr = script.Parent.Parent.Parent.Parent.Parent
local hum = chr:WaitForChild("Humanoid")
local hroot = chr:WaitForChild("HumanoidRootPart")

local Holding = script.Parent.Parent.Holding
local Cooldown = script.Cooldown
local CD = .2
local db = false
local hdb = false
local TTA = 1
local DMG = 2

local Punch1 = hum:LoadAnimation(script.Punch1)
local Punch2 = hum:LoadAnimation(script.Punch2)
local Punch3 = hum:LoadAnimation(script.Punch3)
local Punch4 = hum:LoadAnimation(script.Punch4)

local Swing1 = script.Swing1
local Swing2 = script.Swing2
local Swing3 = script.Swing3
local Swing4 = script.Swing4

Swing1.Parent = chr:WaitForChild("Right Arm")
Swing2.Parent = chr:WaitForChild("Left Arm")
Swing3.Parent = chr:WaitForChild("Right Arm")
Swing4.Parent = chr:WaitForChild("Left Arm")

local S1 = chr:WaitForChild("Right Arm"):WaitForChild("Swing1")
local S2 = chr:WaitForChild("Left Arm"):WaitForChild("Swing2")
local S3 = chr:WaitForChild("Right Arm"):WaitForChild("Swing3")
local S4 = chr:WaitForChild("Left Arm"):WaitForChild("Swing4")

local M1 = 0

while wait() do
	if Holding.Value == true and db == false then
		db = true
		Cooldown.Value = true
		
		if M1 < 4 then
			M1 += 1
		else
			M1 = 1
		end
		
		--Punching
		
		if M1 == 1 then
			Punch1:Play()
			S1:Play()
			wait(.075)
			
			local HitBox = game.ReplicatedStorage.HitBoxes.Punches.BasicPunch:Clone()
			local Weld = Instance.new("Weld", hroot)
			HitBox.Parent = hroot
			Weld.Part0 = HitBox
			Weld.Part1 = hroot
			
			Weld.C0 = HitBox.CFrame:ToObjectSpace(HitBox.CFrame * CFrame.new(0,0,2.5))
			
			HitBox.Touched:Connect(function(hit)
				if not hit:IsDescendantOf(chr) and hit and hit.Parent then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						if hdb == false then
							hdb = true
							print("Damaged")
							Humanoid:TakeDamage(DMG)
						end
					end
				end

			end)
			
			wait(.075)
			
			HitBox:Destroy()
			
		elseif M1 == 2 then
			Punch2:Play()
			S2:Play()
			wait(.075)

			local HitBox = game.ReplicatedStorage.HitBoxes.Punches.BasicPunch:Clone()
			local Weld = Instance.new("Weld", hroot)
			HitBox.Parent = hroot
			Weld.Part0 = HitBox
			Weld.Part1 = hroot

			Weld.C0 = HitBox.CFrame:ToObjectSpace(HitBox.CFrame * CFrame.new(0,0,2.5))

			HitBox.Touched:Connect(function(hit)
				if not hit:IsDescendantOf(chr) and hit and hit.Parent then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						if hdb == false then
							hdb = true
							print("Damaged")
							Humanoid:TakeDamage(DMG)
						end
					end
				end

			end)

			wait(.075)

			HitBox:Destroy()
			
		elseif M1 == 3 then
			Punch3:Play()
			S3:Play()
			wait(.075)

			local HitBox = game.ReplicatedStorage.HitBoxes.Punches.BasicPunch:Clone()
			local Weld = Instance.new("Weld", hroot)
			HitBox.Parent = hroot
			Weld.Part0 = HitBox
			Weld.Part1 = hroot

			Weld.C0 = HitBox.CFrame:ToObjectSpace(HitBox.CFrame * CFrame.new(0,0,2.5))

			HitBox.Touched:Connect(function(hit)
				if not hit:IsDescendantOf(chr) and hit and hit.Parent then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						if hdb == false then
							hdb = true
							print("Damaged")
							Humanoid:TakeDamage(DMG)
						end
					end
				end

			end)

			wait(.075)

			HitBox:Destroy()
			
		elseif M1 == 4 then
			Punch4:Play()
			S4:Play()
			wait(.075)

			local HitBox = game.ReplicatedStorage.HitBoxes.Punches.BasicPunch:Clone()
			local Weld = Instance.new("Weld", hroot)
			HitBox.Parent = hroot
			Weld.Part0 = HitBox
			Weld.Part1 = hroot

			Weld.C0 = HitBox.CFrame:ToObjectSpace(HitBox.CFrame * CFrame.new(0,0,2.5))

			HitBox.Touched:Connect(function(hit)
				if not hit:IsDescendantOf(chr) and hit and hit.Parent then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						if hdb == false then
							hdb = true
							print("Damaged")
							Humanoid:TakeDamage(DMG)
						end
					end
				end

			end)

			wait(.075)

			HitBox:Destroy()
			
			wait(.8)
		end
		
		wait(CD)
		Cooldown.Value = false
		hdb = false
		db = false
		
		--Time To Attack
		
		if M1 == 1 then
			spawn(function()
				
				wait(TTA)
				if M1 == 1 then
					M1 = 0
				end
			end)
			
		elseif M1 == 2 then
			spawn(function()

				wait(TTA)
				if M1 == 2 then
				M1 = 0
				end
			end)
			
		elseif M1 == 3 then
			spawn(function()
	
				wait(TTA)
				if M1 == 3 then
				M1 = 0
				end
			end)
			
		elseif M1 == 4 then
			spawn(function()

				wait(TTA)
				if M1 == 4 then
					M1 = 0
				end
			end)
		
		end
	end
end

Try this instead of HitBox.Touched

like touched is kinda bad for combat system tho

1 Like

how would i connect :GetPartsInPart() to my hitbox, since my hitbox is a clone of a part in replicated storage

As @Heiguy23 mentioned, using .Touched / :GetPartsInPart() generally isn’t suitable for fast combat systems. Sometimes hits won’t register simply due to latency.

Instead you should utilize something like Raycast Hitbox 4.01: For all your melee needs! which allows for accurate triggering (there’s a lot of games that utilize this, would highly recommend)

try using OverlapParams instead of touched there is a trick to using gettouchingparts but OverlapParams is the new system

this might be a little too advanced for the type of game im making + my scripting knowledge

well like im using a module that is made by sushimaster and its really good for my combat system