How can I get a touch screen button signal in just the frame it is pressed?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Victoevel

I have a scene with a TouchScreenButton. However, I don’t want to use the signal all the time the button is pressed, just the first frame it is pressed.
This is what I have tried:

var isPressed = false
var foo = 0

func _on_button_pressed():
    if !isPressed:
        isPressed = true
        foo = 1
    else:
        foo = 0

func _on_button_released():
    isPressed = false
    foo = 0

From what I’ve tested, it never reaches the else statement in the pressed function. I can’t figure this out. Thanks in advance

I would say that the pressed signal already runs just once per press-hold-release, from documentation (it’s really ambiguous tbh): pressed(): Emitted when the button is pressed (down). But you don’t have to calculate anything and that’s why the else statement is never run. I may be wrong though. (And signals aren’t usually emitted multiple times in a short period of time.)

1234ab | 2020-03-27 20:08

:bust_in_silhouette: Reply From: njamster

I don’t want to use the signal all the time the button is pressed, just the first frame it is pressed.

That’s the default behavior. You don’t have to write any code for that!

Take a look at Godot’s source code:

const bool can_press = finger_pressed == -1;
if (!can_press)
    return; //already fingering

if (_is_point_inside(st->get_position())) {
    _press(st->get_index());
}

Here finger_pressed is a global variable defaulting to -1, but set to the index of the InputEvent when _press() is called. After _release() is called, it’s set back to -1. Here _press() is the method emitting the pressed-signal, but it only will be called when can_press is true or the code shown above will return before the call. That’s only the case when finger_pressed == -1 though.


For completeness: If you ever should find yourself in a situation where you want to do something every frame the button is hold down, attach a script like this to it:

extends TouchScreenButton

var time = 0.0

func _process(delta):
	if is_pressed():
        time += delta
	    print("Button is hold down since %d seconds" % time)
    else:
        time = 0.0