0 votes

As is, when scrolling through a button list on mobile, pressed signals are sent as soon as a touch occurs, without first checking if the user is scrolling. I'm not sure if it's just not implemented for mobile. This can be applied to most controls that have pressable buttons like trees and itemlists. Please tell me your work around for this.

in Engine by (12 points)

2 Answers

0 votes

how did you connect your buttons to the signals?

as a work around, you could make the buttons only react on doubleclick/doubletapping.

by (289 points)

I've been trying to connect Button signals to a function.

to ask more specific:
a: what signal did you use
b: did you connect them via gdscript or via godot ide?

maybe you could give us some code.

I would like to just use Object.connect() with the Button signal, pressed(). I must have explained my problem wrong, because you shouldn't need any code to understand it. If I make a scene with CanvasLayer > ScrollContainer > VBoxContainer > Buttons, then test it, I can scroll fine with swiping, but the Button below the beginning of the swipe will become pressed. Obviously on mobile, you don't want buttons to be pressed while the user is scrolling. Does this make sense?

I must have explained my problem wrong, because you shouldn't need
any code to understand it

i only asked for code so i can use it to faster replicate the problem on my computer or to see an overseen mistake.

but after your description this sounds like a problem on godots part. moving your finger over the screen should be like mouse movement and not clicking. pls consider reporting this here:
https://github.com/godotengine/godot/issues

+1 vote

I have used a TextureButton inside a Panel (any control node will do) with the following input processing code:

func _on_ActionButton_gui_input(event : InputEvent) -> void:
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and _is_within_button(event.global_position):
            _handle_press(event.pressed)
        else:
            _reset_state()
    elif event is InputEventMouseMotion:
        if event.speed.length() > IDLE_DRAG_SPEED:  # has to be a small value between 10 and 20
            _reset_state()


# unfortunately gui_input event gets triggered even if event occurs outside control node area
func _is_within_button(event_position : Vector2) -> bool:
    return event_position.x >= rect_global_position.x and event_position.x <= rect_global_position.x + rect_size.x and \
            event_position.y >= rect_global_position.y and event_position.y <= rect_global_position.y + rect_size.y


# Using a timer to wait for 0.1s for any drag event to cancel triggering pressed action
func _on_Timer_timeout() -> void:
    if visible and not button.disabled:
        $Timer.stop()
        emit_signal("action_button_pressed")


func _reset_state() -> void:
    press_input_started = false

    if not $Timer.is_stopped():
        $Timer.stop()


func _handle_press(is_pressed : bool) -> void:
    if is_pressed:
        press_input_started = true
    elif press_input_started and $Timer.is_stopped():
        press_input_started = false
        $Timer.start()

The action_button_pressed signal is only emitted if panel is tapped and minimal or no dragging occurs until finger is removed from screen.

(TextureButton is only used for button state management (normal/pressed/hover/disabled))

by (86 points)
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.

Categories