Skip to content

MenuController

The MenuController is the part of MenuAPI that actually runs: it draws every registered Menu, handles all controls, and keeps track of which menu is currently open.

You never create one yourself. It is a BaseScript that starts automatically as soon as MenuAPI.dll is loaded by your resource, and every member on it is static, so you always use it as MenuController.Something.

Its main job for you is registering menus (AddMenu(), AddSubmenu() and BindMenuItem()) and giving you a handful of global switches to control how menus behave.


using MenuAPI;
public class MyMenus : BaseScript
{
public MyMenus()
{
// Global settings. These can be changed at any time.
MenuController.MenuAlignment = MenuController.MenuAlignmentOption.Right;
MenuController.MenuToggleKey = Control.SelectCharacterMichael;
MenuController.EnableMenuToggleKeyOnController = false;
// The first menu you register becomes MenuController.MainMenu, which is
// the menu that opens when the user presses the toggle key.
Menu menu = new Menu("Main Menu", "Subtitle");
MenuController.AddMenu(menu);
// Submenus.
Menu submenu = new Menu("Submenu");
MenuItem submenuButton = new MenuItem("Open the submenu");
menu.AddMenuItem(submenuButton);
MenuController.BindMenuItem(menu, submenu, submenuButton);
}
// Somewhere else in your resource:
private void CloseEverything()
{
if (MenuController.IsAnyMenuOpen())
{
MenuController.CloseAllMenus();
}
}
}

All properties are static.

Property Type Default value Description Optional
MainMenu Menu Null The menu that is opened when the user presses the menu toggle key. This is set automatically to the first menu you register, but you can change it at any time. When it is null, the first registered menu is opened instead. Yes
Menus List<Menu> (empty) (Getter only) Every menu that has been registered with AddMenu() or AddSubmenu(). Yes
MenuAlignment MenuAlignmentOption MenuAlignmentOption.Left Whether menus are drawn on the left or the right side of the screen. See Menu alignment. Yes
MenuToggleKey Control Control.InteractionMenu The control that opens MainMenu. See The menu toggle key. Yes
MenuToggleKeyIsValid boolean true (Getter only) Whether the current MenuToggleKey is a control the game accepts (0 - 402). When this is false, the toggle key is ignored entirely. Yes
EnableMenuToggleKeyOnController boolean true Whether the menu can also be toggled with a controller. The controller binding can not be changed: it is always the back/select button, held for 400ms. Yes
DisableMenuButtons boolean false When true, all menu controls are ignored. The menu stays on screen, it just does not respond to input. Useful while you are doing something that should not be interrupted. Yes
AreMenuButtonsEnabled boolean false (Getter only) Whether menu controls are currently being processed. This is false when no menu is open, the game is paused, the screen is faded out, a player switch is in progress, the player is dead, or DisableMenuButtons is true. Yes
DontOpenAnyMenu boolean false When true, menus stop being drawn and can not be opened. Menus with IgnoreDontOpenMenus set to true are excluded. Yes
PreventExitingMenu boolean false When true, the user can not close the menu with the back/cancel control. Submenus can still go back to their parent. Yes
DisableBackButton boolean false When true, the back/cancel control does nothing at all, not even in submenus. Yes
NavigateMenuUsingArrows boolean true When true, pressing left on an item that has no left/right behaviour goes back to the parent menu. Yes
SetDrawOrder boolean true Whether MenuAPI sets the script graphics draw order while drawing. Turn this off if the menu draws over (or under) your own UI in the wrong order. Yes
EnableManualGCs boolean true Whether MenuAPI triggers a manual garbage collect every 60 seconds while no menu is open. Turn this off if your resource manages GCs itself. Yes
ScreenWidth float 1920f (Getter only) The width of the screen, scaled to a 1080p height. This changes with the aspect ratio. Yes
ScreenHeight float 1080f (Getter only) The height of the screen. This is always 1080. Yes

Constant Type Value Description
_texture_dict string “commonmenu” The streamed texture dictionary used for the default menu sprites.
_header_texture string “interaction_bgd” The texture name used for the default menu banner.

All methods are static.


Registers a menu with the controller. A menu is not drawn and does not respond to controls until it has been registered.

