> For the complete documentation index, see [llms.txt](https://mindcodeinteractive.gitbook.io/easy-build-system/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mindcodeinteractive.gitbook.io/easy-build-system/reference/building-menus-ui.md).

# Building Menus UI

UI menus with customizable categories and slot actions for browsing and selecting [Building Parts](/easy-build-system/reference/building-part.md). Available as a scrollable **Catalog** or a **Radial** layout. Each slot executes a configurable action.

{% hint style="info" %}
Both menus share the same base class (`BuildingMenuUI`) and the same slot action system.\
Switching between layouts does not require changing your action setup.
{% endhint %}

***

### How Menus Work

Each menu holds a list of **categories**. Each category contains **slots**.\
Each slot holds a configurable **action** that runs when the player confirms the selection.

Menus support three input modes:

* **Standalone** : Keyboard + mouse.
* **Mobile** : Touch input.
* **Gamepad** : Controller navigation.

A toggle key (or Input Action) opens and closes the menu.\
The cursor can be locked while the menu is open and is restored on close.\
Menus do not raise gameplay events directly, slot actions call `BuildingController` methods instead.

***

### Menu Types

#### Catalog Menu

Categories and slots organized in a scrollable list.\
Categories appear as tabs or buttons at the top, slots display in a grid below.\
Best for **large part libraries** with many categories.

#### Radial Menu

Categories and slots arranged around a center point. Slots appear as segments in a circle.\
Best for **quick selection** with a small number of options per category.

***

### Slot Actions

Each slot holds one action that implements `IBuildingMenuSlotAction`.\
The following built-in actions are included:

<table><thead><tr><th width="236.4000244140625">Action</th><th>Description</th></tr></thead><tbody><tr><td><strong>Building Selection Action</strong></td><td>Selects a Building Part and enters placement mode.</td></tr><tr><td><strong>Building Mode Action</strong></td><td>Switches to a specific building mode (Destruction, Adjustment, etc.).</td></tr><tr><td><strong>Building Upgrade Action</strong></td><td>Enters upgrade mode with a target variant index.</td></tr><tr><td><strong>Category Selection Action</strong></td><td>Switches to a different category within the menu.</td></tr><tr><td><strong>Custom Invoke Action</strong></td><td>Calls a custom <code>UnityEvent</code> for any logic you need.</td></tr></tbody></table>

***

### Creating a Menu

1. Go to `Tools > Mind Code Interactive > Easy Build System > UI` and choose:\
   **Create Building Catalog Menu** or **Create Building Radial Menu**.
2. A pre-built menu prefab is added to your scene.
3. Select the menu in the hierarchy and configure it in the inspector.

{% hint style="warning" %}
Only one menu of each type should be present in the scene. Both expose a static `Instance` accessor.
{% endhint %}

***

### Adding a Category

1. Select the menu in the scene hierarchy.
2. In the inspector, locate the **Categories** list.
3. Click `+` to add a new category and set its **Name**.
4. Set the **Default Category Index** if you want this category to be shown on open.

For the Catalog menu, category tabs are generated automatically from this list.\
For the Radial menu, each category corresponds to a radial layer that is enabled when selected.

***

### Adding a Slot

1. Expand a category in the **Categories** list.
2. Click `+` on the **Slots** list to add a new slot.
3. Fill in the slot fields :
   * **Name** : Display name shown in the UI.
   * **Description** : Optional tooltip / detail text (used by the Radial menu).
   * **Icon** : Fallback `Texture2D` used when the action does not provide one.
   * **Action** : Pick a slot action type from the dropdown.
4. Configure the chosen action (for **Building Selection Action**, drag a [Building Part](/easy-build-system/reference/building-part.md) into the field).

***

### Adding a Custom Action

You can extend the menu with your own logic in two ways.

#### Using Custom Invoke Action

Use **Custom Invoke Action** when you only need to trigger a UnityEvent (open another menu, play a sound, etc.). No scripting required.

1. Add a new slot.
2. Set the action to **Custom Invoke Action**.
3. Bind your method to the **On Execute** UnityEvent.
4. Optionally enable **Close Menu** to close the menu after the call.

#### Writing a New Action Class

For reusable logic, implement `IBuildingMenuSlotAction` :

{% code title="MyCustomAction.cs" %}

```csharp
using System;
using UnityEngine;

using MindCodeInteractive.EasyBuildSystem.Framework.Code.Runtime.UI.BuildingMenus.Abstracts;
using MindCodeInteractive.EasyBuildSystem.Framework.Code.Runtime.UI.BuildingMenus.Actions;
using MindCodeInteractive.EasyBuildSystem.Framework.Code.Runtime.UI.BuildingMenus.Data;

[Serializable]
public class MyCustomAction : IBuildingMenuSlotAction
{
    [SerializeField] private string m_message;

    private BuildingMenuUI m_menu;

    public void Initialize(BuildingSlotData owner, BuildingMenuUI menu) => m_menu = menu;

    public Texture2D GetIcon(Texture2D fallback) => fallback;

    public void Execute()
    {
        Debug.Log(m_message);
        m_menu?.CloseMenu();
    }
}
```

{% endcode %}

Once the class compiles, **MyCustomAction** appears in the slot **Action** dropdown.

***

### Scripting Examples

**Open and close a menu :**

```csharp
BuildingCatalogMenuUI.Instance.OpenMenu();
BuildingCatalogMenuUI.Instance.CloseMenu();

BuildingRadialMenuUI.Instance.OpenMenu();
BuildingRadialMenuUI.Instance.CloseMenu();
```

**Check if a menu is open :**

```csharp
bool isOpen = BuildingCatalogMenuUI.Instance.IsOpen;
```

**Detect if the menu was closed this frame** (useful to prevent the same input from being re-used by gameplay code right after closing) :

```csharp
bool justClosed = BuildingCatalogMenuUI.Instance.WasClosedThisFrame;
```

**Switch category :**

```csharp
BuildingCatalogMenuUI.Instance.SelectCategory(categoryIndex);
```

**Get the current category :**

```csharp
int index = BuildingCatalogMenuUI.Instance.CurrentCategoryIndex;
BuildingCategoryData category = BuildingCatalogMenuUI.Instance.CurrentCategory;
```

**Get the last selected slot index :**

```csharp
int slotIndex = BuildingCatalogMenuUI.Instance.SelectedSlotIndex;
```

**Access current slots :**

```csharp
List slots = BuildingCatalogMenuUI.Instance.SlotUIs;
```

**Listen for slot hover events :**

```csharp
BuildingRadialMenuUI.Instance.OnSlotHoveredEvent += (int slotIndex) =>
{
    Debug.Log("Hovered slot : " + slotIndex);
};
```

**Disable menu input temporarily** (e.g. when another UI is in focus) :

```csharp
BuildingCatalogMenuUI.Instance.InputEnabled = false;
```

**Rebuild all slots at runtime** (after modifying categories or slots by script) :

```csharp
BuildingCatalogMenuUI.Instance.ForceRebuildAllSlots();
BuildingRadialMenuUI.Instance.ForceRebuildAllSlots();
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://mindcodeinteractive.gitbook.io/easy-build-system/reference/building-menus-ui.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
