Keep scrolling through focus in UI

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

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.

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!

:bust_in_silhouette: Reply From: njamster

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
		elif event.is_action_pressed("ui_down", true):
			accept_event() # prevent the normal focus-stuff from happening

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

Thank you, this works great!

julkip | 2020-03-28 14:53

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


(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 ‘ui_right’ / ‘ui_left’ 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.

trying_but_failing | 2021-12-13 02:49