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.
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)
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)
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.