Hello, I made a debounce so that whenever the ball is touched, it doesn’t repetitively transfer an event and cause the issue of the ball being able to get an ability affect multiple times at once.
For some reason though, the touch event gets fired many times, and even with the debounce, its not being stopped. How can I fix this issue in my game?
Here is the script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local BM = ReplicatedStorage:WaitForChild("Values"):WaitForChild("BallMultiplier") -- Multiplier when the ball gets abilities
local BDT = ReplicatedStorage:WaitForChild("Values"):WaitForChild("BallDecreaseTime") -- Decresses time of adding points
local BIV = ReplicatedStorage:WaitForChild("Values"):WaitForChild("BallIncreaseValue")
local SpinnerCount = ReplicatedStorage:WaitForChild("Values"):WaitForChild("SpinnerCount").Value
local SpinnerMultiplier = ReplicatedStorage:WaitForChild("Values"):WaitForChild("SpinnerMultiplier").Value
local Ball = script.Parent.Parent.Parent.Parent
DB = false
while true do
task.wait(1-BDT.Value)
script.Parent.Value = (script.Parent.Value+BIV.Value)
Ball.Touched:Connect(function(hit)
if DB == false then DB = true end
if hit.Name == "Spin" then
for i = 1,SpinnerCount do
Ball.BrickColor = BrickColor.random()
script.Parent.Value = script.Parent.Value * SpinnerMultiplier
task.wait(1)
end
end
DB = false
end)
end
First of all, creating a new Touched listener every second is a disaster waiting to happen and will eventually use a lot of memory. Create the Touched event only once, or else your code may be running hundreds or thousands of times every single touch.
Second, your debounce isn’t working because there is no logic to prevent the function from continuing to run. Your function should look something like this:
Ball.Touched:Connect(function(hit)
if DB then return end
DB = true
-- do whatever
task.wait(1)
DB = false
end)
If you want to look more into debounce, I would recommend this article:
I did the reverse logic, where instead of a wrapping if statement, I just did an exit condition. Esentially, the difference between:
Ball.Touched:Connect(function(hit)
if not DB then
-- do whatever
end
end)
Ball.Touched:Connect(function(hit)
if DB then return end -- exit function, nothing below executes
-- do whatever
end)
which are functionally identical.
Also, after writing that response I realized you could instead use the new property, CanTouch, which can be used for the functionality as the debounce but significantly better with 1) less logic required in the code and 2) more performant as it prevents unwanted Touched events from firing. I would use something like this:
Ball.Touched:Connect(function(hit)
Ball.CanTouch = false -- ball cannot be touched, and listener cannot fire
-- do whatever
Ball.CanTouch = true -- ball can be touched again, allowing listener to fire
end)
A wrapping if statement isnt a technical term of any sort, but I used it to describe an if statement that holds the entire body of a function. This isn’t a bad thing to use at all, but I like to avoid them in favor of an early exit condition (if some condition then break from function) which can sometimes improve readability, such as when you may have nested if statements (if statements within other if statements) or have a long function (around 20+ish lines of code)
This is just a stylistic choice, and doesn’t make a difference in the execution of your code, but is a fun thing to think about when designing a program.