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

How to fix MouseButton1Click:Wait() not working as expected?

Asked by 2 years ago
textbutton.MouseButton1Click:Connect(function()
    textbutton.MouseButton1Click:Wait()
    print('textbutton clicked twice')
end)

The first time which I double click the textbutton, it works as expected, 2 clicks and the print runs. However the second time, when I clicked only once, it still ran the print.

Can someone tell me how to solve it skipping the :Wait()?

2 answers

Log in to vote
1
Answered by
aviel101 165
2 years ago
Edited 2 years ago

i would do something like this

local clicks = 0
textbutton.MouseButton1Click:Connect(function()
    clicks += 1
    if clicks == 2 then
        print("textbutton clicked twice")
        clicks = 0
    end
end)

I'm kind of bad with explaining but i'll show you step by step how your code works

first function call: (first click)

textbutton.MouseButton1Click:Connect(function()
    textbutton.MouseButton1Click:Wait() -- <-- first function call: waiting for another click
    print('textbutton clicked twice')
end)

second function call: (second click)

textbutton.MouseButton1Click:Connect(function()
    textbutton.MouseButton1Click:Wait() -- <-- second function call: waiting for another click
    print('textbutton clicked twice') -- <-- first function call: printed double click
end)

-- output 'textbutton clicked twice'

third function call: (third click)

textbutton.MouseButton1Click:Connect(function()
    textbutton.MouseButton1Click:Wait() -- <-- third function call: waiting for another click
    print('textbutton clicked twice') -- <-- second function call: printed double click
end)

-- output 'textbutton clicked twice' (x2)

so you can see that from the third click it actually will print after every 1 button press because you have the previous function waiting for a button press. I hope I explained it okay.

0
Oh yea, thanks, that should work. However, out of pure curiosity, I still want to learn why the :Wait(() is skipped. SuperLittleAdmin 257 — 2y
Ad
Log in to vote
1
Answered by 2 years ago
Edited 2 years ago

Preface

I'm writing this answer in response to your comment on aviel101's answer because that's a very valid question that warrants some deep-diving.

Brief Answer

aviel101 actually explained it quite well. Your call to MouseButton1Click:Wait() is not being skipped. There are just several other things going on at the same time in the background. The culprit: asynchrony.

What is Asynchrony?

Asynchrony (or asynchronous programming) is the procedure of splitting the execution of your code up into tasks that (appear) to be running separately and at the same time as everything else in your program.

For example, every time you do the following...

  • Create a new script instance in your game
  • Use coroutines
  • Make HTTP Requests (or use other Async methods)
  • Use spawn()
  • Use wait()
  • Connect event listeners
  • ...etc

... you are directly coding asynchronously. If you notice a pattern with all of the listed items above -- it is that they are all responsible for splitting your code up into tasks or controlling the flow of your program in some way.

Disclaimer: There is a big difference between asynchrony and tasks that are literally running at the same time in parallel (also referred to as parallelism, not to be confused with concurrency). Going further into this topic is beyond the scope of this answer, but feel free to check out the links provided to learn more.

How Does This Relate?

This relates to your question because as listed above, events are a form of asynchrony. More specifically, whenever you create an event connection in your game (like MouseButton1Click, for example), you are creating a new "task", aka the callback function you pass to :Connect(). This callback function will now execute independantly from the rest of your code, it will not wait for anything (aside from the user's mouse click).

This is what you are experiencing as Wait() being skipped, even though it's not. Here's a step-by-step break down of what's happening in your original code snippet, similar to what aviel101 was describing:

first mouse click:

  • Fire all the MouseButton1Click event listeners asynchronously
  • This code from your click event task gets executed:
textbutton.MouseButton1Click:Wait()
  • Wait inside this task until the user clicks again...

second mouse click:

  • MouseButton1Click:Wait() is now triggered from your previous task, and you see the double click message
  • However, your second click also results in the MouseButton1Click event firing again, which runs the same code as before:
textbutton.MouseButton1Click:Wait()
  • This task will now wait yet again for the next click event

third mouse click:

  • Since the previous click ran the same code again, this click triggers MouseButton1Click:Wait() from the previous click...

This pattern will now continue indefinitely. You're in a situation where every mouse click will wait for the next mouse click, because MouseButton1Click:Wait() does not stop the mouse click event from firing again.

Closing Statement

Hopefully this gives you a bit more insight as to what's going on in your code snippet. Async programming is a very broad and wide-range topic, but crucial to understand if you want to become a better programmer. Good knowledge of it will also save you a lot of headache in the long run!

Let me know if you have any questions.

Answer this question