拓展编辑器 1 - 菜单 MenuItem

菜单 MenuItem

官方文档连接

MenuItem修饰可以让我们对菜单进行扩展,同时,该修饰多数用在静态方法上,CONTEXT除外。

格式:

public MenuItem(string itemName, bool isValidateFunction, int priority)

参数含义:

  • itemName:菜单路径,以 “/” 分隔。如"Window/MyFunc",表示将菜单添加到 Window 下的 MyFunc。
    • 可以为其添加快捷键:%(ctrl), #(shift), &(alt),例如Ctrl+D:“Window/MyFunc %d”。特殊键位为:LEFT, RIGHT, UP, DOWN, F1 … F12, HOME, END, PGUP, PGDN,可以参考unity api 文档
    • GameObject 对应 Hierarchy 窗口右键菜单
    • Asset/Create 对应 Project 窗口右键菜单
    • CONTEXT/ComponentName/XXX,为选中的Object的Inspector窗口上的ComponentName(可以是系统的如Transform,也可以是我们派生的MonoBehaviour)添加齿轮菜单项。该菜单项需要MenuCommand参数
  • isValidateFunction:为true表示该方法是对菜单是否可用的定义。意味着菜单定义由2个方法构成,一个定义逻辑,一个定义是否可用。
  • priority:菜单显示优先级,定义在菜单中显示的位置。

其它相关:

  • 如果菜单路径与现有一样,则覆盖。
  • MenuCommand: 根据需要,可能要用到该参数
  • Selection.activeObject: 选中的Object对象,可以是GameObject,也可以是Project中的资源
  • Selection.activeGameObject: 选中的GameObject对象
  • Selection.activeTransform: 选中的Transform
  • Undo.RegisterCreateObjectUndo: 如果创建了对象,注册撤销,以响应界面的撤销操作
  • GameObjectUtility.SetParentAndAlign: 创建GameObject时,调用该接口以保证新的GameObject的正确的父子关系。
  • EditorUtility.DisplayCustomMenu : 显示自定义菜单

例子:

public class MenuExtend
{
    /// <summary>
    /// % Ctrl # Shift & Alt
    /// </summary>
    [MenuItem("My/Test1 %#&a", false, 1)]
    static void Test1()
    {
        Debug.Log("select menu test1.");
    }

    /// <summary>
    /// 在Test1前显示
    /// </summary>
    [MenuItem("My/Test0", false, 0)]
    static void Test0() { }

    /// <summary>
    /// 该菜单项由下面的函数定义是否可用
    /// </summary>
    [MenuItem("My/Test/A")]
    static void TestA() { }

    /// <summary>
    /// 选择了一个 GameObject 才可用
    /// </summary>
    /// <returns></returns>
    [MenuItem("My/Test/A", true, 20)]
    static bool AValidation()
    {
        return Selection.activeGameObject != null;
    }

    /// <summary>
    /// 可选中选中菜单
    /// </summary>
    [MenuItem("My/Test2", false, 3)]
    static void Test3()
    {
        bool chk = Menu.GetChecked("My/Test2");
        Menu.SetChecked("My/Test2", !chk);
    }
    
    /// <summary>
    /// 为 Rigigbody 添加 "Double Mass" 菜单功能
    /// </summary>
    /// <param name="command"></param>
    [MenuItem("CONTEXT/Rigidbody/Double Mass")]
    static void DoubleMass(MenuCommand command)
    {
        Rigidbody body = (Rigidbody)command.context;
        body.mass = body.mass * 2;
        Debug.Log("Doubled Rigidbody's Mass to " + body.mass + " from Context Menu.");
    }
    
    // Add a menu item to create custom GameObjects.
    // Priority 1 ensures it is grouped with the other menu items of the same kind
    // and propagated to the hierarchy dropdown and hierarchy context menus.
    [MenuItem("GameObject/MyCategory/Custom Game Object", false, 10)]
    static void CreateCustomGameObject(MenuCommand menuCommand)
    {
        // Create a custom game object
        GameObject go = new GameObject("Custom Game Object");
        // Ensure it gets reparented if this was a context click (otherwise does nothing)
        GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject);
        // Register the creation in the undo system
        Undo.RegisterCreatedObjectUndo(go, "Create " + go.name);
        Selection.activeObject = go;
    }
}

可以在我们想要的地方显示自定义菜单。比如在 SceneView 中,右键显示我们的菜单:

public class ShowMenuInScene
{
    [InitializeOnLoadMethod]
    static void Initialize()
    {
        SceneView.duringSceneGui += OnSceneGUI;
    }

    static void OnSceneGUI(SceneView sv)
    {
        if(Event.current != null && Event.current.button == 1 && Event.current.type == EventType.MouseUp)
        {
            Vector2 pos = Event.current.mousePosition;

            GUIContent[] menu = new GUIContent[]
            {
                new GUIContent("Test0"),
                new GUIContent("Test1"),
                new GUIContent("Test2"),
                new GUIContent(""),
                new GUIContent("Test/2")
            };

            int selected = -1;
            object userData = Selection.activeGameObject;
            int width = 100;
            int height = 100;
            Rect rect = new Rect(pos.x, pos.y - height, width, height);
            EditorUtility.DisplayCustomMenu(rect, menu, selected, SelectMyMenu, userData);
            Event.current.Use();
        }
    }

    static void SelectMyMenu(object data, string[] opt, int select)
    {
        Debug.Log($"Select my menu:{opt[select]}.");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值