Odin Inspector 系列教程 --- 自定義 Value Drawer

本次講解的是對應我們自己編寫的類或者結構體,按照需求自定義Drawer的簡單示例

Value Drawer是Odin最基本的Drawer型,通常是最終在檢查員中完成屬性最終繪制的繪制。因此,它們通常位于繪制鏈中的最后一個抽屜中,通常不會延續該鏈。所以本示例不會出現this.CallNextDrawer(label);等字樣。

示例比較簡單,我們接下來分幾個步驟即可完成

創建我們的自定義類
    // 演示如何為自定義類型生成自定義drawer的示例。
    [TypeInfoBox("此示例演示如何為自定義結構或類實現自定義drawer")]
    public class CustomDrawerExample : MonoBehaviour
    {
        public MyStruct MyStruct;
        [ShowInInspector]
        public static float labelWidth = 10;
    }

    // 自定義數據結構,用于演示。
    [Serializable]
    public struct MyStruct
    {
        public float X;
        public float Y;
    }
創建一個用于繪制MyStruct的Darwe類

此繪制類需要繼承OdinValueDrawer,并傳入對應的類型

    public class CustomStructDrawer : OdinValueDrawer<MyStruct>
    {

    }
開始繪制

準備工作完成,接下來開始真正的繪制,這里我們需要重寫DrawPropertyLayout方法

        protected override void DrawPropertyLayout(GUIContent label)
        {
            
        }
繪制主要分為以下幾個步驟
  • 獲取我們繪制類的值
  • 獲取要繪制的區域(rect)
  • 保存原始labelWidth的寬度
  • 設定新的label寬度
  • 根據slider對應的值進行賦值
  • 恢復設定原始label寬度
  • 將新的Struct賦值給我們定義的MyStruct
        protected override void DrawPropertyLayout(GUIContent label)
        {
            //獲取我們繪制類的值
            MyStruct value = this.ValueEntry.SmartValue;

            //獲取要繪制的區域(rect)
            var rect = EditorGUILayout.GetControlRect();
            //在Odin中,標簽是可選項,可以為空,所以我們必須考慮到這一點。
            if (label != null)
            {
                rect = EditorGUI.PrefixLabel(rect, label);
            }

            //保存原始labelWidth的寬度,此label為struct中對應的X,Y
            var prev = EditorGUIUtility.labelWidth;

            //設定新的label寬度
            EditorGUIUtility.labelWidth = CustomDrawerExample.labelWidth;

            //根據slider對應的值進行賦值
            value.X = EditorGUI.Slider(rect.AlignLeft(rect.width * 0.5f), "X", value.X, 0, 1);
            value.Y = EditorGUI.Slider(rect.AlignRight(rect.width * 0.5f), "Y", value.Y, 0, 1);

            //恢復設定原始label寬度
            EditorGUIUtility.labelWidth = prev;

            //將新的Struct賦值給我們定義的MyStruct
            this.ValueEntry.SmartValue = value;
        }

完整示例代碼

#if UNITY_EDITOR
namespace Sirenix.OdinInspector.Demos
{
    using UnityEngine;
    using System;

#if UNITY_EDITOR

    using Sirenix.OdinInspector.Editor;
    using UnityEditor;
    using Sirenix.Utilities;

#endif

    // 演示如何為自定義類型生成自定義drawer的示例。
    [TypeInfoBox("此示例演示如何為自定義結構或類實現自定義drawer")]
    public class CustomDrawerExample : MonoBehaviour
    {
        public MyStruct MyStruct;
        [ShowInInspector]
        public static float labelWidth = 10;
    }

    // 自定義數據結構,用于演示。
    [Serializable]
    public struct MyStruct
    {
        public float X;
        public float Y;
    }

#if UNITY_EDITOR

    public class CustomStructDrawer : OdinValueDrawer<MyStruct>
    {
        protected override void DrawPropertyLayout(GUIContent label)
        {
            //獲取我們繪制類的值
            MyStruct value = this.ValueEntry.SmartValue;

            //獲取要繪制的區域(rect)
            var rect = EditorGUILayout.GetControlRect();
            //在Odin中,標簽是可選項,可以為空,所以我們必須考慮到這一點。
            if (label != null)
            {
                rect = EditorGUI.PrefixLabel(rect, label);
            }

            //保存原始labelWidth的寬度,此label為struct中對應的X,Y
            var prev = EditorGUIUtility.labelWidth;

            //設定新的label寬度
            EditorGUIUtility.labelWidth = CustomDrawerExample.labelWidth;

            //根據slider對應的值進行賦值
            value.X = EditorGUI.Slider(rect.AlignLeft(rect.width * 0.5f), "X", value.X, 0, 1);
            value.Y = EditorGUI.Slider(rect.AlignRight(rect.width * 0.5f), "Y", value.Y, 0, 1);

            //恢復設定原始label寬度
            EditorGUIUtility.labelWidth = prev;

            //將新的Struct賦值給我們定義的MyStruct
            this.ValueEntry.SmartValue = value;
        }
    }
#endif
}
#endif


更多教程內容詳見:革命性Unity 編輯器擴展工具 --- Odin Inspector 系列教程

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容