If MainMenu is still null, the menu you pass here becomes the main menu.

Parameter Type Description
menu Menu The menu to register. Registering the same menu twice does nothing.

This function does not return anything.

Menu menu = new Menu("Main Menu", "Subtitle");
MenuController.AddMenu(menu);

Registers child (if it was not registered yet) and sets its ParentMenu to parent. That parent/child relation is what makes the back/cancel control return to the previous menu.

Parameter Type Description
parent Menu The menu that the child returns to.
child Menu The submenu.

This function does not return anything.


BindMenuItem(Menu parentMenu, Menu childMenu, MenuItem menuItem)

Section titled “BindMenuItem(Menu parentMenu, Menu childMenu, MenuItem menuItem)”

Turns menuItem into a submenu button: pressing it closes parentMenu and opens childMenu. This also calls AddSubmenu() for you.

Binding the same item again replaces the menu it was bound to.

Parameter Type Description
parentMenu Menu The menu that menuItem belongs to.
childMenu Menu The menu to open when the item is pressed.
menuItem MenuItem The item that opens the submenu.

This function does not return anything.

Menu menu = new Menu("Main Menu", "Subtitle");
MenuController.AddMenu(menu);
Menu submenu = new Menu("Submenu", "Secondary Menu");
MenuItem submenuButton = new MenuItem("Open submenu", "This opens the submenu.")
{
Label = "→→→"
};
menu.AddMenuItem(submenuButton);
// Registers `submenu`, sets its parent, and binds the button to it.
MenuController.BindMenuItem(menu, submenu, submenuButton);

Returns the menu that is currently open.

This function does not have any parameters.

Type Description
Menu The currently open menu, or null if no menu is open.
Menu current = MenuController.GetCurrentMenu();
if (current != null)
{
Debug.WriteLine($"'{current.MenuTitle}' is open, on item {current.CurrentIndex}.");
}

Returns whether any menu is currently open.

This function does not have any parameters.

Type Description
boolean True if at least one menu is open.
// Don't let the player shoot while a menu is open.
if (MenuController.IsAnyMenuOpen())
{
Game.DisableControlThisFrame(0, Control.Attack);
}

Closes every open menu. Each closed menu triggers its own OnMenuClose event.

This function does not have any parameters.

This function does not return anything.


Menus can be drawn on the left or the right side of the screen, and this can be changed at any time during runtime. The menu updates instantly, and both alignments scale with the safezone size automatically.

Value Description
MenuAlignmentOption.Left Menus are drawn on the left side of the screen. This is the default.
MenuAlignmentOption.Right Menus are drawn on the right side of the screen.
// Right align all menus.
MenuController.MenuAlignment = MenuController.MenuAlignmentOption.Right;
// Let the user toggle it with a checkbox.
MenuCheckboxItem alignBox = new MenuCheckboxItem("Right aligned menu", "Move the menu to the other side.", false);
menu.AddMenuItem(alignBox);
menu.OnCheckboxChange += (_menu, _item, _index, _checked) =>
{
if (_item == alignBox)
{
MenuController.MenuAlignment = _checked
? MenuController.MenuAlignmentOption.Right
: MenuController.MenuAlignmentOption.Left;
}
};

MenuAPI handles all menu controls for you, including one key that opens MainMenu. By default that is Control.InteractionMenu (the interaction menu key, M on a default keyboard layout).

// Use a different key.
MenuController.MenuToggleKey = Control.SelectCharacterMichael;
// Decide which menu the toggle key opens.
MenuController.MainMenu = myOtherMenu;
  • Pressing the toggle key while a menu is open closes that menu, unless PreventExitingMenu is true.
  • Only controls in the range 0 - 402 are accepted. If you set anything else, MenuToggleKeyIsValid becomes false and the toggle key is ignored entirely (all other menu controls keep working).
  • When MainMenu is null, the first registered menu is opened instead. If no menus are registered at all, nothing happens.
  • The controller binding can not be changed: it is always the interaction menu button, held for 400ms. Set EnableMenuToggleKeyOnController to false to disable it.

If you would rather open menus yourself, ignore the toggle key and call Menu.OpenMenu() from your own command or key mapping.