mcpField
U
ui-imgui

ui-imgui

github.com/unity-technologies开发1.2k4.7k 次安装1 天前更新
代码仓库

关于 ui-imgui

面向 Unity 旧版 IMGUI 代码的维护与创建技能,涵盖编辑器窗口、自定义检查器、属性绘制器和运行时调试叠层。强调遵循项目规范、使用序列化属性,并为新的编辑器 UI 考虑 UI Toolkit。

主要功能

  1. 01旧版 IMGUI 代码指引
  2. 02编辑器窗口与检查器模式
  3. 03属性绘制器和调试叠层支持
  4. 04布局与 GUI 元素说明
  5. 05序列化属性及撤销实践

适用场景

  1. 01更新现有 OnGUI 编辑器工具
  2. 02按明确需求构建 IMGUI 检查器
  3. 03添加运行时调试叠层
  4. 04维护旧版 PropertyDrawer

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/unity-technologies/skills --skill ui-imgui

安装后在 Claude Code 中输入/ui-imgui确认已加载。

附带文件references/gui-elements.mdreferences/templates.md

详细介绍

开始之前: 如果用户询问要创建一个新的编辑器窗口、自定义检查器或 PropertyDrawer,但未明确提及 IMGUI/OnGUI,请建议改用 UI Toolkit(CreateGUI),因为这是更现代的做法。仅在以下情况下使用 IMGUI:

  • 用户正在修改现有 IMGUI 代码
  • 用户明确要求使用 IMGUI/即时模式
  • 项目中的编辑器工具全部采用 IMGUI

激活后,请阅读参考文件:

何时使用此技能

重要: 此技能仅适用于旧版 IMGUI 代码。在以下情况下使用此技能:

  • 用户正在维护或更新现有 IMGUI 编辑器代码(包含 OnGUI()、OnInspectorGUI() 的文件)
  • 用户明确要求使用 IMGUI/即时模式 GUI
  • 项目中的所有编辑器工具都只使用 IMGUI

不要在以下情况下使用此技能:

  • 新建编辑器窗口(改用 UI Toolkit 和 CreateGUI())
  • 新建自定义检查器(改用 UI Toolkit)
  • 用户未明确提及 IMGUI 或 OnGUI 的请求

旧版 IMGUI 用于:

  • 编辑器窗口 — 包含 OnGUI() 的 EditorWindow 类
  • 自定义检查器 — 包含 OnInspectorGUI() 的 Editor、PropertyDrawer 类
  • 调试叠加层 — MonoBehaviour 中的 OnGUI()(运行时)

IMGUI 不适用于运行时游戏 UI——请改用 UI Toolkit 或 uGUI。

范围

仅生成用户所要求的内容(适用于旧版 IMGUI 代码):

请求输出说明
编辑器窗口(IMGUI/OnGUI)带有 OnGUI() 的 EditorWindow仅限明确要求使用 IMGUI 的情况
自定义检查器(IMGUI)带有 OnInspectorGUI() 的 Editor仅限明确要求使用 IMGUI 的情况
PropertyDrawer(IMGUI)带有 OnGUI() 的 PropertyDrawer仅限明确要求使用 IMGUI 的情况
调试叠加层带有 OnGUI() 的 MonoBehaviour运行时调试
更新现有 IMGUI 脚本修改现有 OnGUI 代码始终适用

如果存在歧义,请先确认:

  • “inspector” → 针对特定类型的 Custom Editor,还是 PropertyDrawer?**还要询问:**应使用 UI Toolkit(现代)还是 IMGUI(旧版)?
  • “editor window” → **首先询问:**应使用 UI Toolkit(现代/CreateGUI)还是 IMGUI(旧版/OnGUI)?
  • “tool window” → 使用什么功能的 EditorWindow?采用哪种 UI 系统?

约定

优先遵循项目现有模式。 应用默认约定前,先搜索现有编辑器脚本。

类型约定正确示例错误示例
脚本名称PascalCaseMyToolWindow.csmy-tool-window.cs
EditorWindow[Name]Window.csLevelEditorWindow.csLevelEditor.cs
Custom Editor[Type]Editor.csEnemyEditor.csEnemyInspector.cs
PropertyDrawer[Type]Drawer.csRangeDrawer.csRangePropertyDrawer.cs
位置Editor 文件夹Assets/Editor/Assets/Scripts/

必须使用 Editor 文件夹——使用 UnityEditor 命名空间的脚本必须放在 Editor 文件夹中,否则将无法构建。

工作流

  1. 分析——确定所需的脚本类型(EditorWindow、Editor、PropertyDrawer 等)
  2. 搜索——查找现有编辑器脚本以匹配项目模式
  3. 遵循项目模式——匹配文件夹结构和命名方式
  4. 创建脚本——使用合适的基类和特性
  5. 实现 OnGUI——使用布局组构建界面

脚本结构

EditorWindow
[MenuItem attribute] → adds to menu
ShowWindow() static method → opens window
OnGUI() → draws interface
OnEnable/OnDisable → initialization/cleanup
Custom Editor
[CustomEditor attribute] → targets component type
OnInspectorGUI() → draws inspector
OnEnable() → cache SerializedProperties
serializedObject.Update/ApplyModifiedProperties → undo support
PropertyDrawer
[CustomPropertyDrawer attribute] → targets type or attribute
OnGUI(Rect, SerializedProperty, GUIContent) → draws property
GetPropertyHeight() → custom height if needed

关键规则

  • 缓存 GUIStyle 对象——切勿在 OnGUI 中创建新的 GUIStyle(每帧都会造成内存分配)
  • 使用 SerializedProperty——确保检查器支持正确的撤销/重做
  • 调用 ApplyModifiedProperties()——在任何序列化对象更改后调用
  • 使用 EditorGUILayout——用于编辑器脚本(自动布局)
  • 使用 GUILayout——用于运行时 OnGUI
  • 匹配 Begin/End 调用——始终确保 BeginHorizontal 与 EndHorizontal 等成对使用
  • 必须放在 Editor 文件夹中——否则脚本会导致构建失败

布局基础

水平分组:

EditorGUILayout.BeginHorizontal();
// elements appear side by side
EditorGUILayout.EndHorizontal();

垂直分组:

EditorGUILayout.BeginVertical("box");
// elements appear stacked, with box style
EditorGUILayout.EndVertical();

滚动视图:

scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
// scrollable content
EditorGUILayout.EndScrollView();

折叠区域:

showSection = EditorGUILayout.Foldout(showSection, "Section Name");
if (showSection)
{
    EditorGUI.indentLevel++;
    // section content
    EditorGUI.indentLevel--;
}

常见模式

带操作的按钮:

if (GUILayout.Button("Do Something"))
{
    // action here
}

带标签的属性字段:

EditorGUILayout.PropertyField(myProperty, new GUIContent("Label"));

对象引用字段:

myObject = (MyType)EditorGUILayout.ObjectField("Label", myObject, typeof(MyType), true);

禁用组:

EditorGUI.BeginDisabledGroup(condition);
// disabled elements
EditorGUI.EndDisabledGroup();

最佳实践

  • 使用 SerializedObject 和 SerializedProperty 支持撤销
  • 在 OnEnable() 中缓存属性引用
  • 仅对非序列化更改使用 EditorUtility.SetDirty()
  • 直接修改对象前,使用 Undo.RecordObject()
  • 使用 EditorStyles 保持外观一致
  • 使用 GUILayout.FlexibleSpace() 拉开元素间距

完整的脚本模板请参阅 references/templates.md。 完整的元素参考请参阅 references/gui-elements.md。

评论

支持 Markdown