Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How can I add a debounce to this?

Asked by 9 years ago

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)

2 answers

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

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:

  • Define some sort of enabled or disabled variable (it's often called debounce but that name is so completely undescriptive you shouldn't use it)
  • At the beginning of an event, check that you're allowed to continue -- if enabled or not disabled. If it's a go:
    • Disable yourself (enabled = false or disabled = true)
    • Do whatever you would do if you weren't adding a debounce
    • Enable yourself (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.

Ad
Log in to vote
0
Answered by
dyler3 1510 Moderation Voter
9 years ago

Please provide explanation with your answers. Simply posting code does not spread knowledge of integral scripting processes which helps people understand the logic and reasoning behind your answer.

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

Answer this question