Hi, a coding noob here! I am trying to make a part which gives the player a Tool whenever the player touches the part. However, I am experiencing a struggle where the part gives the player infinite amount of tools whenever they touch the part, and I don’t want that!
What I want is to make a debounce so that the part gives a tool to the player one at a time. (e.g 1 tool per second) but I have no idea how to make this debounce. Can somebody give me some advice on what to add on my script? Thank you!!
local getTool = script.Parent
local replicatedStorage = game:GetService("ReplicatedStorage")
local debounce = false
getTool.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player and not debounce then
debounce = true
local tool = replicatedStorage:FindFirstChild("Tool")
local character = Player.Character
tool.Clone().Parent = player.BackPack
task.wait(1)
debounce = false
end
end)
The typical way to do debounce is the way I have shown above.
Your method doesn’t work since every time an event is run, it creates its own thread to run on.
Imagine your right leg touched the part, it would create a new “script” and it will create the tool and parent it to the player’s backpack and then it will wait 5 seconds on that “script” and that’s it. During this time, it can create new “scripts”, so for every time, that you touch a part with another limb, it creates another “script” which continuously create tools.
Try the below instead, my previous code had a few spelling errors.
local getTool = script.Parent
local replicatedStorage = game:GetService("ReplicatedStorage")
local debounce = false
getTool.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player and not debounce then
debounce = true
local tool = replicatedStorage:FindFirstChild("Tool")
local character = player.Character
tool:Clone().Parent = player.Backpack
task.wait(1)
debounce = false
end
end)
Debounce is what controls the cooldown so you don’t get hundreds of tools really fast.
In the, if statement, it checks if there’s a player and turns debounce to true since the not keyword inverses the boolean so it gives the player a tool.
We set debounce to true to stop it from constantly giving more tools as the inverse of debounce will be false and therefore, the if statement will not run, when another limb touches it in another “script”. FYI, the variable debounce is shared between the “scripts.”
We set debounce back to false after a second so we can give another tool to the player.
Keep in mind that the current solution will not allow other players to receive the tool while the one second duration is in effect. To clarify: once a player receives the tool, no other player can receive the tool during the one second duration.
Is this the behavior you are going for? If you want the one second duration to apply on a per-player basis then the code will be slightly more complicated since it needs to keep track of individual players.
Does “not debounce” mean debounce == true? In that case, wouldn’t the if-statement not run? since debounce = false initially, though it does run and idk why
The not keyword just inverses the boolean. The if statement uses the and keyword there, therefore, both expressions need to evaluate to true for the it to run.
The first expression ,player, runs perfectly and evaluates to true.
The second expression, not debounce, means to inverse the boolean and see if that is true. So, since, debounce is false, it inverses it to be true and now evaluates it with this new value instead. This however does not change the value of debounce itself.
Wait, now im confused.. I remember that LUA reads from up to down. Since debounce IS false, in no way would the if statement run the things below, since “not debounce / debounce == true” is NOT satisfied. Or this is not the case? cuz im not familiar with LUA. T_T
I don’t fully understand your second question. When the Lua VM gets to the if statement, it sees that both expressions has to be true for it to run. It then goes on to evaluating both of the expressions.
The second expression is not checking debounce itself as that would cause the if statement to not run. It checks with the expression as a whole: not debounce , not: not debounce / debounce == true. It only checks: not debounce which is just the inverse of debounce and since debounce was initalized as false, not debounce returns true.
Maybe, this version of the code will be easier to understand for you:
local getTool = script.Parent
local replicatedStorage = game:GetService("ReplicatedStorage")
local debounce = true
getTool.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player and debounce then
debounce = false
local tool = replicatedStorage:FindFirstChild("Tool")
local character = player.Character
tool:Clone().Parent = player.Backpack
task.wait(1)
debounce = true
end
end)
The above version of the code is exactly the same but with the debounce value being initialized with true instead of false.
Ok i get the picture now. However, wouldn’t changing debounce from false to true mean that debounce = false is IGNORED? Let me try to run the script line by line:
When debounce == true, tools will be given to the player. Then when part is touched again, debounce is still true (because in the end, debounce = true). So wouldn’t debounce = false mean nothing? Essentially, why can debounce = false prevent tools be constantly given to player when DEBOUNCE becomes true in the end?
Debounce is true and a tool is given to the player.
Debounce is immediately set to false which causes any other future “scripts” to not be run as debounce is shared between the “scripts” and every other if statement will see that debounce has been set to false.
We then give the player the tool.
We then wait for however long we want on this current “script”. It doesn’t matter if any other “scripts” are started during this time as they all will not run because debounce has been set to false which causes them not to run.
Right after we set the debounce back to true so that the player can receive another tool.
If your still struggling to understand, you can always come back tomorrow or in a few hours to give it another go.