菜單 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]}.");
}
}