Hitbox hitting multiple times

I’ve made code which hits the player(Clientsided), tends to go well except for one little issue.

It hits the player multiple times.

I’ve tried changing the already hit detection, and I’ve tried changing the actual damage function.
Ignore the parry system, unless its affecting the hit detection.

The hitbox itself:

local hit = false
game["Run Service"].Heartbeat:Connect(function()
	local chars = game.Workspace:GetPartsInPart(script.Parent)
	for i, h in pairs(chars) do
		if h.Parent == game.Players.LocalPlayer.Character and hit == false then
			if h.Parent:FindFirstChild("Parry") == nil then
			game.ReplicatedStorage.DmgPlr:FireServer(15)
			script.Parent.Color = Color3.new(0,1,0)
			else
				game.ReplicatedStorage.DmgPlr:FireServer(-15)
				script.Parent.Parry:FireServer()
			end
		hit = true
		end
	end
end)

The damage function:

game.ReplicatedStorage.DmgPlr.OnServerEvent:Connect(function(plr,dmg)
	plr.Character.Humanoid:TakeDamage(dmg)
end)
1 Like

i need more info,use this code instead and then tell me what the console shows:

local hit = false
game["Run Service"].Heartbeat:Connect(function()
	local chars = game.Workspace:GetPartsInPart(script.Parent)
	for i, h in pairs(chars) do
		if h.Parent == game.Players.LocalPlayer.Character and hit == false then
			if h.Parent:FindFirstChild("Parry") == nil then
  
			game.ReplicatedStorage.DmgPlr:FireServer(15)
			script.Parent.Color = Color3.new(0,1,0)
			else
				game.ReplicatedStorage.DmgPlr:FireServer(-15)
				script.Parent.Parry:FireServer()
			end
        print(h.Name)
         print(hit)
		hit = true
		end
	end
end)

That way we can know exactly what the problem could be.

store the hit flag per character rather than adding a global flag. if that’s not the problem then it may be your if h.Parent == game.Players.LocalPlayer.Character check.

For starters you probably shouldn’t be partcasting every single heartbeat, that’s gonna cause immense lag.

Secondly, it looks like it’s hitting multiple times because you’re running the code multiple times. Every heartbeat, to be exact.

local hit = false
local chars = game.Workspace:GetPartsInPart(script.Parent) -- this value dosn't change locally
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()

local function onBeat()
	for i, h in pairs(chars)
		if h.Parent == character and not hit then
			hit = true
			if h.Parent:FindFirstChild("Parry") then
				game.ReplicatedStorage.DmgPlr:FireServer(-15)
				script.Parent.Parry:FireServer()
			else
				game.ReplicatedStorage.DmgPlr:FireServer(15)
				script.Parent.Color = Color3.new(0,1,0)
			end
		end
		print(h.Name)
		print(hit)
	end
end
game:GetService("Run Service").Heartbeat:Connect(onBeat)

Just as @AntoniV_17 requested, run this code and let us know what the output console returns.

I have a feeling it was detecting multiple hits because the hit = true debounce was set at the end of the if h.Parent statement rather than at the beginning. My theory is the next Heartbeat fires before the hit debounce can be set to true.

And I agree with @CraX_573 , this should be tied to Instance.Touched rather than on every heartbeat.

1 Like

I agree with that,i was thinking exactly that,it could be the debounce


Sorry about the eyeburn of light mode, but the issue seems to be that it does detect the hit twice. It’s likely the heartbeat loop, so a better solution that i can think of is likely to use the current damage detection once upon creation, and then use instance.touched to detect if the hitbox collides after creation.

This is the new code

script.Parent.Touched:Connect(function(h)
	if h.Parent == game.Players.LocalPlayer.Character and hit == false then
		hit = true
		if h.Parent:FindFirstChild("Parry") == nil then
			game.ReplicatedStorage.DmgPlr:FireServer(15)
			script.Parent.Color = Color3.new(0,1,0)
		else
			game.ReplicatedStorage.DmgPlr:FireServer(-15)
			script.Parent.Parry:FireServer()
		end
		print(h)
		print(hit)
	end
end)

However the issue still prevails. The console still shows the duplication.

A .Touched setup with a debounce would only run once as intended unless your script is running twice, or the debounce variable is being set elsewhere. We’ll need more context

this is the ENTIRE script, maybe there’s an issue here?

local hit = false
game["Run Service"].Heartbeat:Connect(function()
	script.Parent.CFrame = script.Parent.attachment.Value.CFrame * script.Parent.Offset.Value
end)

script.Parent.Touched:Connect(function(h)
	if hit == true then
		return
	end
	if h.Parent == game.Players.LocalPlayer.Character then
		hit = true
		if h.Parent:FindFirstChild("Parry") == nil then
			game.ReplicatedStorage.DmgPlr:FireServer(15)
			script.Parent.Color = Color3.new(0,1,0)
		else
			game.ReplicatedStorage.DmgPlr:FireServer(-15)
			script.Parent.Parry:FireServer()
		end
		print(h)
		print(hit)
	end
end)

Otherwise, there is an enemy ai which clones the hitbox from serverstorage and sets up the size and that.

I pasted your script into a part in an empty place file and it runs properly. The script that creates the hitbox must be creating two of them, what does that script look like?

