[閱讀筆記] Unity のエディター拡張 #3
《Unity のエディター拡張》後所留下的簡單筆記,第九到十一章。 介紹了 CustomEditor,也就是最常被使用的 自訂 Inspector 操作介面,這幾個章節內容很多,我覺得介紹依舊尚淺而有些不明白。 CustomEditor 真是博大精深的領域!
第九章:CustomEditor
- CustomEditor 是指 **自訂 **提供給 Component 顯示於 Inspector 與 SceneView 中的 編輯器。
- Inspector 視窗可以切換 Normal / Debug 兩個模式,分成 GUI 顯示或者只列出 Serialize Field 欄位資訊。
- 一般應用可以利用第二章介紹的功能自訂部分 Inspector 視窗。
- 直接實作 CustomEditor 需要繼承 Editor 類別,並使用 CustomEditor (Type) 這個 Attribute 指定想要對應的 MonoBehaviour。
- 自訂的 GUI 需透過 override 寫於 OnInspectorGUI 及 OnSceneGUI 兩個方法中。
- base.OnInspectorGUI () 記得於 override 後進行呼叫。
- 作為 Editor 存取 MonoBehaviour 的 Serialize Field 參數的手段:
- 使用 Editor.serializedObject 來存取,透過 serializedObject.FindProperty() 來取得特定欄位。
- 直接參照 MonoBehaviour,進行操作。
- Undo 的實作:
- EditorGUI.BeginChangeCheck / EndChangeCheck 檢查參數是否有變化。
- Undo.RecordObject () 進行 Undo 序列的紀錄寫入。
- 複選多個相同 Component 的情況:
- CanEditMultipleObjects 是允許複數編輯的 Attribute。
- 複數編輯是對多個 serializedObject 的存取與操作。
- Editor.targets 可以取得被複選的 Component 實體,進行複數選取時的綜合介面實作。
- EditorGUI.showMixedValue 用於標示接下來的欄位,不同 Component 的值相異,數值顯示會以橫槓 (ー) 表示。
- 值的寫入需要用迴圈操作。
- 用 PropertyDrawer 實作特定類別的編輯器:
- 需要繼承 PropertyDrawer 類別,並使用 CustomPropertyDrawer (Type) 這個 Attribute 指定想要對應的 class。
- OnGUI (Rect position, SerializedProperty property, GUIContent label) 是實作 GUI 的指定方法。
- 透過 property.FindPropertyRelative 可以取得對性類別的 Serialize Field 資訊。
- GetPropertyHeight () 必須 override 並回傳自訂編輯器的高度,才能正確的在 Inspector 上繪製。
- base.GetPropertyHeight (property, label) 可取得依照 Serialize Field 數量計算的預設高度。
- Inspector 下方的預覽窗:
- Editor.HasPreviewGUI () 經過 override,會在回傳 true 時顯示預覽窗。
- Editor.GetPreviewTitle () 用於實作標題。
- Editor.OnPreviewSettings () 用於實作右上方按鈕。
- Editor.OnPreviewGUI (Rect r, GUIStyle background) 用於實作窗口內容。
- 透過 PreviewRenderUtility 進行場景的取景與渲染。
- 如果需要單一物件的預覽:
- 使用 Object.Instantiate 生成預覽用物件。
- 物件設定為 HideFlags.HideAndDontSave。
- 以 Camera.PreviewCullingLayer 為 cullingMask 進行 PreviewRenderUtility 的渲染。
- Editor.OnInteractivePreviewGUI (Rect r, GUIStyle background) 用於實作可以互動 (旋轉物件) 的預覽窗。
- 針對 Asset (而非腳本) 也可以實作 Editor 來增加對資源的支援。
第十章:PropertyDrawer
- PropertyDrawer 是為特定類別設計,通用於所有相關應用的 Component 上, 顯示 Serialize Field 於 Inspector。
- PropertyDrawer 除了對應類別,也可以對應到 PropertyAttribute 的實作。
- 如果實作的 CustomGUI 跟預設的 GUI 高度不同,則必須實作 GetPropertyHeight() 的 override,Inspector 才能正確運作。
- base.GetPropertyHeight() 會取得預設 GUI 的高度。
- EditorGUILayout.Knob 本來不可用於 PropertyDrawer,但本章節使用了 Reflection 強制將這個 EditorGUI 用於 PropertyDrawer 上。
- 本章的其他範例:
- 連結參數到同一物件其他 Component 的資訊。
- 讓對應欄位顯示 GUI 跟數值但無法編輯。
- 讓 enum 的 popup menu 用指定字串代替數值。
- 實作 int,string 等變數的 popup menu。
- url 圖片預覽。
- 用下拉選單選擇場景名稱存入 string 變數。
第十一章:ProjectWindowUtil
- ProjectWindowUtil 用於處理在 Project 視窗創建資源、變更名稱等動作。
- ProjectWindowUtil.CreateAsset () 創建資源,並進入命名模式,與 AssetDatabase.CreateAsset 會直接定名不同。
- 實際上內部呼叫了 StartNameEditingIfProjectWindowExists ()。
- ProjectWindowUtil.StartNameEditingIfProjectWindowExists () 創建資源並進行更名動作。
- EndNameEditAction 是更名動作需要的一個傳入參數,可用於自訂更名完畢的後續動作。
- EndNameEditAction 需用 ScriptableObject.CreateInstance
() 實體化。
- 透過 ProjectWindowUtil 可以實作各種自訂資源的生成,並可以在命名後進行一些處理。