Punches hitting twice sometimes

Whenever I punch a dummy, sometimes it connects twice. It happens very rarely so its hard to tell how its happening, but it seems like it only does it once per dummy and never again, but again I can’t confirm this since it happens so rarely it’s hard to tell.

The script works by detecting whether the value = true, and then executing the script punch. It works this way so that you can hold down the click button to punch. Idk if this has anything to do with the issue, I just thought I should mention it.

Video:

local chr = script.Parent.Parent.Parent.Parent.Parent
local plr = game.Players:GetPlayerFromCharacter(chr)
local hum = chr:WaitForChild("Humanoid")
local hroot = chr:WaitForChild("HumanoidRootPart")

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

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
		
		if M1 < 4 then
			M1 += 1
		else
			M1 = 1
		end
		
		--Punching
		
		if M1 == 1 and Punching == false then
			Punching = true
			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(plr.Character) and hit and hit.Parent and hit.Name == "HumanoidHitBox" and not hit.Parent:FindFirstChildOfClass("ForceField") then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						print("Hit")
						Humanoid:TakeDamage(10)
						hit.Sounds.Impact.Punch1:Play()
					end
				end
			end)
			
			wait(.2)
			
			HitBox:Destroy()
			Punching = false
			
		elseif M1 == 2 and Punching == false then
			Punching = true
			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(plr.Character) and hit and hit.Parent and hit.Name == "HumanoidHitBox" and not hit.Parent:FindFirstChildOfClass("ForceField") then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						print("Hit")
						Humanoid:TakeDamage(10)
						hit.Sounds.Impact.Punch2:Play()
					end
				end
			end)
			
			wait(.2)

			HitBox:Destroy()
			Punching = false
			
		elseif M1 == 3 and Punching == false then
			Punching = true
			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(plr.Character) and hit and hit.Parent and hit.Name == "HumanoidHitBox" and not hit.Parent:FindFirstChildOfClass("ForceField") then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						print("Hit")
						Humanoid:TakeDamage(10)
						hit.Sounds.Impact.Punch3:Play()
					end
				end
			end)

			wait(.2)

			HitBox:Destroy()
			Punching = false
			
		elseif M1 == 4 and Punching == false then
			Punching = true
			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(plr.Character) and hit and hit.Parent and hit.Name == "HumanoidHitBox" and not hit.Parent:FindFirstChildOfClass("ForceField") then
					local Humanoid = hit.Parent:FindFirstChild("Humanoid")
					if Humanoid then
						print("Hit")
						Humanoid:TakeDamage(10)
						hit.Sounds.Impact.Punch4:Play()
					end
				end
			end)

			wait(.2)

			HitBox:Destroy()
			Punching = false
			
			wait(.75)
		end
		
		wait(CD)
		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
2 Likes

it can hit twice because you never store the humanoids you already hit

whenever you damage a humanoid, store it into a list so it never damages it again until the next time it punches

make sure to check if the humanoid you are about to damage is in that list before damaging it

1 Like
local MyPart = workspace.Part

local Hitlist = {}

Hitbox.Touched:Connect(function(hit)
       if table.find(Hitlist, hit.Parent) then return end
             table.insert(Hitlist, hit.Parent)

-- Rest of The Code.
       end
end)
1 Like

Try using a db2 after each “if Humanoid then” hit then resetting db2 all the way at the end.
Or just use db for that and not on top …

1 Like

if this was me making this just to make sure it doesnt hit again i would fireclient(person that got hit)

Client:
onclientevent:Connect(function()
HitBox.CanTouch = false

but if u want the hitbox to only focus 1 person and the hitbox cant hit more than 2 people
i would just
local done = false

hitbox.touched:connect(function()
if done == true then return
done = true

This is like saying while heartbeat and is magnitudes faster than an alternatives.
Also may want to switch to task.wait(). in front of all your wait commands. wait() isn’t always perfect task.wait() is.

Considering you’re working with very fast inputs you may even want to focus in more in places with:
local rs= game:GetService(“RunService”)
rs.Stepped:Wait() ← each frame in sync
rs.Heartbeat:Wait() ← as fast as possible

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.