Trying to add a cooldown to this script

So I’m working on this script where if you touch a part it accesses your character and leaderstats and sets your score + 1

This is the code:

local char

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:IsA("Model") and hit.Parent:FindFirstChild("Humanoid") then
		char = hit.Parent 
	end
	local player = game.Players:GetPlayerFromCharacter(char)
	player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
	wait(5)
end)

I’m sure this is just some beginner mistake, but I spent quite some time trying to figure this out, roaming the developer forum and the internet yet failed to find a clear solution to this problem.

Thanks for anyone helping in advance!

If you want to add a proper cooldown, all you have to do is create a debounce (a true/false variable) above the touched event, and set it to true when touch is in effect, and set it to false 5 seconds later to run the code again.

Here is an example:

local char
local debounce = false -- we will consider 'false' to mean that the code is ready to be executed again

script.Parent.Touched:Connect(function(hit)
	if hit.Parent:IsA("Model") and hit.Parent:FindFirstChild("Humanoid") and not debounce then -- if debounce is 'false'
		debounce = true -- sets debounce to 'true' (the rest of the code will only run once untill the cooldown is over
		char = hit.Parent 
		local player = game.Players:GetPlayerFromCharacter(char)

		if player then -- this is to avoid possible errors while obtaining the player
			player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
		end
		task.wait(5) -- 5 second cooldown
		debounce = false -- set debounce to 'false'
	end
end)
2 Likes

try

local char
local debounces={}
script.Parent.Touched:Connect(function(hit)
	if hit.Parent:IsA("Model") and hit.Parent:FindFirstChild("Humanoid") then
		char = hit.Parent 
	end
	local player = game.Players:GetPlayerFromCharacter(char)
	if not player then return end
	if not debounces[player.Name] then 
		debounces[player.Name]=true
	else
		if debounces[player.Name]==true then return end
		debounces[player.Name]=true
	end
	player.leaderstats.Stage.Value = player.leaderstats.Stage.Value + 1
	wait(5)
	debounces[player.Name]=false
end)
1 Like

When you connect a callback function to an event, that function is spawned in its own separate thread, so yielding in it would do nothing for the next time the event fires.

You would want to set up a variable that tracks when your event is in a debounced state, and then set it up so it resets after an amount of time.

local Debounce = false

local function Reset()
	Debounce = false
end

Event:Connect(function()
	if not Debounce then
		Debounce = true
		task.delay(3, Reset)
		
		print("fired")
	end
end)

This, however, would add a cooldown for every time something touched the part. I believe in your case you want to add a cooldown for a per player basis. You could achieve this through adding a hashmap for each player.

local DebounceList = {}

local function Reset(Player)
	DebounceList[Player] = nil
end

Part.Touched:Connect(function(OtherPart)
	local Player = ...
	
	if not DebounceList[Player] then
		DebounceList[Player] = true
		task.delay(3, Reset, Player)
		
		print("fired")
	end
end)

My implementation may be confusing, so feel free to ask any questions about what I did.

2 Likes

Thank you so much for replying! Your solution is very clear to me and I will certainly try it out, thanks!

1 Like

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