Unity GenericMenu 类详解
Unity GenericMenu 类方法详解表
方法签名 | 作用描述 | 参数说明 | 使用示例 |
---|---|---|---|
AddItem(GUIContent content, bool on, GenericMenu.MenuFunction func) | 添加可点击菜单项 | content : 菜单项显示内容on : 是否显示选中标记func : 点击回调方法 | menu.AddItem(new GUIContent("保存"), false, Save) |
AddItem(GUIContent content, bool on, GenericMenu.MenuFunction2 func, object userData) | 添加带参数的菜单项 | userData : 传递给回调的自定义数据 | menu.AddItem(new GUIContent("删除"), false, (data) => Delete(data), obj) |
AddDisabledItem(GUIContent content, bool on) | 添加禁用菜单项 | content : 菜单项显示内容on : 是否显示选中标记 | menu.AddDisabledItem(new GUIContent("需要专业版")) |
AddSeparator(string path) | 添加菜单分隔符 | path : 分隔符位置路径 | menu.AddSeparator("编辑/") |
ShowAsContext() | 在鼠标位置显示菜单 | 无参数 | menu.ShowAsContext() |
DropDown(Rect rect) | 在指定位置显示菜单 | rect : 显示位置的矩形区域 | menu.DropDown(buttonRect) |
allowDuplicateNames | 允许重复菜单项名 | 布尔值属性 | menu.allowDuplicateNames = true |
方法详解与使用场景
1. AddItem - 基础菜单项
menu.AddItem(new GUIContent("新建场景"), false, () => EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects)
);
- 适用场景:创建基本功能菜单项
- 参数说明:
content
:可包含文本和图标on
:控制左侧勾选状态func
:无参数回调方法
2. AddItem - 带参数菜单项
menu.AddItem(new GUIContent($"删除/{obj.name}"), false, (target) => DestroyImmediate(target as GameObject), obj
);
- 适用场景:动态生成的菜单项
- 优势:可传递上下文数据
- 典型用途:对象列表操作
3. AddDisabledItem - 禁用菜单项
bool hasSelection = Selection.activeObject != null;if (!hasSelection)
{menu.AddDisabledItem(new GUIContent("复制属性"));
}
- 适用场景:条件未满足的功能项
- 视觉提示:灰色显示,不可交互
- 最佳实践:配合条件判断使用
4. AddSeparator - 菜单分隔符
menu.AddItem("文件/新建", false, NewFile);
menu.AddSeparator("文件/"); // 在"文件"菜单下添加分隔符
menu.AddItem("文件/打开", false, OpenFile);
- 路径规则:
""
:根菜单分隔符"分类/"
:指定子菜单分隔符
- 作用:视觉分组,提高可读性
5. ShowAsContext - 上下文菜单
// 在Inspector中添加
public override void OnInspectorGUI()
{if (Event.current.type == EventType.ContextClick){GenericMenu menu = new GenericMenu();menu.AddItem("重置", false, ResetValues);menu.ShowAsContext();Event.current.Use();}
}
- 典型场景:组件右键菜单
- 特点:自动定位到鼠标位置
6. DropDown - 指定位置菜单
void OnGUI()
{if (GUILayout.Button("选项")){Rect btnRect = GUILayoutUtility.GetLastRect();GenericMenu menu = new GenericMenu();menu.AddItem("高", false, SetQualityHigh);menu.AddItem("中", false, SetQualityMedium);menu.AddItem("低", false, SetQualityLow);menu.DropDown(btnRect);}
}
- 适用场景:工具栏下拉菜单
- 位置控制:精确显示在触发控件下方
7. allowDuplicateNames - 重复项控制
GenericMenu menu = new GenericMenu();
menu.allowDuplicateNames = true;// 允许添加同名但功能不同的菜单项
menu.AddItem("工具/优化", false, OptimizeA);
menu.AddItem("工具/优化", false, OptimizeB);
- 默认值:
false
(禁止重名) - 特殊场景:需要同名不同功能的菜单项
- 风险:可能导致用户混淆
完整工作流示例
[MenuItem("Tools/场景工具")]
static void ShowWindow()
{var window = GetWindow<SceneToolsWindow>();window.titleContent = new GUIContent("场景工具");
}void OnGUI()
{if (GUILayout.Button("对象操作")){GenericMenu menu = new GenericMenu();// 添加创建子菜单menu.AddItem("创建/立方体", false, CreateCube);menu.AddItem("创建/球体", false, CreateSphere);menu.AddSeparator("创建/");menu.AddItem("创建/灯光", false, CreateLight);// 添加选择相关操作bool hasSelection = Selection.activeGameObject != null;if (hasSelection){menu.AddItem("选择操作/删除", false, DeleteSelected);menu.AddItem("选择操作/复制", false, DuplicateSelected);}else{menu.AddDisabledItem(new GUIContent("选择操作/删除"));menu.AddDisabledItem(new GUIContent("选择操作/复制"));}// 添加设置项menu.AddSeparator("");menu.AddItem("设置/高品质", QualitySettings.level == 0, SetHighQuality);menu.AddItem("设置/中品质", QualitySettings.level == 1, SetMediumQuality);menu.AddItem("设置/低品质", QualitySettings.level == 2, SetLowQuality);// 显示菜单Rect btnRect = GUILayoutUtility.GetLastRect();menu.DropDown(new Rect(btnRect.x, btnRect.yMax, 0, 0));}
}
效果
方法对比指南
特性 | AddItem | AddDisabledItem | AddSeparator |
---|---|---|---|
交互性 | 可点击 | 不可交互 | 无交互 |
视觉状态 | 正常/选中 | 灰色 | 分隔线 |
回调支持 | ✔️ | ❌ | ❌ |
参数传递 | ✔️ | ❌ | ❌ |
使用频率 | 高 | 中 | 高 |
最佳实践建议
-
菜单组织原则:
// 按功能分组 menu.AddItem("编辑/复制", false, Copy); menu.AddItem("编辑/粘贴", false, Paste); menu.AddSeparator("编辑/"); // 组内分隔 menu.AddItem("编辑/撤销", false, Undo);
-
动态菜单生成:
// 根据场景对象动态生成 foreach (var obj in FindObjectsOfType<Light>()) {menu.AddItem($"灯光/{obj.name}", false, () => SelectLight(obj)); }
-
菜单项状态反馈:
// 使用选中标记表示状态 menu.AddItem("视图/显示网格", showGrid, ToggleGrid);
-
性能优化:
// 避免在循环中重复创建菜单 GenericMenu menu = new GenericMenu(); for (int i = 0; i < 1000; i++) {menu.AddItem($"选项/{i}", false, () => SelectOption(i)); }