本次講解的是對(duì)應(yīng)我們自己編寫的類或者結(jié)構(gòu)體耕腾,按照需求自定義Drawer的簡(jiǎn)單示例
Value Drawer是Odin最基本的Drawer型,通常是最終在檢查員中完成屬性最終繪制的繪制敢艰。因此,它們通常位于繪制鏈中的最后一個(gè)抽屜中,通常不會(huì)延續(xù)該鏈兑凿。所以本示例不會(huì)出現(xiàn)
this.CallNextDrawer(label);
等字樣疤祭。
示例比較簡(jiǎn)單盼产,我們接下來分幾個(gè)步驟即可完成
創(chuàng)建我們的自定義類
// 演示如何為自定義類型生成自定義drawer的示例。
[TypeInfoBox("此示例演示如何為自定義結(jié)構(gòu)或類實(shí)現(xiàn)自定義drawer")]
public class CustomDrawerExample : MonoBehaviour
{
public MyStruct MyStruct;
[ShowInInspector]
public static float labelWidth = 10;
}
// 自定義數(shù)據(jù)結(jié)構(gòu)画株,用于演示辆飘。
[Serializable]
public struct MyStruct
{
public float X;
public float Y;
}
創(chuàng)建一個(gè)用于繪制MyStruct
的Darwe類
此繪制類需要繼承
OdinValueDrawer
,并傳入對(duì)應(yīng)的類型
public class CustomStructDrawer : OdinValueDrawer<MyStruct>
{
}
開始繪制
準(zhǔn)備工作完成谓传,接下來開始真正的繪制,這里我們需要重寫
DrawPropertyLayout
方法
protected override void DrawPropertyLayout(GUIContent label)
{
}
繪制主要分為以下幾個(gè)步驟
- 獲取我們繪制類的值
- 獲取要繪制的區(qū)域(rect)
- 保存原始labelWidth的寬度
- 設(shè)定新的label寬度
- 根據(jù)slider對(duì)應(yīng)的值進(jìn)行賦值
- 恢復(fù)設(shè)定原始label寬度
- 將新的Struct賦值給我們定義的MyStruct
protected override void DrawPropertyLayout(GUIContent label)
{
//獲取我們繪制類的值
MyStruct value = this.ValueEntry.SmartValue;
//獲取要繪制的區(qū)域(rect)
var rect = EditorGUILayout.GetControlRect();
//在Odin中蜈项,標(biāo)簽是可選項(xiàng),可以為空续挟,所以我們必須考慮到這一點(diǎn)紧卒。
if (label != null)
{
rect = EditorGUI.PrefixLabel(rect, label);
}
//保存原始labelWidth的寬度,此label為struct中對(duì)應(yīng)的X,Y
var prev = EditorGUIUtility.labelWidth;
//設(shè)定新的label寬度
EditorGUIUtility.labelWidth = CustomDrawerExample.labelWidth;
//根據(jù)slider對(duì)應(yīng)的值進(jìn)行賦值
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);
//恢復(fù)設(shè)定原始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("此示例演示如何為自定義結(jié)構(gòu)或類實(shí)現(xiàn)自定義drawer")]
public class CustomDrawerExample : MonoBehaviour
{
public MyStruct MyStruct;
[ShowInInspector]
public static float labelWidth = 10;
}
// 自定義數(shù)據(jù)結(jié)構(gòu)跑芳,用于演示。
[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;
//獲取要繪制的區(qū)域(rect)
var rect = EditorGUILayout.GetControlRect();
//在Odin中直颅,標(biāo)簽是可選項(xiàng)博个,可以為空,所以我們必須考慮到這一點(diǎn)功偿。
if (label != null)
{
rect = EditorGUI.PrefixLabel(rect, label);
}
//保存原始labelWidth的寬度盆佣,此label為struct中對(duì)應(yīng)的X,Y
var prev = EditorGUIUtility.labelWidth;
//設(shè)定新的label寬度
EditorGUIUtility.labelWidth = CustomDrawerExample.labelWidth;
//根據(jù)slider對(duì)應(yīng)的值進(jìn)行賦值
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);
//恢復(fù)設(shè)定原始label寬度
EditorGUIUtility.labelWidth = prev;
//將新的Struct賦值給我們定義的MyStruct
this.ValueEntry.SmartValue = value;
}
}
#endif
}
#endif