I tried to even tried to add waits. It's a sliding door and it has sound to it, but the door glitches too much and plays the sound again and again because it keeps detecting humanoid. How can I create a debounce?
bin = script.Parent openTime = .5 closeTime = 0 openState = bin.DoorScript.open function touch(hit) if hit.Parent == nil then return end local p = game.Players:playerFromCharacter(hit.Parent) if p ~= nil then if openState.Value then closeTime = openTime -- Prolong open time else openState.Value = true closeTime = openTime while closeTime > 0 do wait(0.1) closeTime = closeTime - 0.1 end openState.Value = false wait(2) end end end bin.trigger1.Touched:connect(touch)
The idea behind a "debounce" is that only one event can touch anything at the same time.
You can actually think of it in a way as "disabling" the event:
local enabled = true -- begin in a state where ALL events matter function event() if enabled then -- I'm enabled! enabled = false -- I'm not longer "enabled" (to everyone else) -- ...but I'm gonna do my thing, and then re-enable me for i = 1, 10 do wait() -- do whatever end enabled = true -- I'm done, so everyone else can start up end end
Three parts:
enabled
or disabled
variable (it's often called debounce
but that name is so completely undescriptive you shouldn't use it)if
enabled
or not disabled
. If it's a go:
enabled = false
or disabled = true
)enabled = true
or disabled = false
)I am not particularly fond of the debounce pattern. Since you're effectively disabling the thing, while anything is moving, all input is ignored. That's not usually intuitive or fun to deal with as a player.
Instead, I like to make my events instantaneous, and a loop in the background responds to variables set.
For instance, consider this simple sliding door with an open
and a close
(including a debounce)
local door = script.Parent local home = door.CFrame local enabled = true function open() if enabled then enabled = false for i = 1, 20 do door.CFrame = home + Vector3.new(0, i, 0) wait() end enabled = true end end function close() if enabled then enabled = false for i = 1, 20 do door.CFrame = home + Vector3.new(0, 20 - i, 0) wait() end enabled = true end end
I prefer this shape:
local door = script.Parent local home = door.CFrame local speed = 0 function open() speed = 0.5 end function close() speed = -0.5 end local y = 0 while wait() do door.CFrame = home + Vector3.new(0, y, 0) y = y + speed if y > 20 then y = 20 end if y < 0 then y = 0 end end
Rather than actually doing the work for opening & closing, you just say the direction to go and another loop takes care of it. This simplifies the events and reduces how much you repeated, while making the looping part only slightly more complicated.
Why? The debounce pattern is an attempt to avoid illegal states -- you use debounce to prevent opening and closing at the same time, or opening & opening at the same, etc.
With this design, the only state is whether or not you are currently opening or closing -- there's no way to mess up and let it both open and close because for any number you set speed
to, you get a well-behaved result.
Try this:
bin = script.Parent openTime = .5 closeTime = 0 Debounce=false openState = bin.DoorScript.open function touch(hit) if Debounce==false then Debounce=true if hit.Parent == nil then return end local p = game.Players:playerFromCharacter(hit.Parent) if p ~= nil then if openState.Value then closeTime = openTime -- Prolong open time else openState.Value = true closeTime = openTime while closeTime > 0 do wait(0.1) closeTime = closeTime - 0.1 end openState.Value = false wait(2) end end Debounce=false end end bin.trigger1.Touched:connect(touch)
(Sorry about no identations, i'm on my phone).
Anyways, I just added a value that when set to false will allow the function to be triggered, and when it's true it won't allow it to go through. I believe it should work now. If yoy have any further questions/problems, please leave a comment below. Hope I helped :P