I'm creating a combat system, and so far what I have is a player presses q to play an animation, which in turn fires an event. The event is handled in a server script in ServerScriptService, and handles the hit detection and damaging (to prevent exploiters). However, the hit detection for it seems to be very buggy when I try to disconnect the function.
-- All variables are defined prior to this code
local Touched
Touched = part.Touched:Connect(function(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
local upperTorso = hit.Parent:FindFirstChild("UpperTorso")
if humanoid and not humanoid:IsDescendantOf(plr.Character) then
humanoid:TakeDamage(damage)
Touched:Disconnect() -- Disconnect the function once it's hit to prevent double hitting
end
end)
wait(.35) -- Wait for the animation to end, then disconnect it again (incase the character never hits anyone)
Touched:Disconnect()
The hit detection works fine without the second disconnect, except for if I press Q tons of times, it will then do tons of damage to whoever is hit next, whether or not the character is playing the animation.
Local Script
local UIS = game:GetService("UserInputService")
local player = game:GetService("Players").LocalPlayer
local character
local humanoid
local LeftPunchAnimation
local RightPunchAnimation
local PunchEvent = game:GetService("ReplicatedStorage").Events.Punch
local PowerAmount = script.Parent.SlideValue
player.CharacterAdded:Connect(function(c)
character = c
humanoid = c:WaitForChild("Humanoid")
LeftPunchAnimation = humanoid:LoadAnimation(script.LeftPunch)
RightPunchAnimation = humanoid:LoadAnimation(script.RightPunch)
end)
local punchDebounceTime = .45
local punchDefaultDamage = 5
local punchDB = false
local lastPunch = 0
UIS.InputBegan:Connect(function(input,gp)
if gp then return end
if input.KeyCode == Enum.KeyCode.Q and punchDB == false then
punchDB = true
if lastPunch == 0 then
lastPunch = 1
RightPunchAnimation:Play()
local connect
connect = RightPunchAnimation.KeyframeReached:Connect(function(name)
if name == "Action" then
PunchEvent:FireServer("Right",PowerAmount.Value)
connect:Disconnect()
end
end)
elseif lastPunch == 1 then
lastPunch = 0
LeftPunchAnimation:Play()
local connect
connect = LeftPunchAnimation.KeyframeReached:Connect(function(name)
if name == "Action" then
PunchEvent:FireServer("Left",PowerAmount.Value)
connect:Disconnect()
end
end)
end
wait(punchDebounceTime)
punchDB = false
end
end)
Any help appreciated!

13 comments
If you have any questions feel free to ask, i have yet to test this code myself but it should work fine.
Defining upperTorso was for a separate purpose, guess I forgot to completely remove it from the script. I know plenty about debounces, but am confused how I would incorporate that into this? If I fire the remoteevent multiple times, then multiple touched connections will be formed causing extra damage, and using the debounce will continue damaging even if the animation isn't playing.
Show me your local script
Edited it into the question
You need a seperate debounce for both KeyframeReached events.
I'll try to edit the script so gimme a minute
My issue isn't regarding time between punches, if that's what you mean when you say I need debounces for the both KeyframeReached events. I'm just having trouble with the touched part, as it hits sometimes, whereas it doesn't other times.
Alright i edited the script, see if it works now
Reason why you need a debounce for KeyframeReached is because when the keyframe has been reached, it will fire the RemoteEvent multiple times which is why you need the debounce.
Nope, works how I expected (still damages after animation has ended). https://gyazo.com/c7ac5a548744192e51ff0f5562428b93
It also never fired more than once, I disconnect the KeyframeReached event afterwards to prevent that.
Well normally i put the hit detection in the local script so i can check if the animation is playing before dealing damage, but you put the touched event in the server script so i'm not sure what can be done, sorry.
I put the hit detection in a server script so that exploiters can't fire the damage remote themselves and kill anyone even if they aren't being hit. Thanks for trying, though.