本次講解的是對應我們自己編寫的類或者結構體,按照需求自定義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