How to add reliable cooldown?

When making my heavy attack, everything Is perfect. The damage and stun and all that. But for some reason, if you spam it, it summons 3 hitboxes. Here’s the script (scroll to the bottom for some reason it won’t let me collapse the punch function)

local CAS = game:GetService("ContextActionService")

local Combat_Event = game.ReplicatedStorage.Combat_Event

local player = game.Players.LocalPlayer
local Character = player.Character
local humanoid = Character:WaitForChild("Humanoid")

local Heavy_Event = game.ReplicatedStorage.Heavy_Event

local can_heavy = true

local combo = 1
local last_hit = 0

local can_hit = true

local lastM1 = os.clock()

if humanoid:GetAttribute("Blocking", true) == true or humanoid:GetAttribute("IFrames", true) == true or humanoid:GetAttribute("Stunned", true) == true then
	can_hit = false
	can_heavy = false
end

if humanoid:GetAttribute("Attacking", true)  == true then
	can_heavy = false
end

local animations = {
	'rbxassetid://16054362647', 
	'rbxassetid://16054511462',
	'rbxassetid://16054664934',
}
print(#animations)
local function punch(action_name, input_state, input_type)
	if input_state == Enum.UserInputState.Begin and can_hit then
		local currentTime = os.clock()
		lastM1 = currentTime
		task.delay(1,function()
			if lastM1 == currentTime then
				combo = 1	
			end
		end)
		Combat_Event:FireServer()
		can_hit = false

		local animation = Instance.new("Animation", Character)
		animation.AnimationId = animations[combo]
		animation:Destroy()

		local hit_track = humanoid:WaitForChild("Animator"):LoadAnimation(animation)
		hit_track:Play()


		if combo == #animations then
			combo = 1
			wait(1)
			can_hit = true
		else
			combo += 1 
			humanoid:SetAttribute("Attacking", true)
			wait(0.5)
			humanoid:SetAttribute("Attacking", false)
			can_hit = true
		end
	end
end

local function heavypunch(action_name, input_state, input_type)
	if input_state == Enum.UserInputState.Begin and can_heavy then
		wait(0.30)
		can_heavy = false
		Heavy_Event:FireServer()
		wait(4)
		can_heavy = true
	end
end

CAS:BindAction('Punch', punch, false, Enum.UserInputType.MouseButton1)
CAS:BindAction('HeavyPunch', heavypunch, false, Enum.KeyCode.R)

As you can see, I’ve made multiple measures to make sure they cannot press the button while doing another task, (which makes “can_heavy” = false). But for some odd reason when everything else checks, out they are able to spam it. I even put the can heavy before the actual event fire to make sure that the event wasn’t making the code wait. But it’s still odd? It may be just a simple piece of code I’m missing i have no idea lol.

1 Like

If you have a cooldown, place the hitbox creation behind it.

The hitbox creation is managed in a server script.

well I guess thats your problem. You should be only detecting clicks in a localscript soley, not performing cooldowns and other things on top of it. All functionality should be in a server script in ssservice

how would I go about doing that? Do you need the server script? (I’m very new to scripting so if the stupidity gets repetitive I apologize lol.

The function is waiting 0.30 seconds before setting the can_heavy variable to false, which means that there’s a small window of time where the function can be activated several times and for the variable to still be equal to true before it’s updated by the function.

Consider setting the variable to false before the wait, in addition to making sure that there is an equivalent *debounce / cooldown implemented on the server-side to make it less likely for exploiters to be able to get around the cooldown by repeatedly firing the RemoteEvent quicker than intended.


(And as a side note, it’s recommended to use task.wait(), instead, as the original wait() has been deprecated).

1 Like

So somehow I managed to miss the simplest thing ever. Also thanks for the task.wait tip.

2 Likes

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