Animation keyframe fires multiple time, increasing with every function call

I am making a simple NPC that attacks the player in close range. The NPC damages if the player is within a certain range around it, which is triggered by a KeyframeReached event.

For some reason, the KeyframeReached event fires multiple times, even though I have only one unique keyframe that fires the event. In addition, the event fires in increasingly consecutive amounts, so it first fires only once, then twice, 3 times, 4 times, etc. However, the function itself only activates once when called.

Below is my code:

local Debounce = false

local function Swing()
	local SwingTrack = SwingA -- this is the animation i am using
	task.wait(0.25)
	SwingTrack:Play()
	SwingTrack.KeyframeReached:Connect(function(KeyframeName)
		if KeyframeName == "AttackFrame" then -- this is supposed to only fire once
			SwingTrack:AdjustSpeed(0.0)
			task.wait(0.25)
			SwingTrack:AdjustSpeed(1.0)
			script.Swing:Play() -- sound effect
			Debounce = false
			if (RootPart.Position - script.Parent.Parent.HumanoidRootPart.Position).Magnitude <= WeaponRange and Debounce == false then -- WeaponRange is the maximum distance the player can be from the NPC so to get damaged
				Debounce = true
				script.Hit:Play()
				RootPart.Parent.Humanoid:TakeDamage(15)
			end
			script.Swing.Ended:Connect(function()
				Debounce = true
			end)
		end
	end)
end

-- calling the function
while task.wait(1.75) do
	task.spawn(Swing)
end
4 Likes

Assuming the function Swing gets called multiple times, It also connects to the event multiple times when only once is necessary. You could move that portion outside of the function or add a variable name which you can check for:

local Connection -- Put this somewhere at the first lines of your script
if not Connection then -- Check if connection already exists
	Connection = SwingTrack.KeyframeReached:Connect(function(KeyframeName) -- If it doesn't exist, create it once by setting the variable.
		...
end

This will also allow you to disconnect the event in case you don’t need it anymore. Please note that this requires the RootPart variable to be global but I assume it already is.

4 Likes

I wouldn’t have thought of this if not for you, it works like a charm now! Thank you so much!

1 Like

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