Combat system issue

I’ve got a local script, that plays all anims for the combat system, etc. and when a specific KeyFrame of an animation is reached, it fires an event to the Server to damage.

LocalScript
Tool.Equipped:Connect(function()
	local AttackAnim = possibleAttackAnimations[math.random(1, #possibleAttackAnimations)] -- this is the anim that is selected on tool equip
	Tool.Activated:Connect(function()
		AttackAnim = possibleAttackAnimations[math.random(1, #possibleAttackAnimations)] -- and this one selects after tool is activated

		toolActivatedValue.Value = true

		if debounce == false then
			if #playingAnimations == 0 then
				debounce = true
				AttackAnim:Play()
				AttackAnim:AdjustSpeed(1.4)
			end
		end

		AttackAnim.Stopped:Connect(function()
			debounce = false
		end)

		toolActivatedValue.Value = false
	end)
	
	local connection 
	connection = AttackAnim.KeyframeReached:Connect(function(keyframeName) -- but this here, it defines the animation that was defined when the tool equipped, and not when activated
		if keyframeName == "CanHit" then
			local part = CanDamage()

			if part then
				print(tostring(AttackAnim).." is attacking")
				DamageEvent:FireServer(part.Parent, Tool, AttackAnim.Name)
			end
		end
	end)
	
	Tool.Unequipped:Connect(function()
		connection:Disconnect()
	end)
end)

So my problem is, that this script just doesnt work. I have some ideas, why does it not work. I wanted to do it, so each time, when the player attacks, it chooses a new animation from possibleAnimations table. But, I don’t know how to implement it so it would detect the keyframe reached of a new animation, and not the old one. Any help is appreciated!

EDIT: I’ve managed to fix the script, and I updated it, but the problem is, that the KeyFrameReached event is defining the old animation, and not the new one.

put local connection at the top of the Equiped function. In the activated event, disconnect the connection and replace it with the new one.

But my question is that why are you connecting functions inside the equipped event? This would just keep on adding new events every time the item is equipped and cause a memory leak. Have the connection, and attackAnim outside and define the other events outside of the equipped event. Then, the activated event will disconnect the previous connection and define the newest animation

This way, we would only need two connections (have not tested this code):

local AttackAnim, connection;

Tool.Activated:Connect(function()
	AttackAnim = possibleAttackAnimations[math.random(1, #possibleAttackAnimations)]
	
	-- Disconnect the previous connection and define a new one.
	if connection then connection:Disconnect() end
	connection = AttackAnim.KeyframeReached:Connect(function(keyframeName)
		if keyframeName == "CanHit" then
			local part = CanDamage()

			if part then
				print(tostring(AttackAnim).." is attacking")
				DamageEvent:FireServer(part.Parent, Tool, AttackAnim.Name)
			end
		end
	end)

	toolActivatedValue.Value = true

	if debounce == false then
		if #playingAnimations == 0 then
			debounce = true
			AttackAnim:Play()
			AttackAnim:AdjustSpeed(1.4)
		end
	end

	AttackAnim.Stopped:Connect(function()
		debounce = false
	end)

	toolActivatedValue.Value = false
end)

Tool.Unequipped:Connect(function()
	connection:Disconnect()
end)
1 Like