Learn Unity Editor Scripting: Menus (Part 4)

No Such Dev
7 min readOct 28, 2020

In this post we will learn how to create menu items in Unity Editor to perform different tasks. You can add menu items to the main menu, or the context menus in the Inspector window.

This article is part of a series in which I explain all the techniques for extending the Unity Editor. See the overview post here.

Prerequisite: You need to know C# programming and be familiar with Unity Editor to benefit most from this post.

There is an accompanying Unity project. I highly recommend downloading it and trying the topics as you read them here. Seeing the examples in action makes them stick to your brain.

For instructions on how to get started with the project, see the overview post.

Without further ado, let’s jump in!

Unity’s Main Menu

We can add menu items to the menus in Unity using the MenuItem attribute. The attribute takes 3 parameters:

  1. itemName: decides the location of the menu item. For example "Help/My Sub Menu/My Menu Item" will add a menu item there.
  2. isValidateFunction: Each menu item can have a corresponding validation function which decides whether the item is enabled or disabled.
  3. priority: decides the sorting order of items in each menu. The items are sorted in ascending order.
    The parent item get their priority from its child menu item with the lowest priority value.
    Items that are apart in priority by 10 or more will have a separator line between them.

The method can take an optional parameter of type MenuCommand. The context field has a reference to the object that the menu is opened for. We will see how we can use this parameter when it is applicable.

A menu item will invoke a static method.

Let’s create a menu item! In the previous post, we created a validation method for the scene in our GameManager class. Let’s write a more general static validation method. The method ValidateScene will first search for the GameManager component in scene and show and error message if one is not found. If it is found it calls the validation method on our GameManager component.

Create a file named MyMenus.cs under the Editor folder in your project and paste this into it (need to add using statements to the top.)

Code explanation:

  • MenuItem attribute is defined in the UnityEditor namespace, so you should either use it in your Editor code or enclose it (along with using UnityEditor;line) with #if UNITY_EDITOR directive.
  • MenuItem attribute can be used with static methods only.

After you save switch back to Unity Editor, our menu will get added to the top.

Pressing it will show a dialog with the result of the validation.

Creating new top level menu items is discouraged by Unity. Imagine if every package that you used created their own menu. It would be total chaos.

Menu Validation Methods

A menu item can have a validation method. The validation method tells Unity whether the menu is enabled or disabled. It applies to all the menus that we discuss further on.

Let’s create a validation method for our menu from before. Add this code to the MyMenus class from before.

Code explanation:

  • The validation method should returnbool. true means the menu is enabled, false means the menu is disabled.
  • I like the Validate<MenuMethodName> naming convention for validation methods. In this case it became weird because the menu name also starts with Validate.

Now in Unity, our menu item is grayed out and cannot be pressed.

Normal Menus

File, Edit, Window and Help are normal menus. They can only be reached from the top menu bar. As we will see later, some menus have special handling and can be accessed from other editor windows in Unity.

Window menu is for showing Editor Windows. We will learn about Editor Windows in the next post. But imagine if we had created a tool like mecanim or asset store or animation panel. We would create a dockable window within Unity for the user to perform tasks. The normal way to show it would be through the Window menu.

For now, we can add a menu item to the Window menu that does the validation. Unity Editor doesn’t check if we actually go with the convention of showing an Editor window. But don’t do it for real assets / packages you make.

Add this code to the MyMenus class from before.

priority 10000, our menu shows last.

Note that our menu item shows last. This is because we set the priority to 10000 which is really high. Let’s reduce the priority to 10.

Unity doesn’t update the menu if only the priority changes. You need to comment the line with the MenuItem attribute, switch to Unity to have the menu item removed and then uncomment the line again.

priority 10, our menu shows near the top.

Now our menu item shows near the top. You have to play around with different values to get your menu item where you want it.

Help menu is for showing references to different learning material. Nothing new here. As an exercise you can add an item that does validation to this menu as well.

GameObject Menu

This menu is special. It is for adding new game objects to your scene and changing the scene hierarchy.

We can add menu items to this menu just as we did before. Items with priority 10 will also show in the hierarchy window’s context menu and create button.

This time instead of validation, let’s create a new game object with our TargetController script already added to it.

Add this code the MyMenus class from before.

code copied and modified from https://docs.unity3d.com/ScriptReference/MenuItem.html

Code explanation:

  • SetParentAndAlign ensures the new gameobject is a child of the currently selected object.
  • Undo.RegisterCreatedObjectUndo will add a new entry to the undo stack so that ctrl + z will delete the newly created game object.
  • Line 7 sets the selection to the newly created game object.
Our menu item in the top level GameObject menu.
Our menu in the Create button in the hierarchy window.

Assets Menu

Assets menu is for creating and managing assets in the project. The items under the Create sub menu will also show in the Project window’s context menu and create button.

CreateAssetMenu attribute

For creating instances of our scriptable objects, we can use the CreateAssetMenu attribute which will add an entry to Assets/Create menu for us. It handles creating the new asset in the selected folder in the Projects window.

Create a new file named MyScriptableObject.cs under your scripts folder with this code.

Now we can create instances of our Scriptable Object from the Assets/Create menu, which shows as context menu and from the + button in the Projects window.

Component Menu

Component menu is used for adding new components to Unity objects. At this point you should be comfortable adding an item to this menu the normal way using the MenuItem attribute.

Our MonoBehaviours normally end up under the Scripts/<namespace>/<Name> path. So we can actually add our custom scripts to our objects.

AddComponentMenu attribute

AddComponentMenu attribute can be used with our component to create a custom path for our component in the Component menu.

Let’s add this attribute to our TargetController class.

Component menu opened from the top menu bar
Component menu opened from Inspector UI

Context Menus in Inspector Window

We can add menu items to Inspector window’s context menu for different components. Let’s go ahead and add a menu item to the context menu for our GameManager component.

Now when we right click the header of the Inspector UI for our component, we have the Validate Scene menu item.

We are not limited to our components only. We can create a new context menu item for Unity’s Text component.

Pressing the menu item will set the font size of this text component to 36.

Conclusion

In this post we learnt about:

  • How to create menu items in Unity’s main menu.
  • Validation methods and how they can be used to enabled / disable our menu items.
  • Special menus: Component menu, Assets menu, GameObject menu.
  • Context menus in Inspector window.

If you have any questions and suggestions about this post, feel free to leave a comment.

If you find this tutorial useful, please support me on Patreon. It takes a good amount of time to write these tutorials and your support will keep me going. Thank you!

In the next post, we will see how to create custom Editor windows.

--

--

No Such Dev

Software Engineer | Indie Game Developer | Founder of No Such Studio. Follow me to learn how to make video games with Unity. http://www.nosuchstudio.com