Managing Submenu Control Nodes like a Stack

Godot Version

4.4

Question

So I have been playing around some more with multiple Control Nodes, but one thing I want is like this. Take a look at this screenshot:

While this game is originally joystick control, I believe later port accepts touch inputs. For my case, I would like to handle both joystick and keyboard and mouse.

So here’s the thing: when you select this character, the game shows all sort of status, equipments, etc. Now, on the equipment section, we select the right-handed weapon, then the game creates another submenu overlay and lists out all equipments we could choose. This is it. When we are on this submenu overlay, all other preceding menu elements are technically “unreachable”. You cannot do anything on preceding menus, and only the topmost menu could be interacted. You must pick an equipment here first, then and only then the preceding menu will be available to interact. This is like a Stack where only topmost element is available while everything else is not available.

In this case, for Godot, what would be the recommended way to do this? Imagine I have something like this Pause Menu:

RESUME GAME
OPTION
EXIT GAME

When I pressed on OPTION, the OPTION Control Node comes up, and there could be other submenu in the OPTION further. But then the RESUME GAME button could still be pressed and the game is resumed…

I am thinking it might be better to create a Stack system that whenever a new submenu is to be on top, the preceding menu Node is to be disabled entirely, then push into the Stack. Afterward, once the submenu is dismissed, we pop the Stack back and re-enable this preceding Node. So this design allow you to have submenus of many levels.

Should I design it just like the above paragraph or are there better recommended ways for Godot in this case?

Help > Programming

1 Like

To block mouse input you can just add a plain Control node covering the are you don’t want to interact with at the bottom of your popup (the first child in the hierarchy) and set its Control.mouse_filter to Stop