0 votes

Hi everyone,

I built one of those buttons that trigger action#1 at a quick tap/click and trigger action#2 after holding down for some time. To achieve this, I set up two timers that start when holding down, a short one and a long one.

func _ready():
    timer_long = Timer.new()
    timer_long.set_wait_time(2)
    add_child(timer_long)
    timer_long.connect("timeout", self, "_on_timer_timeout_long")

    timer_short = Timer.new()
    timer_short.set_wait_time(.7)
    add_child(timer_short)
    timer_short.connect("timeout", self, "_on_timer_timeout_short")

func _on_HoldButtonArea_input_event(_viewport, _event, _shape_idx):
    if Input.is_action_just_pressed("mousebuttonclick"):
        timer_short.start()
        timer_long.start()

So releasing before the short timer runs out triggers action#1, holding down until the long timer runs out triggers action#2.

Releasing in between the end of the short timer and the end of the long timer cancels everything. (Mouse-exiting cancels everything at any point, by the way.)

Among some variables there are:

var short_timer_out = false
var long_timer_out = false

func _on_timer_timeout_short():
    short_timer_out = true
    emit_signal("short_timer_finished")
    print ("Short-timer out!")
    timer_short.stop()

func _on_timer_timeout_long():
    long_timer_out = true
    emit_signal("long_timer_finished")
    print ("Long-timer out!")
    timer_long.stop()

The signals are being used for some separate animations to run above the button: A bar filling up from the moment when the short timer finished until the long timer finishes...
I use the variables for dealing with canceling things.

This all works wonderfully, but: only once! As soon as the short timer runs out once, the button does not work properly anymore (quick tap/click won't register anymore etc.).
What I can observe is the cancel-animation that should play after the short timer runs out then also plays when canceling during short-timimg, and this makes me wonder if "timershort.stop" actually really cancels the timer, so/and the timershort.start() really starts at a reset 0 time. I have the impression that the counters might somehow be paused and then resumed instead, messing everything up... could that be the case? Is "timer_short.stop" not "definite" enough?

Any suggestions?

in Engine by (328 points)

1 Answer

0 votes

I believe you don't need to stop timers in timeout callbacks.
If timeout signal is emitted they are already stopped. But I am not sure it will completely solve your problem, maybe try commenting those lines.

By the way, why all by code? Is it to display on this site? Because you can easily make those timer settings in GUI...

by (226 points)

Thanks for your thoughts, gloele.

I startet these button-features by code with that simple ontimer_timeout function and had no idea how complex things would grow afterwards... how would you suggest doing the settings in GUI? (I've been looking into the timer nodes but am not convinced yet.)

What I try to achieve (as a first step) is to "interrupt" a timer and reset it, so it will start at 0 again next time. And I wonder if timer.stop() actually does this properly.
(Not stopping the short timer in the ontimer_timeout function makes it repeat over and over again while holding down the button.)

One weird thing is that finishing the long timer always triggers the action like it should. It's only the short tapping that doesn't work anymore after the short timer runs out once...

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.