0 votes

I have programmed a menu, using VBoxLayouts and Buttons inside it. How can I tell godot to keep scrolling through the focus of the buttons, while I keep ui_down and ui_up pressed. Right now, I have to re-press the buttons every time I want to focus the next Button.
enter image description here
Until now I have not needed to script anything, and it "just works". I would love to not have to reimplement the whole Input-handling for focus switching by myself to solve it (but I will, if I have to). Does anyone know of a way, where I don't have to?

Thanks in advance!

in Engine by (47 points)
edited by

1 Answer

0 votes
Best answer

Does anyone know of a way, where I don't have to?

There is no way! Take a look at Godot's source code. It explicitly checks for just_pressed there, meaning it will only fire once (on the first frame the button is pressed) and not again (when the button is hold down).

To make it work nonetheless, add this script to each of your buttons:

extends Button

func _gui_input(event):
    if has_focus() and event is InputEventKey:
        if event.is_action_pressed("ui_up", true):
            accept_event() # prevent the normal focus-stuff from happening
            get_node(focus_neighbour_top).grab_focus()
        elif event.is_action_pressed("ui_down", true):
            accept_event() # prevent the normal focus-stuff from happening
            get_node(focus_neighbour_bottom).grab_focus()

Make sure the focus_neighbour_bottom|top-properties are set correctly on each button. I just did it for the "uiup"-actions and "uidown"-actions, but the principle should be clear and expanding this on your own shouldn't be too hard.

by (10,483 points)
selected by

Thank you, this works great!

This is working great for keyboard input, but is there a way to make it work for gamepads as well? In the code above I've changed

event is InputEventKey

to

(event is InputEventKey or event is InputEventJoypadButton)

...but it seems to make no difference. Holding the left or right joystick or d-pad button (both of which are assigned to 'uiright' / 'uileft' in the input map) only goes to the first neighbor, then stops.

Any insight or help would be greatly appreciated. I know this is an old thread, but I've spent most of the day trying to troubleshoot and have gotten nowhere.

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 Frequently asked questions and 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.