Unity3D 引擎的編輯器擁有很強的擴展性,用的好可以幫我們省很多事情。在這里記錄下如何去擴展 Unity3D 的編輯器,定制屬於我們自己的開發環境。
本篇主要講解在 Unity3D 引擎的各個窗口添加我們自己的菜單按鈕。
添加菜單按鈕我們需要用到 MenuItem 特性:
MenuItem 的三個重載:
MenuItem(string itemName);
MenuItem(string itemName, bool isValidateFunction);
MenuItem(string itemName, bool isValidateFunction, int priority);
參數詳解:
string itemName:菜單路徑以及名稱,可以設置多級菜單
bool isValidateFunction:控制菜單是否被激活。
通常都是通過兩個函數來完成的:
1、菜單的名稱必須完全一致;
2、第1個函數的第2個參數必須是 false 或不寫,因為默認值就是 false,第2個函數的第2個參數必須是 true;
3、第2個函數的返回值必須是 bool 類型:如果函數的返回值如果返回 true,則本菜單被高亮激活,並執行第一個函數;如果返回值為 false,本菜單就為灰色,不可以被點擊;
int priority:控制菜單的顯示上下的順序。值越小越在上面顯示,默認的優先級為1000;如果想要系統添加下划線,相鄰的2個菜單的優先級的大小要超過 >= 11。
添加我們自己的菜單有兩點需要注意:
1、MenuItem 的函數必須是靜態(static)函數。
2、腳本必須放在 Editor 文件夾下。
在菜單欄添加菜單:
代碼:
[MenuItem("MyMenuItem/Item1")] private static void Item1Do1() { Debug.Log("MyMenuItem Item1"); }
效果圖:
代碼:
[MenuItem("GameObject/Item1")] private static void Item1Do2() { Debug.Log("GameObject Item1"); }
效果圖:
第二個參數 bool isValidateFunction 的用法:
代碼:
[MenuItem("MyMenuItem/Item2")] private static void Item2Do1() { Debug.Log(Selection.activeTransform.gameObject.name); } [MenuItem("MyMenuItem/Item2", true)] private static bool Item2Do2() { return Selection.activeTransform != null; }
效果圖:
第三個參數 int priority 的用法:
代碼:
[MenuItem("MyMenuItem/Item3", false, 1)] private static void Item3Do() { Debug.Log("Item3"); } [MenuItem("MyMenuItem/Item4", false, 12)] private static void Item4Do() { Debug.Log("Item4"); }
效果圖:
Project 視圖右鍵添加菜單:
代碼:
[MenuItem("Assets/AssetsItem")] private static void AssetsItemDo() { Debug.Log("AssetsItem"); }
效果圖:
Hierachry層級視圖添加右鍵菜單:核心是參數第三個參數 int priority,設置為10,添加到同一組內
代碼:
[MenuItem("GameObject/Custom Game Object", false, 10)] private static void CreateCustomGameObject(MenuCommand menuCommand) { //創建一個新的游戲物體 GameObject go = new GameObject("Custom Game Object"); //menuCommand.context是當前鼠標左鍵選中的GameObjet游戲物體,通過GameObjectUtility.SetParentAndAlign函數設置為新創建的go物體的父節點 GameObjectUtility.SetParentAndAlign(go, menuCommand.context as GameObject); //注冊到U3D的Undo系統中。就是指我們可以使用Ctrl+Z組合鍵對這個物體進行撤銷操作。 Undo.RegisterCreatedObjectUndo(go, "Create " + go.name); //將鼠標的選中物體自動的移動到剛剛創建的go物體上 Selection.activeObject = go; }
效果圖:
Inspector 屬性面板中添加一個右鍵菜單,功能可以通過MenuItem("COMTEXT/組件名稱/右鍵菜單名稱")完成
代碼:
//MenuCommand 表示當前正在操作的組件 //通過context 屬性獲取到 對應的腳本對象或游戲物體GameObject [MenuItem("CONTEXT/Rigidbody/SetMass=5")] private static void DoSomething(MenuCommand command) { Rigidbody body = (Rigidbody)command.context as Rigidbody; body.mass = 5; Debug.Log("Changed Rigidbody's Mass to " + body.mass + " from Context Menu..."); }
效果圖:
我們還有另外一種方法,就是通過 ContextMenu 特性來完成,效果是一樣的。並且 ContextMenu 的函數重載和參數與 MenuItem 是一樣的,前面已經寫過了,這里就不贅述了。與 ContextMenu 不同的是,它是寫在組件函數里面,且不用並不能放在 Editor 文件夾下。
代碼:
public class ContextMenuTest : MonoBehaviour { [ContextMenu ("Do Something")] void DoSomething () { Debug.Log ("Perform operation"); } }
效果圖:
接下來介紹另外兩個屬性:
ContextMenuItem 為菜單綁定一個方法。
代碼:使 Reset 擁有了重置 playerBiography 值的功能。
[ContextMenuItem("Reset", "ResetBiography")] public string playerBiography = ""; void ResetBiography() { playerBiography = ""; }
AddComponentMenu:允許將我們的腳本添加到Component菜單的指定位置,而不是"Component->Scripts-->xxxx"。特例: menuName為空,則菜單中將隱藏此腳本的顯示
代碼:
[AddComponentMenu("MyCompenent/ContextMenuTest",200)] public class ContextMenuTest : MonoBehaviour { }
效果圖:
前面說了一大堆如何擴展自己的菜單,接下來我們說如何添加快捷鍵,畢竟使用快捷鍵比鼠標點爽多了有沒有,而且顯得很牛有沒有。
代碼:
[MenuItem("MyMenuItem/Item5 %G")] private static void Item5Do() { Debug.Log("Item5"); }
效果圖:這樣我們就給這個菜單按鈕設置了快捷鍵:Ctrl+G
設置快捷鍵的規則大致如下:
% (ctrl on Windows, cmd on macOS), # (shift), & (alt).
"MyMenu/Do Something _g" 快捷鍵g,字母簽名添加下划線
"#LEFT" :shift+ left. 其他的一個鍵的支持情況: LEFT, RIGHT, UP, DOWN, F1 .. F12, HOME, END, PGUP, PGDN.
快捷鍵和前面的菜單名稱中間必須加入空格,否則無效
_w 單一的快捷鍵 W
#w shift+w
%w ctrl+w
&w Alt+w