Touched Event Problems

Hey guys I’m not really sure how to describe the problem, so I will try my best.

Basically I have some code which is supposed to continually damage the player as long as they are touching a part. This works perfectly, however I’ve run into an issue. Here is my code:

local RunService = game:GetService("RunService")

local killPart = script.Parent

local canDamage = true

killPart.Touched:Connect(function(hit)
	print("Kill part touched!")
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= killPart.Parent.Parent then
		canDamage = true
		RunService.Heartbeat:Connect(function(step)
			if canDamage then
				task.wait(step)
				hit.Parent:FindFirstChild("Humanoid"):TakeDamage(0.05)
			end
		end)
	end
end)

killPart.TouchEnded:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= killPart.Parent.Parent then
		canDamage = false
		task.wait(2)
	end
end)

Whenever the player moves or jumps out of the killPart, this makes the TouchedEnded event fire, however as soon as they are done moving back into the hitbox, or they come back down from jumping, the Touched event fires which causes way more damage to be done than I want. Here is a comparison I have:


The first print statement shows that the touched event was fired 10 times. This was when I wasn’t moving or jumping.

The second print statement shows the touched event ran 68 times in the same amount of time when I was jumping and moving around.

There is a huge difference in the amount of damage dealt, as I didn’t even get close to dying when I was at full health with no movement, compared to immediately dying when jumping around.

If you need more explanation, let me know. Thanks for helping!

The issue is creating Runservice Connections stacks, one connected it won’t be stopped unless you :Disconnect() or destroy the script.

Consequently, make sure only one connection is ran at a time

local RunService = game:GetService("RunService")

local killPart = script.Parent

local canDamage = true
local damageConnection
killPart.Touched:Connect(function(hit)
	print("Kill part touched!")
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= killPart.Parent.Parent then
		canDamage = true
		if not damageConnection then -- check if there is already a connection
			damageConnection = RunService.Heartbeat:Connect(function(step)
				if canDamage then
					task.wait(step)
					hit.Parent:FindFirstChild("Humanoid"):TakeDamage(0.05)
				end
			end)
		end
	end
end)

killPart.TouchEnded:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent ~= killPart.Parent.Parent then
		canDamage = false
		if damageConnection then --disconnect and remove connection
			damageConnection:Disconnect()
			damageConnection = nil
		end
		task.wait(2)
	end
end)
2 Likes

Works perfectly! Can’t believe this never crossed my mind! Thanks!