Learn Unity Editor Scripting: Menus (Part 4)
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:
- itemName: decides the location of the menu item. For example
"Help/My Sub Menu/My Menu Item"
will add a menu item there. - isValidateFunction: Each menu item can have a corresponding validation function which decides whether the item is enabled or disabled.
- 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 theUnityEditor
namespace, so you should either use it in your Editor code or enclose it (along withusing UnityEditor;
line) with#if UNITY_EDITOR
directive.MenuItem
attribute can be used withstatic
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 return
bool
.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.
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.
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 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.
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.
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.