local anim = script.Parent.Humanoid:LoadAnimation(script.DoubleSlash)
					anim:Play(0.05)
					task.wait(0.05)
					script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
					task.wait(0.07)
					local velocity = Instance.new("BodyVelocity",script.Parent.HumanoidRootPart)
					velocity.MaxForce = Vector3.new(math.huge,0,math.huge)
					velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
					local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
					hitbox.attachment.Value = script.Parent.HumanoidRootPart
					hitbox.Offset.Value = CFrame.new(0,0,-3)
					hitbox.Size = Vector3.new(4,5,6)
					hitbox.Parent = game.Workspace.Attacks
					task.wait(0.2)
					hitbox:Destroy()
					velocity.Velocity = Vector3.new(0,0,0)
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
					task.wait(0.14)
					script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
					task.wait(0.2)
					velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
					local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
					hitbox.attachment.Value = script.Parent.HumanoidRootPart
					hitbox.Offset.Value = CFrame.new(0,0,-3)
					hitbox.Size = Vector3.new(4,5,6)
					hitbox.Parent = game.Workspace.Attacks
					task.wait(0.2)
					hitbox:Destroy()
					velocity.Velocity = Vector3.new(0,0,0)
					task.wait(0.1)
					velocity:Destroy()
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false

a video with the double hit in action:

If that’s the entire script I’d need the place file to determine what could be causing the issue

The place file.
hitbox.rbxl (167.5 KB)

1 Like

i’ve looked at the attacks folder and he just seems to summon 2 hitboxes at the same time for unknown reason

Ok so i pinpointed the WRONG issue, it was just that the enemy was attacking TWICE at the same time due to my spaghetti code

if you’re curious, the full attack code pre-change:

spawn(function()
	task.wait(1)
	while  task.wait() do
			local target = SwingAttempt(script.Parent.HumanoidRootPart.Position)
			if target ~= nil and db == false then
				----print(script.Parent.Humanoid.WalkSpeed)
				local attack = math.random(1,1) 
				spawn(function()
					if attack == 1 then
					db = true
					print("attack")
					local anim = script.Parent.Humanoid:LoadAnimation(script.DoubleSlash)
					anim:Play(0.05)
					task.wait(0.05)
					script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
					task.wait(0.07)
					local velocity = Instance.new("BodyVelocity",script.Parent.HumanoidRootPart)
					velocity.MaxForce = Vector3.new(math.huge,0,math.huge)
					velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
					local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
					hitbox.attachment.Value = script.Parent.HumanoidRootPart
					hitbox.Offset.Value = CFrame.new(0,0,-3)
					hitbox.Size = Vector3.new(4,5,6)
					hitbox.Parent = game.Workspace.Attacks
					task.wait(0.2)
					hitbox:Destroy()
					velocity.Velocity = Vector3.new(0,0,0)
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
					task.wait(0.14)
					script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
					task.wait(0.2)
					velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
					local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
					hitbox.attachment.Value = script.Parent.HumanoidRootPart
					hitbox.Offset.Value = CFrame.new(0,0,-3)
					hitbox.Size = Vector3.new(4,5,6)
					hitbox.Parent = game.Workspace.Attacks
					task.wait(0.2)
					hitbox:Destroy()
					velocity.Velocity = Vector3.new(0,0,0)
					task.wait(0.1)
					velocity:Destroy()
					script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
					task.wait(0.5)
					db = false
					end
				end)
			end
			end
end)

After some testing, taking the function out of the spawn() call fixed the double hitbox issue

spawn(function()
	task.wait(1)
	while  task.wait() do
		local target = SwingAttempt(script.Parent.HumanoidRootPart.Position)
		if target ~= nil and db == false then
			----print(script.Parent.Humanoid.WalkSpeed)
			local attack = math.random(1,1) 
			if attack == 1 then
				db = true
				print("attack")
				local anim = script.Parent.Humanoid:LoadAnimation(script.DoubleSlash)
				anim:Play(0.05)
				task.wait(0.05)
				script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
				script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
				task.wait(0.07)
				local velocity = Instance.new("BodyVelocity",script.Parent.HumanoidRootPart)
				velocity.MaxForce = Vector3.new(math.huge,0,math.huge)
				velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
				local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
				hitbox.attachment.Value = script.Parent.HumanoidRootPart
				hitbox.Offset.Value = CFrame.new(0,0,-3)
				hitbox.Size = Vector3.new(4,5,6)
				hitbox.Parent = game.Workspace.Attacks
				task.wait(0.2)
				hitbox:Destroy()
				velocity.Velocity = Vector3.new(0,0,0)
				script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
				task.wait(0.14)
				script.Parent.HumanoidRootPart.AlignOrientation.CFrame = script.Parent.HumanoidRootPart.CFrame
				script.Parent.HumanoidRootPart.AlignOrientation.Enabled = true
				task.wait(0.2)
				velocity.Velocity = script.Parent.HumanoidRootPart.CFrame.LookVector*125
				local hitbox = game.ServerStorage.attacks.juggernaut.hitbox:Clone()
				hitbox.attachment.Value = script.Parent.HumanoidRootPart
				hitbox.Offset.Value = CFrame.new(0,0,-3)
				hitbox.Size = Vector3.new(4,5,6)
				hitbox.Parent = game.Workspace.Attacks
				task.wait(0.2)
				hitbox:Destroy()
				velocity.Velocity = Vector3.new(0,0,0)
				task.wait(0.1)
				velocity:Destroy()
				script.Parent.HumanoidRootPart.AlignOrientation.Enabled = false
				task.wait(0.5)
				db = false
			end
		end
	end
end)

For what it’s worth, using spawn() isn’t necessary here, and your SwingAttempt() function can be potentially very laggy with higher instance counts in the workspace

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