Creating a gamepad controllable menu

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

Hi everyone !

I’ve been looking for a great tutorial on how to make a menu that is selectable with a gamepad. Everyone that I find is using the mouse, but my game is made to be played with a controller…

Thanks a lot ! !!

:bust_in_silhouette: Reply From: Wakatta

The best way would be to setup Input mapping this way your gamepad buttons can be reassigned during gameplay and you can use the mouse/keyboard if the gamepad is not attached.

Now to answer your question really depends on how your menu is structured
Since you did not provide one, will use this setup as a demonstration

For all your Control nodes set the focus_next and focus_previous properties in the editor located under the Focus tab

On the MainMenu scene you can have a script like this and show/hide it as needed

func _show():
    .show() #important when overriding
    set_process_input(true)

    # grab focus of the first node
    $HBoxContainer/VBoxContainer/Menu options/Continue.grab_focus()

func _hide():
    .hide() #important when overriding
    set_process_input(false) #disable input for this node

func _input(event):
    var current = get_focus_owner()
    if not current: #should not happen but in case it does
        return

    if event is InputEventJoypadMotion:
        if event.axis == JOY_AXIS_1: #vertical left stick
            if event.axis_value == -1.0: #full motion up
                var prev = get_node(current.focus_previous)
                prev.grab_focus()
            elif event.axis_value == 1.0: # full motion down
                var next = get_node(current.focus_next)
                next.grab_focus()

    if event is InputEventJoypadButton:
        #the confirmation button is pressed
        #this will be JOY_SONY_X Playstation JOY_XBOX_A on Xbox
        if event.button_index == JOY_BUTTON_0 and event.pressed:
            if current is Button:
                current._pressed() # emulate button press
                #current.emit_signal("pressed") #emulate button press