一、基本功能介绍
MenuItem是UnityEditor下的属性,它是对编辑器的扩展,主要有两大作用:
第一,在主菜单中添加菜单项,也就是在以下编辑器部分添加,这是一个很重要的用途,在开发插件的时候经常用到。
示例代码如下:
[MenuItem("MyMenu/LookCamera")]
static void LookCamera()
{
//
}
注意:函数一般都是私有的,而且必须是静态函数才能使用MenuItem属性。为什么必须是static函数呢,因为该类可以不用实例化,不用继承自MonoBehavior,比如给刚体添加一个重置属性功能,就不需要添加脚本组件,因此,我们就可以在一个扩展脚本中集中很多类似的菜单项。
可以在第一个字符串参数中添加快捷键,具体参考官方文档:MenuItem-Reference;
第二,在属性面板的组件的上下文中添加菜单项,针对编辑器中已有组件的扩展,如下图,这是为刚体组件添加的右键上下文的菜单项,可用于调试等。
示例代码如下:
[MenuItem("CONTEXT/Rigidbody/Do Something")]
static void DoSomething(MenuCommand command)
{
Rigidbody body = (Rigidbody)command.context;
body.mass = 5;
Debug.Log("Changed Rigidbody's Mass to " + body.mass + " from ContextMenu..."+command.context);
}
二、MenuItem构造函数
public MenuItem(string itemName);
public MenuItem(string itemName, bool isValidateFunction);
public MenuItem(string itemName, bool isValidateFunction, int priority);
- ItemName:菜单项名称
- isValidateFunction:这是一个bool类型变量,一般来说都为false;它是用来决定接下来响应的这个函数是否是一个验证函数,如果它是true,它就是一个验证函数,那么就要有一个同名的菜单项但是第二个变量为false的与之对应,它的意义就是每次执行所需要的函数前必须首先调用验证函数
- priority:决定了菜单项在菜单中的顺序
[MenuItem("Edit/Reset Selected Objects Position (No Undo)",true)]
static bool ValidateSelection()
{
if (Selection.gameObjects == null)
return false;
return true;
}
[MenuItem("Edit/Reset Selected Objects Position (No Undo)")]
static void ResetSelectionPosition() {
//
}
Priority如何决定顺序:首先在同一级下,会按照Priority来判断位置,如果有两个相邻菜单项的Priority的值差距大于10,就会在这两个菜单项中间加上一条线;如果没有指定Priority,就会将其放置到最后面的位置;
Window窗口下的Asset Store和Package Manager两个菜单项的值分别为1499和1500;如果想要加入到某个菜单项的某一栏中,可以到unity编辑器源码中查询这一栏中的菜单项的order即可;(所有新菜单都会放置在Component和Window之间,而且顺序按照添加脚本到Unity编辑器的顺序来定,也就是菜单的位置不可由开发者定义,我们也不需要关心);
- 快捷键使用:在命名之后加上特殊字符(菜单项名称和热键之间必须要有空格)
- 单个字符使用:_g
- 几个特殊限定符:ctrl-%,alt-&,shift-#
- 其它按键:LEFT/RIGHT/UP/DOWN/F1/F2/.../HOME/END/PGUP/PGDN;
- 示例:%&a-Ctrl+Alt+A
三、MenuCommand
在第一节的第二个代码示例中,函数里使用了MenuCommand类,这个类是为菜单项来获取上下文。
MenuCommand类有一个重要的属性context,可以用于获取当前菜单项的上下文,在上文代码中的最后一行debug中,我们打印了context,现在先看一下结果,
我在主相机上挂了刚体组件,然后这里的打印结果就是主相机的刚体组件,也正好验证了我们代码的第一行获取刚体组件是正确的。