local UIS = game:GetService("UserInputService") local Debounce = true local ChargeTime = 0 UIS.InputBegan:Connect(function(input) if input.KeyCode == Enum.KeyCode.Q then Debounce = true while Debounce do local Equipped = script.Parent.EquippedDe.Value ChargeTime = ChargeTime + 1 if ChargeTime == 5 then print("Five Seconds") end print(ChargeTime) wait(1) end end end) UIS.InputEnded:Connect(function(input) if input.KeyCode == Enum.KeyCode.Q then Debounce = false ChargeTime = 0 end end)
Trying to make it print "Five Seconds" if i hold down q for 5 seconds. It works but if i spam Q, the numbers go rapidly, any help?
Try to think of what lines is being executed, one step at a time:
1. The script initializes 2. You press down Q. 'debounce' is now true so the loop starts. It goes through your code until it hits the `wait(1)`. 3. You let go of Q, let's say after 0.2 seconds. 'debounce' is now false. 4. Let's say that 0.3 seconds after that, you press down Q again. Now, InputBegan is going to start again (on a new `coroutine`), set 'debounce' to true, and it's going to start up a new `while` loop. Like before, it goes through your code until it hits `wait(1)`. Notably, since `ChargeTime` is not local to the function, it is shared between coroutines (which is fine), which is why ChargeTime will now be 2. 5. Let's say you hold down Q now for a full second. Before that second is up, the first coroutine (started on step #2) is going to resume and check to see if it should continue the loop. It sees that 'debounce' is true and so keeps going! It increase ChargeTime to 3. At the end of the second, the second coroutine (started on step #4) will do the same thing, increasing ChargeTime to 4. By the time you've let go of Q, ChargeTime is at 4 and it's only been 1.5 seconds total.
Clearly, spamming Q can make this effect even more dramatic.
The problem is that you are trying to use debounce
as a keyDown
variable. debounce
is specifically for preventing a function from executing the code 2+ times at once and is set up like this:
local debounce = false function Example() if debounce then return end debounce = true --code here debounce = false end
Change your debounce
variable's name to keyDown
and then add proper debounce to make sure that you won't run your while
loop more than once at a time. Specifically, make sure to do the if debounce then return end
before the while
loop starts (and make sure to set debounce = true
after the if debounce then return end
and also before the while
loop). Make sure that debounce
will always eventually be set to true after it's been set to false, or else your script will stop running that section entirely. ex, this would be bad:
local debounce = false function Example() if debounce then return end debounce = true print("HI") wait(1) if someCondition then print("Leaving early") return -- <------ this is bad; it returns without setting debounce back to false! end for i = 1, 10 do print(i) wait() end debounce = false end