移动/游戏
维护已有 Unity IMGUI 编辑器代码时,按…
适用于维护或修改已有 Unity 传统 IMGUI 编辑器工具,且用户明确要求 IMGUI/OnGUI,或项目仅使用 IMGUI。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
维护已有 Unity IMGUI 编辑器特定
解决思路
- 激活后先读取 references/templates.md(EditorWindow、Inspector、PropertyDrawer 模板)和 references/gui-elements.md(GUI 元素、布局组、样式)。
- 先判断需要的脚本类型:EditorWindow、Editor、PropertyDrawer 或 MonoBehaviour 调试覆盖层。
- 在项目中搜索已有 Editor 脚本,优先匹配现有模式,再套用默认约定。
- 只生成请求对应的输出:IMGUI/OnGUI 的 EditorWindow 用 OnGUI();IMGUI 自定义 Inspector 用 Editor + OnInspectorGUI();IMGUI PropertyDrawer 用 PropertyDrawer + OnGUI();调试覆盖层用 MonoBehaviour + OnGUI();更新已有 IMGUI 脚本则修改现有 OnGUI 代码。
- 请求歧义时先澄清:inspector 是 Custom Editor 还是 PropertyDrawer,并用 UI Toolkit 还是 IMGUI;editor window 用 UI Toolkit/CreateGUI 还是 IMGUI/OnGUI;tool window 的具体功能和 UI 系统。
- 遵循项目命名约定:脚本名用 PascalCase,例如 MyToolWindow.cs;EditorWindow 用 [Name]Window.cs,例如 LevelEditorWindow.cs;Custom Editor 用 [Type]Editor.cs,例如 EnemyEditor.cs;PropertyDrawer 用 [Type]Drawer.cs,例如 RangeDrawer.cs。
- 将使用 UnityEditor 命名空间的脚本放到 Editor 文件夹,例如 Assets/Editor/,否则构建失败。
- 创建脚本时使用合适基类和 attribute:EditorWindow、Editor、PropertyDrawer 等。
- 实现 OnGUI:用布局组构建界面。
- EditorWindow 结构:用 [MenuItem attribute] 添加到菜单;提供 ShowWindow() 静态方法打开窗口;用 OnGUI() 绘制界面;用 OnEnable/OnDisable 做初始化和清理。
- Custom Editor 结构:用 [CustomEditor attribute] 指定目标组件类型;用 OnInspectorGUI() 绘制 Inspector;在 OnEnable() 缓存 SerializedProperties;用 serializedObject.Update/ApplyModifiedProperties 支持撤销。
- PropertyDrawer 结构:用 [CustomPropertyDrawer attribute] 指定类型或 attribute;实现 OnGUI(Rect, SerializedProperty, GUIContent) 绘制属性;需要时实现 GetPropertyHeight() 自定义高度。
- 缓存 GUIStyle 对象,不要在 OnGUI 中新建 GUIStyle,否则每帧产生内存分配。
- 在 Inspector 中使用 SerializedProperty,以获得正确的撤销/重做支持。
- 序列化对象变更后调用 ApplyModifiedProperties()。
- 编辑器脚本使用 EditorGUILayout(自动布局)。
- 运行时 OnGUI 使用 GUILayout。
- 所有 Begin/End 成对出现,例如 BeginHorizontal 与 EndHorizontal 配对。
- 水平分组:用 EditorGUILayout.BeginHorizontal() 和 EditorGUILayout.EndHorizontal() 让元素并排。
- 垂直分组:用 EditorGUILayout.BeginVertical('box') 和 EditorGUILayout.EndVertical() 让元素堆叠,并可套用 box 样式。
- 滚动视图:用 scrollPos = EditorGUILayout.BeginScrollView(scrollPos); ... EditorGUILayout.EndScrollView()。
- Foldout 区块:用 showSection = EditorGUILayout.Foldout(showSection, 'Section Name'); if (showSection) 内用 EditorGUI.indentLevel++ 和 EditorGUI.indentLevel-- 缩进内容。
- 按钮动作:用 if (GUILayout.Button('Do Something')) { ... }。
- 带标签属性字段:用 EditorGUILayout.PropertyField(myProperty, new GUIContent('Label'))。
- 对象引用字段:用 myObject = (MyType)EditorGUILayout.ObjectField('Label', myObject, typeof(MyType), true)。
- 禁用组:用 EditorGUI.BeginDisabledGroup(condition) 和 EditorGUI.EndDisabledGroup()。
- 使用 SerializedObject 和 SerializedProperty 支持撤销。
- 在 OnEnable() 缓存属性引用。
- 只有非序列化变更才使用 EditorUtility.SetDirty()。
- 直接修改对象前使用 Undo.RecordObject()。
- 使用 EditorStyles 保持外观一致。
- 使用 GUILayout.FlexibleSpace() 推开元素。
- 参考 references/templates.md 获取完整脚本模板;参考 references/gui-elements.md 获取完整元素参考。
适用边界 · 注意事项
- 不适用于新建编辑器窗口、新建自定义 Inspector 或新建 PropertyDrawer 的请求;这些应推荐使用 UI Toolkit(CreateGUI)而不是 IMGUI。
- 不适用于用户没有明确提到 IMGUI 或 OnGUI 的请求。
- 不适用于运行时游戏 UI;应使用 UI Toolkit 或 uGUI,而不是 IMGUI。