拓展編輯器 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]}.");
    }
}
發佈了49 篇原創文章 · 獲贊 2 · 訪問量 2614
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章