MenuItem 属性用于向主菜单和检视面板上下文菜单添加菜单项。
该 MenuItem 属性能够将任何静态函数转变为菜单命令,仅静态函数可使用 MenuItem 属性。
1、要创建热键
您可以使用以下特殊字符:%(在 Windows 上为 ctrl,在 macOS 上为 cmd)、# (shift)、& (alt)。如果不需要特殊的修改键组合,该键可以在下划线后给出。例如,要创建一个带有热键 shift-alt-g 的菜单,可以使用“MyMenu/Do Something #&g”。要创建带有热键 g 而不按下修改键的菜单,则使用“MyMenu/Do Something _g”。
2、一些特殊的键盘键可支持作为热键
例如,“#LEFT”可映射到 shift-left。支持这一功能的键为:LEFT、RIGHT、UP、DOWN、F1 .. F12、HOME、END、PGUP 和 PGDN。
热键文本前必须有一个空格字符(“MyMenu/Do_g”不能被解释为热键,而“MyMenu/Do _g”则可以被解释为热键)。
3、子菜单结构
将菜单项添加到“GameObject/”菜单,以在创建自定义游戏对象时,确保调用 GameObjectUtility.SetParentAndAlign,从而确保在发生上下文单击事件时, 对新的游戏对象进行正确地重定父级(请参阅以下示例)。您的函数也应该调用 Undo.RegisterCreatedObjectUndo,以使创建操作可撤销并将 Selection.activeObject 设置到新创建的对象上。另请注意,为了将“GameObject/”中的菜单项 传播到层级视图 Create 下拉菜单和层级视图上下文菜单,它必须与 其他游戏对象创建菜单项归为一组。
4、菜单优先级
这可以通过将其优先级 设为 10 来实现(请参阅以下示例)。请注意,对于“GameObject/Create Other” 中没有明确优先级设置且支持旧版项目的 MenuItem 来说,接收到的优先级为 10 而非默认的 1000, 我们建议使用比“Create Other”更具描述性的类别名称,并将优先级 显式设置为 10。
一、MenuItem 属性
1、itemName:菜单名称路径
特殊路径:
CONTEXT: 为组件添加菜单项
Assets: 对应顶部菜单 Assets,并添加 Project 面板右键菜单
GameObject: 对应顶部菜单 GameObject,priority 值在 149 时,添加 Hierarchy 面板右键菜单
Component: 对应顶部菜单 Component,对应 Inspector 面板的 Add Component 窗口。但是不知道怎么用,用 AddComponentMenu吧。
2、isValidateFunction:不写为 false,true 则点击菜单前就会调用
3、priority:菜单项显示排序 默认 1000
二、创建多级菜单
[MenuItem("一级菜单/二级菜单上/三级菜单")]
static void MenuOne()
{
//功能
}
[MenuItem("一级菜单/二级菜单下")]
static void MenuTwo()
{
//功能
}
三、创建带快捷键的菜单
在 MenuItem 的双引号菜单路径最后 + 空格 + 快捷键字符
快捷键可任意组合使用
英文字母 :_字母 (不区分大小写)
常用快捷键:
符号 | 字符 |
---|
% | Ctr/Command |
# | Shift |
& | Alt |
LEFT/Right/UP/DOWN | 方向键 |
F1-F2 | F 功能键 |
_g | 字母 g |
四、创建可被勾选的菜单
//设置勾选状态
//Menu.SetChecked(string menuPath, bool isChecked)
//获取勾选状态
//Menu.GetChecked(string menuPath)
[MenuItem("一级菜单/二级菜单上 #_A")]
static void MenuA()
{
string menuPath = "一级菜单/二级菜单上 #_A";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
[MenuItem("一级菜单/二级菜单中 %#_B")]
static void MenuB()
{
string menuPath = "一级菜单/二级菜单中 %#_B";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
[MenuItem("一级菜单/二级菜单下 %&_C")]
static void MenuC()
{
string menuPath = "一级菜单/二级菜单下 %&_C";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
五、检查菜单是否使用
通过函数判断菜单是否可使用,操作如下所示:
[MenuItem("菜单路径名")]
static void 方法() { }
[MenuItem("菜单路径名"),true]
static void 验证方法()
{
return bool值; //返回true 改菜单启用
}
具体实现操作用例:
[MenuItem("一级菜单/二级菜单上")]
static void MenuA()
{
string menuPath = "一级菜单/二级菜单上";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
[MenuItem("一级菜单/二级菜单中")]
static void MenuB()
{
string menuPath = "一级菜单/二级菜单中";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
EditorPrefs.SetBool("MenuCValidate", isChecked);
}
[MenuItem("一级菜单/二级菜单下")]
static void MenuC()
{
string menuPath = "一级菜单/二级菜单下";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
[MenuItem("一级菜单/二级菜单下", true)]
static bool MenuCValidate()
{
bool flag = EditorPrefs.GetBool("MenuCValidate");
Menu.SetChecked("一级菜单/二级菜单中", flag);
return flag;
}
六、菜单排序
在 priority 小的位置在上方 不配置默认为 1000
当相邻两个菜单的 priority 值差距超过 10 时 就会分组 中间出现一条横线
多级菜单的 priority 按照子级里面最小的 priority 算
[MenuItem("一级菜单/二级菜单上", false, 3)]
static void MenuA()
{
string menuPath = "一级菜单/二级菜单上";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
[MenuItem("一级菜单/二级菜单中", false, 2)]
static void MenuB()
{
string menuPath = "一级菜单/二级菜单中";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
[MenuItem("一级菜单/二级菜单下", false, 1)]
static void MenuC()
{
string menuPath = "一级菜单/二级菜单下";
bool isChecked = !Menu.GetChecked(menuPath);
Menu.SetChecked(menuPath, isChecked);
}
七、Hierarchy 右键菜单
Hierarchy 右键菜单是菜单栏的 GameObject 菜单栏下的菜单,并且 priority 在 149 范围内
[MenuItem("GameObject/二级菜单", false, 1)]
static void MenuA()
{
}
八、Project 右键菜单
Project 右键菜单是菜单栏的 Assets 菜单栏下的菜单
[MenuItem("Assets/二级菜单", false, 1)]
static void MenuA()
{
}
九、Inspector 组件右键菜单
组件右键菜单是使用特殊路径 CONTEXT 创建的
MenuCommand 可以获取到该组件
[MenuItem("CONTEXT/组件名/菜单名")]
static void 方法名(MenuCommand cmd)
{
//组件名 t = cmd.context as 组件名;
//对该组件进行操作
}
[MenuItem("CONTEXT/Transform/Reset功能")]
static void ClearTransformMenu(MenuCommand cmd)
{
Transform t = cmd.context as Transform;
t.position = Vector3.zero;
t.rotation = Quaternion.identity;
t.localScale = Vector3.zero;
GameObject obj = new GameObject();
obj.transform.parent = t.gameObject.transform;
}
十、AddComponentMenu 特性
AddComponentMenu 直接加载类上,会自动将菜单加到 Component 下,并加在 Inspector 面板的 AddComponentMenu 里。
AddComponentMenu(string menuName, int order)
menuName:菜单名路径
order:菜单项排序
使用用例:
[AddComponentMenu("自定义/Test", 1)]
public class Test : MonoBehaviour
{
}
十一、ContextMenu特性添加组件右键菜单
ContextMenu(string itemName, bool isValidateFunction, int priority)
itemName:菜单名称
isValidateFunction:不写为false,true则点击菜单前就会调用
priority:菜单项显示排序 默认 1000000
使用用例:
[AddComponentMenu("自定义/Test", 1)]
public class Test : MonoBehaviour
{
[ContextMenu("添加空物体")]
public void AddGameObject()
{
transform.position = Vector3.zero;
transform.rotation = Quaternion.identity;
transform.localScale = Vector3.zero;
GameObject obj = new GameObject();
obj.transform.parent = transform;
}
}