SKILL.md
唯讀
名稱
ui-imgui
描述
Unity IMGUI(即時模式 GUI)專家,專精於使用 OnGUI/即時模式的舊版編輯器工具。可產生及修改 IMGUI EditorWindow、自訂 Inspector、PropertyDrawer,以及包含 IMGUI 程式碼(OnGUI、OnInspectorGUI)的腳本。在維護現有 IMGUI 編輯器程式碼,或使用者明確要求 IMGUI/OnGUI 時使用。
開始前注意: 如果使用者要求建立新的編輯器視窗、自訂 Inspector 或 PropertyDrawer,但沒有明確提到 IMGUI/OnGUI,請建議改用 UI Toolkit(CreateGUI),因為這是現代化的做法。只有在以下情況才使用 IMGUI:
- 使用者正在修改現有的 IMGUI 程式碼
- 使用者明確要求 IMGUI/即時模式
- 專案僅使用 IMGUI 作為編輯器工具
啟用時,請閱讀參考檔案:
- references/templates.md — EditorWindow、Inspector、PropertyDrawer 範本
- references/gui-elements.md — GUI 元素、版面配置群組、樣式
何時使用此技能
重要: 此技能僅適用於舊版 IMGUI 程式碼。請在以下情況使用:
- 使用者正在維護/更新現有的 IMGUI 編輯器程式碼(包含
OnGUI()、OnInspectorGUI()的檔案) - 使用者明確要求 IMGUI/即時模式 GUI
- 專案僅使用 IMGUI 作為所有編輯器工具
請勿將此技能用於:
- 新的編輯器視窗(請改用 UI Toolkit 的
CreateGUI()) - 新的自訂 Inspector(請改用 UI Toolkit)
- 未明確提及 IMGUI 或 OnGUI 的需求
舊版 IMGUI 用於:
- 編輯器視窗 — 包含
OnGUI()的EditorWindow類別 - 自訂 Inspector — 包含
OnInspectorGUI()的Editor、PropertyDrawer類別 - 除錯覆疊 — MonoBehaviour 中的
OnGUI()(執行時期)
IMGUI 不適用於執行時期的遊戲 UI — 請改用 UI Toolkit 或 uGUI。
範圍
僅產生使用者要求的內容(針對舊版 IMGUI 程式碼):
| 需求 | 輸出 | 備註 |
|---|---|---|
| 編輯器視窗(IMGUI/OnGUI) | 包含 OnGUI() 的 EditorWindow |
僅限明確要求 IMGUI 時 |
| 自訂 Inspector(IMGUI) | 包含 OnInspectorGUI() 的 Editor |
僅限明確要求 IMGUI 時 |
| PropertyDrawer(IMGUI) | 包含 OnGUI() 的 PropertyDrawer |
僅限明確要求 IMGUI 時 |
| 除錯覆疊 | 包含 OnGUI() 的 MonoBehaviour |
執行時期除錯 |
| 更新現有 IMGUI 腳本 | 修改現有的 OnGUI 程式碼 | 永遠適用 |
若需求不明確,請釐清:
- "inspector" → 是特定型別的自訂 Editor,還是 PropertyDrawer?同時詢問: 應該使用 UI Toolkit(現代)還是 IMGUI(舊版)?
- "editor window" → 先詢問: 應該使用 UI Toolkit(現代/CreateGUI)還是 IMGUI(舊版/OnGUI)?
- "tool window" → EditorWindow 需要什麼功能?使用哪種 UI 系統?
慣例
優先遵循專案模式。 套用預設值前,先搜尋現有的編輯器腳本。
| 型別 | 慣例 | 良好 | 不佳 |
|---|---|---|---|
| 腳本名稱 | PascalCase | MyToolWindow.cs |
my-tool-window.cs |
| EditorWindow | [Name]Window.cs |
LevelEditorWindow.cs |
LevelEditor.cs |
| 自訂 Editor | [Type]Editor.cs |
EnemyEditor.cs |
EnemyInspector.cs |
| PropertyDrawer | [Type]Drawer.cs |
RangeDrawer.cs |
RangePropertyDrawer.cs |
| 位置 | Editor 資料夾 |
Assets/Editor/ |
Assets/Scripts/ |
必須放在 Editor 資料夾 — 使用 UnityEditor 命名空間的腳本必須放在 Editor 資料夾中,否則無法建置。
工作流程
- 分析 — 判斷需要的腳本型別(EditorWindow、Editor、PropertyDrawer 等)
- 搜尋 — 尋找現有的編輯器腳本以比對模式
- 遵循專案模式 — 比對資料夾結構和命名
- 建立腳本 — 使用適當的基底類別和屬性
- 實作 OnGUI — 使用版面配置群組建立介面
腳本結構
EditorWindow
[MenuItem attribute] → 加入選單
ShowWindow() 靜態方法 → 開啟視窗
OnGUI() → 繪製介面
OnEnable/OnDisable → 初始化/清理
自訂 Editor
[CustomEditor attribute] → 指定目標元件型別
OnInspectorGUI() → 繪製 Inspector
OnEnable() → 快取 SerializedProperties
serializedObject.Update/ApplyModifiedProperties → 支援復原
PropertyDrawer
[CustomPropertyDrawer attribute] → 指定目標型別或屬性
OnGUI(Rect, SerializedProperty, GUIContent) → 繪製屬性
GetPropertyHeight() → 如有需要,自訂高度
重要規則
- 快取 GUIStyle 物件 — 切勿在 OnGUI 中建立新的 GUIStyle(會導致每幀記憶體配置)
- 使用 SerializedProperty — 以在 Inspector 中獲得正確的復原/重做支援
- 呼叫 ApplyModifiedProperties() — 在序列化物件有任何變更後
- 使用 EditorGUILayout — 用於編輯器腳本(自動版面配置)
- 使用 GUILayout — 用於執行時期的 OnGUI
- Begin/End 配對 — 務必將 BeginHorizontal 與 EndHorizontal 配對,其餘依此類推
- 必須放在 Editor 資料夾 — 腳本若不在 Editor 資料夾中,將無法建置
版面配置基礎
水平群組:
EditorGUILayout.BeginHorizontal();
// 元素並排顯示
EditorGUILayout.EndHorizontal();
垂直群組:
EditorGUILayout.BeginVertical("box");
// 元素垂直堆疊,並套用 box 樣式
EditorGUILayout.EndVertical();
捲動檢視:
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
// 可捲動內容
EditorGUILayout.EndScrollView();
摺疊區段:
showSection = EditorGUILayout.Foldout(showSection, "區段名稱");
if (showSection)
{
EditorGUI.indentLevel++;
// 區段內容
EditorGUI.indentLevel--;
}
常見模式
帶有動作的按鈕:
if (GUILayout.Button("執行某動作"))
{
// 在此執行動作
}
帶有標籤的屬性欄位:
EditorGUILayout.PropertyField(myProperty, new GUIContent("標籤"));
物件參考欄位:
myObject = (MyType)EditorGUILayout.ObjectField("標籤", 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。






