一、基本功能介绍

MenuItem是UnityEditor下的属性,它是对编辑器的扩展,主要有两大作用:

第一,在主菜单中添加菜单项,也就是在以下编辑器部分添加,这是一个很重要的用途,在开发插件的时候经常用到。

unity模型属性 unity属性栏_菜单项

示例代码如下: 

[MenuItem("MyMenu/LookCamera")]
    static void LookCamera()
    {
        //
    }

注意:函数一般都是私有的,而且必须是静态函数才能使用MenuItem属性。为什么必须是static函数呢,因为该类可以不用实例化,不用继承自MonoBehavior,比如给刚体添加一个重置属性功能,就不需要添加脚本组件,因此,我们就可以在一个扩展脚本中集中很多类似的菜单项。

可以在第一个字符串参数中添加快捷键,具体参考官方文档:MenuItem-Reference

第二,在属性面板的组件的上下文中添加菜单项,针对编辑器中已有组件的扩展,如下图,这是为刚体组件添加的右键上下文的菜单项,可用于调试等。

unity模型属性 unity属性栏_unity模型属性_02

示例代码如下:

[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编辑器的顺序来定,也就是菜单的位置不可由开发者定义,我们也不需要关心)

unity模型属性 unity属性栏_菜单项_03

  • 快捷键使用:在命名之后加上特殊字符(菜单项名称和热键之间必须要有空格)
  • 单个字符使用:_g
  • 几个特殊限定符:ctrl-%,alt-&,shift-#
  • 其它按键:LEFT/RIGHT/UP/DOWN/F1/F2/.../HOME/END/PGUP/PGDN;
  • 示例:%&a-Ctrl+Alt+A

三、MenuCommand

在第一节的第二个代码示例中,函数里使用了MenuCommand类,这个类是为菜单项来获取上下文。

MenuCommand类有一个重要的属性context,可以用于获取当前菜单项的上下文,在上文代码中的最后一行debug中,我们打印了context,现在先看一下结果,

unity模型属性 unity属性栏_示例代码_04

我在主相机上挂了刚体组件,然后这里的打印结果就是主相机的刚体组件,也正好验证了我们代码的第一行获取刚体组件是正确的。