Custom Editors in Unity3D – Appendix A: Menus

In this first appendix, we’re going to take a look at how to add options to various menus within Unity to provide easy access to custom functionality that we have written.  Menus are pretty simple, so this should be a relatively short post – let’s get started!

There are three primary places you can put menu items in Unity:

  • The primary Unity Menu Bar (generally at the top of the screen, where ‘File’, ‘Edit’, etc are)
  • A Component’s context menu (when you right click on a component in the editor)
  • A Component field/member’s context menu (when you right click on an editable variable inside of the inspector)

Each of them has a slightly different way of doing things, so I’ll go over each of them individually with a simple example.

Menu Bar

The first place we’ll look at adding menu items is the main menu bar at the top of the screen.  If you’ve read my post on EditorWindows, you’ve already seen this in action!

In order to add an item to the MenuBar, you just need to add the [MenuItem(string)] attribute to a static function inside of some piece of Editor code (anything below a folder named ‘Editor’), passing in the name you want to show up in the menu itself (you can use ‘/’ to indicate sub-menus).  Once this is done, you’ll see your menu item show up, and clicking it will call the function you attached MenuItem to.

Let’s take a look at a simple example:

[MenuItem("Custom/Test Menu Item")]
public static void TestMenuItem()
{
    Debug.Log("Menu Item Selected!");
}

MenuItemExample

This one’s super simple – a static function inside of a Custom Editor (though it could be any class inside of an Editor folder) that adds a new Menu – ‘Custom’, with one element – ‘Test Menu Item’.  When clicked, it simply outputs “Menu Item Selected!” – obviously you can do much more exciting and useful things though – it all depends on what you need!

Component Context Menu

The next place we’ll look at adding menu items in in the context menu for a component.  This is what shows up when you right click on a Component in the inspector (By default, it includes things like ‘Reset’, ‘Remove Component’, ‘Copy/Save Component’, etc).

To add items to this menu, we just add the [ContextMenu(string)] attribute to a function inside of the component’s class, and a new context menu item gets added with the name passed to ContextMenu, that calls the function that the attribute was attached to.

Here’s a simple example:

public class MenuExampleComponent : MonoBehaviour
{
    public float aFloatValue = 0.0f;

    //...

    [ContextMenu("Reset Value")]
    void ResetValue()
    {
        aFloatValue = 0.0f;
    }
}

ContextMenuExample

 

In the example above, we have a MonoBehavior – ‘MenuExampleComponent’, with a float named aFloatValue, and a function called ResetValue (clever names, I know!), with a context menu entry called ‘Reset Value’ that sets aFloatValue to 0.  As you can see from the screenshot of the result, right clicking on the component has an extra option, ‘Reset Value’, which, when clicked, sets aFloatValue to 0.

Member Context Menu

The third and final place to add menu items that we’ll look at is adding a context menu to a specific member of a component – that is, anything that you can edit in the inspector.  We do this using the [ContextMenuItem(string, string)] attribute, applied to the field itself.  The two parameters passed in are the name that we want to display in the context menu, and the name of a function that we want to call whenever that menu item is selected.  As with MenuItem, you can use ‘/’ here to add sub-menus.  Let’s look at a version of MenuExampleComponent with a few more options added to aFloatValue itself:

 

public class MenuExampleComponent : MonoBehaviour
{

    [ContextMenuItem("Modify/Increment", "IncrementValue")]
    [ContextMenuItem("Modify/Decrement", "DecrementValue")]
    [ContextMenuItem("Round", "RoundValue")]
    [ContextMenuItem("Reset", "ResetValue")]
    public float aFloatValue = 0.0f;

    [ContextMenu("Reset Value")]
    void ResetValue()
    {
        aFloatValue = 0.0f;
    }

    void IncrementValue()
    {
        aFloatValue += 1.0f;
    
    }

    void DecrementValue()
    {
        aFloatValue -= 1.0f;
    }

    void RoundValue()
    {
        aFloatValue = Mathf.Round(aFloatValue);
    }
}

ContextMenuItemExample

In the example above, we added ResetValue directly to aFloatValue, as well as three new options: ‘Round’, and a sub-menu called ‘Modify’ with options ‘Increment’ and ‘Decrement’.  The screenshot above shows the final result of clicking on aFloatValue itself in the inspector.

If you want a more direct link to the full source of  MenuExampleContext, you can find it here.

 

And that just about wraps up how to add menu items to various spots in the Unity Editor.  These can be useful for all kinds of things – from instantiating EditorWindows to clearing components, to ….really any other custom code you can think of!

As always, if you have any questions or comments about this post, feel free to leave them in the comments below!

 

One thought on “Custom Editors in Unity3D – Appendix A: Menus

  1. This whole series was extremely helpful! 🙂
    I try to learn unity for a week now and I have a question:
    Let’s say I want to add the Round context menu to *every* float field in the whole inspector. How do I do this? As far as I understand the custom stuff only works for custom components/scripts? Is it possible to extend the “default” components in the inspector, too?

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *