Context Menu
A flexible right click menu
Overview
Context Menu creates a dynamic popup menu that appears when the user clicks a specified mouse button. It supports buttons, separators, expandable sections, and fully custom prefab entries.
The menu positions itself based on the pointer location, applies animated transitions, and closes automatically when clicking outside or selecting an item.
The component works both on normal UI and 3D objects and manages multiple active context menus to ensure only one is open at a time.
Usage
Add Context Menu component to a GameObject
Add menu entries to Menu Items
Make sure that Menu Preset is assigned
Menu will appear when clicked
Customize Preset
- Locate the default preset prefab in the References foldout
- Open the prefab and customize it as needed
- Optionally customize the Button, Section, or Separator prefabs
Create New Presets
You can create different Context Menu presets and use them on different objects. To create a new preset:
- Locate the default preset prefab in the References foldout
- Duplicate the default preset (this is the fastest way to customize)
- Open the new prefab and customize it to your liking
- Optionally do the same for the Button, Section, or Separator prefabs
Properties
Content
| Name | Type | Description |
|---|---|---|
menuItems | List<Item> | List of menu entries used to build the context menu |
Each menu entry has:
| Field | Type | Description |
|---|---|---|
itemName | string | Name displayed in the menu |
itemType | ItemType | Button, Separator, Section, or CustomObject |
icon | Sprite | Optional icon displayed next to the label |
onClick | UnityEvent | Invoked when clicking the item (button type only) |
expandOnHover | bool | Whether section items open their submenu on hover |
sectionItems | List<SectionItem> | Items inside a section submenu |
customPrefab | GameObject | Custom object that replaces standard button layout |
Settings
| Name | Type | Description |
|---|---|---|
is3DObject | bool | Enables 3D object interaction instead of UI pointer events |
closeOnItemClick | bool | Closes menu after clicking a button entry |
closeOnOutsideClick | bool | Closes menu when clicking outside the menu |
triggerButton | MouseButton | Mouse button to open the menu (Left, Right, Middle) |
Animation
| Name | Type | Description |
|---|---|---|
animationType | AnimationType | None, Fade, Scale, or Slide |
animationDuration | float | Duration of show and hide animations |
animationCurve | AnimationCurve | Curve controlling ease in and out |
scaleFrom | float | Starting scale used in Scale mode |
slideOffset | Vector2 | Offset direction used in Slide mode |
Position and Offset
| Name | Type | Description |
|---|---|---|
offsetPosition | OffsetPosition | Defines pivot and direction of menu offset |
customOffset | Vector2 | Custom offset used when offsetPosition is Custom |
offsetDistance | float | Default offset distance from pointer |
screenEdgePadding | float | Minimum padding from screen edges |
References
| Name | Type | Description |
|---|---|---|
menuPreset | GameObject | Prefab used to build the menu contents |
targetCanvas | Canvas | Canvas where the menu is instantiated |
Events
| Name | Type | Description |
|---|---|---|
onShow | UnityEvent | Fired when the menu is shown |
onHide | UnityEvent | Fired when the menu is hidden |
Public Methods
| Name | Parameters | Description |
|---|---|---|
Show() | None | Opens the context menu at last click position |
Hide() | None | Starts hide animation or closes instantly |
HideImmediate() | None | Immediately destroys the menu instance |
IsVisible() | None | Returns whether a menu instance is currently active |
OnItemClicked(item) | Item | Called internally when an item is clicked |
SetTriggerButton(index) | int | Changes trigger button by index (0, 1, 2) |
Code Example
using UnityEngine;
using Evo.UI;
public class ContextMenuExample : MonoBehaviour
{
public Evo.UI.ContextMenu menu;
void Start()
{
// Build the context menu programmatically
AddButton();
AddButtonWithIcon();
AddSeparator();
AddSectionWithSubItems();
// Configure menu settings
menu.is3DObject = false; // Set to true for 3D world objects
menu.SetTriggerButton((int)Evo.UI.ContextMenu.MouseButton.Right); // Set pointer trigger button
menu.closeOnItemClick = true; // Auto-close when item is clicked
menu.closeOnOutsideClick = true; // Close when clicking outside
// Listen for when the menu opens
menu.onShow.AddListener(() =>
{
Debug.Log("Context menu opened");
});
// Listen for when the menu closes
menu.onHide.AddListener(() =>
{
Debug.Log("Context menu closed");
});
// Show menu manually
menu.Show();
}
void AddButton()
{
// Create a simple button item
var newItem = new Evo.UI.ContextMenu.Item
{
itemName = "New Item",
itemType = Evo.UI.ContextMenu.Item.ItemType.Button
};
// Add listener to handle clicks
newItem.onClick.AddListener(() =>
{
Debug.Log("New item clicked!");
});
// Add the item to the menu
menu.menuItems.Add(newItem);
}
void AddButtonWithIcon()
{
// Items can display icons alongside text
var iconItem = new Evo.UI.ContextMenu.Item
{
itemName = "Delete",
itemType = Evo.UI.ContextMenu.Item.ItemType.Button,
icon = Resources.Load<Sprite>("Icons/DeleteIcon"), // Set your sprite,
};
iconItem.onClick.AddListener(() =>
{
Debug.Log("Delete clicked");
});
menu.menuItems.Add(iconItem);
}
void AddSeparator()
{
// Separators create visual dividers between menu items
menu.menuItems.Add(new Evo.UI.ContextMenu.Item
{
itemType = Evo.UI.ContextMenu.Item.ItemType.Separator
});
}
void AddSectionWithSubItems()
{
// Sections allow nested menus that expand on hover or click
var sectionItem = new Evo.UI.ContextMenu.Item
{
itemName = "Options",
itemType = Evo.UI.ContextMenu.Item.ItemType.Section,
expandOnHover = true,
sectionItems = new()
{
new Evo.UI.ContextMenu.SectionItem
{
itemName = "Option 1",
itemType = Evo.UI.ContextMenu.SectionItem.ItemType.Button
},
new Evo.UI.ContextMenu.SectionItem
{
itemName = "Option 2",
itemType = Evo.UI.ContextMenu.SectionItem.ItemType.Button
}
}
};
// Add listeners to section items
sectionItem.sectionItems[0].onClick.AddListener(() =>
{
Debug.Log("Option 1 selected");
});
sectionItem.sectionItems[1].onClick.AddListener(() =>
{
Debug.Log("Option 2 selected");
});
menu.menuItems.Add(sectionItem);
}
// Clear all menu items
public void ClearMenuItems()
{
menu.menuItems.Clear();
}
// Remove specific item by name
public void RemoveItem(string itemName)
{
menu.menuItems.RemoveAll(item => item.itemName == itemName);
}
}