Unity Editor: Menu Items

Unity Editor: Menu Items

When making a tool, you may want the user to be able to press a button in the navigation menu in Unity. Whether that be to open a editor window, perform a function or clear for player prefs. Making menu items can be very useful for your tools. This post will go through how to set them up and any quirks I found when making my own tools.

Basic setup up

To setup a menu item you need to apply the attribute [MenuItem] to any static editor method. The method doesn’t need to be public for it to work with this attribute. The method does need to be a method either in the editor space such as an editor folder or in an #if define with UNITY_EDITOR, otherwise you won’t be able to make a build of your project. An example below:

This produces the following once compiled:

using UnityEditor;            // Menu item is in the editor namespace.

public static class MyEditorClass 
{
    [MenuItem("My Custom Menu/My Menu Item")]
    private static void OnMenuItemPressed()
    {
        
    }
}

Attribute settings

The attribute requires you to give it a name/path to use. It can go under existing tabs in the navigation menu if you want it to. Just use that tab name as the root and it should go under that tab when comiled. You can also set the order for the item to draw at as an optional override, which can be finiky to get working. Some general tips for setting it up:

  • The menu path cannot be a single item, it much have a root path to be under:
// Valid - Has a parent path.
[MenuItem("My Custom Menu/My Menu Item")]
private static void OnMenuItemPressed()
{
    
}

// Invalid - Will throw an error in the editor.
[MenuItem("My Menu Item")]
private static void OnMenuItemPressed()
{
    
}

Setting the priority can be a pain, sometimes you may need to reload the project for it to take effect while other times it’ll update just fine when compiling. You can get the dividers to show if your priority is greater than 10 from the last in the menu path.

This example produced the following:

using UnityEditor;            // Menu item is in the editor namespace.

public static class MyEditorClass 
{
    [MenuItem("My Custom Menu/My Menu Item", priority = 1)]
    private static void OnMenuItemPressed()
    {
        
    }
    
    
    [MenuItem("My Custom Menu/My Menu Item 2", priority = 13)]
    private static void OnMenuItemPressedAsWell()
    {
        
    }
    
    
    [MenuItem("My Custom Menu/My Menu Item 3", priority = 2)]
    private static void OnMenuItemPressedAlso()
    {
        
    }
    
    
    [MenuItem("My Custom Menu/My Menu Item 4", priority = 100)]
    private static void OnMenuItemPressedAgain()
    {
        
    }
}

If you want, you can also add custom shortcuts to your frequently used menu items. Add them after your I’d be careful with these and only use them when you know its going to be used often as you’ll like hit a conflict with another tool in larger projects.

  • % or ^ = CTRL
  • # = SHIFT
  • & = ALT
  • _ = No prefix buttons

You can combine these together to to make sequences like CTRL – ATL etc. If you just want say “g” to run it without a pre-req button using the _ beforehand to do that.

using UnityEditor;            // Menu item is in the editor namespace.

public static class MyEditorClass 
{
    [MenuItem("My Custom Menu/My Menu Item", priority = 1)]
    private static void OnMenuItemPressed()
    {
    }
    
    
    // Will also run on the shortcut: CTRL-G
    [MenuItem("My Custom Menu/My Menu Item/My Sub-Menu Item %g")]
    private static void OnMenuItemPressedAsWell()
    {
        // Will appear in a sub menu...
    }
}

You can also sub-menu items by making the path longer using a dash to seperate the menu items. This can go on for a long as you like, but I wouldn’t go too mad if I were you. The example here produces:

using UnityEditor;            // Menu item is in the editor namespace.

public static class MyEditorClass 
{
    [MenuItem("My Custom Menu/My Menu Item", priority = 1)]
    private static void OnMenuItemPressed()
    {
    }
    
    
    [MenuItem("My Custom Menu/My Menu Item/My Sub-Menu Item")]
    private static void OnMenuItemPressedAsWell()
    {
        // Will appear in a sub menu...
    }
}
  • There is also an additional override field for a validate function. Though I have yet to find a use-case for this personally in my tools so far. But if you define a menu item method as a validation function, you can do checks before running a menu item like so:
using UnityEditor;            // Menu item is in the editor namespace.

public static class MyEditorClass 
{
    [MenuItem("My Custom Menu/My Menu Item", priority = 1)]
    private static void OnMenuItemPressed()
    {
        // Logic to run only if the check was true...
    }
    
    
    // Note the menu item path is the same as the actual logic method!
    [MenuItem("My Custom Menu/My Menu Item", true)]
    private static bool ValidateOnMenuItemPressed()
    {
        // Do a check here or something...
        return true;
    }
}

Further reading

Unity docs for menu items: https://docs.unity3d.com/ScriptReference/MenuItem.html