mcpField
U
ui-imgui

ui-imgui

github.com/unity-technologies开发57741 次安装5 天前更新
代码仓库

关于 ui-imgui

ui-imgui 是用于维护现有 Unity IMGUI 编辑器代码或处理明确要求使用 IMGUI 的任务的技能。它面向旧式编辑器工作流,并建议新建编辑器界面时改用 UI Toolkit。

主要功能

  1. 01旧版 IMGUI 代码指引
  2. 02EditorWindow、检查器和抽屉模式
  3. 03OnGUI 布局与元素规范
  4. 04SerializedProperty 与撤销指引
  5. 05项目模式和文件夹检查

适用场景

  1. 01更新现有 OnGUI 编辑器窗口
  2. 02维护自定义检查器或 PropertyDrawer
  3. 03添加 IMGUI 调试覆盖层
  4. 04判断需求应使用 UI Toolkit 还是 IMGUI

安装

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

$npx skills add https://github.com/unity-technologies/unity-agent-plugin --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