Why is my Debounce not working?

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
2 Likes

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)
1 Like

Why do you return db? and why do you check if it’s true instead of false?

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)
1 Like

What do you mean by wrapping an if statement?

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.

2 Likes