How can I introduce a debounce mechanism in this script?

Hi, I am trying to make an obby for my game.

WinPart.Touched:Connect(function(Toucher)
	if game.Players:GetPlayerFromCharacter(Toucher.Parent) then
		Toucher.Parent.HumanoidRootPart.Position = script.Parent.ObbyStart.Position
	
		local Plr = game.Players:GetPlayerFromCharacter(Toucher.Parent)
		script.AddCoins:Fire(Plr, Prize)
	end
end)

This is currently the script for the obby. It is a script located inside workspace, with the BindableEvent “AddCoins” parented to it.

What I’m asking is, is there a way to implement a debounce mechanism in this script?

The obvious issue is that when the player touches the part, the .Touched event will be fired 2 or 3 times before the player is teleported to the beginning of the obby, thus causing the AddCoins event to also fire multiple times.

Any help would be appreciated, thanks! :smiley:

db = false

WinPart.Touched:Connect(function(Toucher)
if db == false then
	if game.Players:GetPlayerFromCharacter(Toucher.Parent) then
        db = true
		Toucher.Parent.HumanoidRootPart.Position = script.Parent.ObbyStart.Position
	
		local Plr = game.Players:GetPlayerFromCharacter(Toucher.Parent)
		script.AddCoins:Fire(Plr, Prize)
         wait(1)
        db = false
        end
	end
end)

Try something like that.

2 Likes

I did, but the problem is that it is a server-sided script, meaning that if a player touches the part, another player that comes will have to wait the 1 second before getting his prize.

Try lower numbers like 0.3 or 0.2, and see if that fixes it.

Just make it a local script and make it so that the “AddCoins” Event is a function in a module script
Assuming you’re using the event to send a signal from a server-side script to a local script

You can add the player’s name into a table once the player touches it and if their name is already in the table it won’t run. Or just use a local script

3 Likes

A table of all those who’ve touched this part and when should help.
Like:

local tab = {}
part.Touched:Connect(function(hit)
   if hit.Parent:FindFirstChild("Humanoid") then --detect player
      tab[#tab+1] = {hit.Parent, tick()} --inserts the player and the time at which it touched
   end
end)

Then simply have a loop that goes through the table every second to remove players who the time limit no longer needs to be inplace (comparing the tick() part of the table) and it should be good for adding a person specific debounce. You would just need to check if the player that hits the item isn’t in the table or that the time since last touched is longer than a second.

Note: Don’t forget to make a check in the function I provided you so you don’t add the same person twice.

local debounce = false

WinPart.Touched:Connect(function(Toucher)
if game.Players:GetPlayerFromCharacter(Toucher.Parent) and not debounce then
	debounce = true
    Toucher.Parent.HumanoidRootPart.Position = script.Parent.ObbyStart.Position

    	local Plr = game.Players:GetPlayerFromCharacter(Toucher.Parent)
	    script.AddCoins:Fire(Plr, Prize)
        wait(1) --Change the number to your liking.
        debounce = false
	end
end)

In order to only have the debounce apply only to the player, you’d need to put this in a LocalScript in StarterPlayerScripts.

Edit: There actually has to be some changes to the script if it’s going to be a LocalScript.

local debounce = false
local players = game:GetService("Players")
local localPlayer = players.LocalPlayer

WinPart.Touched:Connect(function(Toucher)
local player = players:GetPlayerFromCharacter(Toucher.Parent)
if (player and player == localPlayer) and not debounce then
    debounce = true
    Toucher.Parent.HumanoidRootPart.Position = script.Parent.ObbyStart.Position

	    local Plr = game.Players:GetPlayerFromCharacter(Toucher.Parent)
        script.AddCoins:Fire(Plr, Prize)
        wait(1) --Change the number to your liking.
        debounce = false
	end
end)