Hoping this makes sense...

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

So, I’m programming a pause menu using a Vector2 position to denote which icon is currently highlighted. (0, 0 being the top left and 2, 2 being the bottom right).

Default    Weapon 1   Item 1
Weapon 2   Weapon 3   Item 2
Weapon 4   Weapon 5   Item 3

In game, I’m trying to get the menu to skip over unacquired weapons (weapon 1-5 have to be found). Default and the items are all selectable regardless. Is there an easy way to do this or am I stuck checking every directional possibility with each button press?

:bust_in_silhouette: Reply From: Sween123

Using a dictionary instead.
For example: var equipments = {}
For each weapon, item, create a dictionary, or a scene, and add them into equipments
The dictionary or a scene that represents a weapon or item should contains infos like “is_acquired”, “selectable”, “button_scene”, etc. (You decide what infos you want to have)
For each button, if it is for specific equipment, you can make it use your equipment scene, or dictionary, to bind it to self. For example, if you have an dictionary EQIUPMENT, EQUIPMENT.button = YourButton.
Basicly the main idea is to use one dictionary to keep all equipments, and each equipment should have a dictionary or be a scene to control its infos and functions.
Go with this idea, and what exactly those dictionaries should contain is according to what you want to have and how you want to design.

:bust_in_silhouette: Reply From: njamster

While our understanding of “easy” might differ, this is how I would do it:

Setup a GridContainer (columns-property set to 3), then add nine Buttons as children. The first three buttons will form the top-row, the three after that will be the middle row and the last three will end up in the bottom row. Finally add the following script to the GridContainer:

extends GridContainer

func _ready():
    # disable focus changes with the mouse (optional)
    for button in get_children():
        button.mouse_filter = MOUSE_FILTER_IGNORE

    # disable unacquired weapons
    for i in [2, 4, 5, 7, 8]:
        # get the i-th button in the grid
        var button = get_node("Button" + str(i))
        # make the button no longer focusable
        button.focus_mode = Control.FOCUS_NONE
        # disable the button visually as well
        button.disabled = true

    # select the first button by default
    $Button.grab_focus()

If you run the scene, the top-left button should be focused by default. As long as you haven’t overwritten the default input map, you should be able to select a different button using the arrow keys, skipping over the disabled buttons.

If the player acquires a new weapon, you would simply reset the button:

func unlock_weapon(id):
    # get the id-th button in the grid
    var button = get_node("Button" + str(id))
    # make the button focusable again
    button.focus_mode = Control.FOCUS_ALL
    # re-enable the button visually as well
    button.disabled = true

Depending on your exact use case, you might be better off using TextureButton instead of Button. If you want your menu to loop (e.g. pressing left on the leftmost button will select the rightmost button in the same row), you would have to set the focus_neighbor_(top|right|bottom|left) properties of the buttons accordingly.