本章簡述如何基于Odin制作可繪制的特性
本示例是在一個(gè)屬性上面添加一個(gè)自定義特性,然后這個(gè)屬性會(huì)基于這個(gè)特性按照我們定于的效果繪制。
創(chuàng)建一個(gè)我們示例類
// 演示如何為屬性創(chuàng)建自定義drawer的示例。
[TypeInfoBox("這里是使用自定義屬性drawer繪制的HealthBar欄的可視化")]
public class HealthBarExample : MonoBehaviour
{
public float Health;
}
隨后我們要?jiǎng)?chuàng)建一個(gè)特性醒陆,放在 Health
屬性上面
// Attribute used by HealthBarAttributeDrawer.
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class HealthBarAttribute : Attribute
{
public float MaxHealth { get; private set; }
public HealthBarAttribute(float maxHealth)
{
this.MaxHealth = maxHealth;
}
}
添加特性
唯一的變化就是在屬性
Health
添加了特性[HealthBar(100)]
// 演示如何為屬性創(chuàng)建自定義drawer的示例溪椎。
[TypeInfoBox("這里是使用自定義屬性drawer繪制的HealthBar欄的可視化")]
public class HealthBarExample : MonoBehaviour
{
[HealthBar(100)]
public float Health;
}
這樣我們在使用的層面上算是完成了肺孵,但是我們怎么自定義繪制呢走敌?接下來就需要給這個(gè)特性
HealthBarAttribute
做詳細(xì)的繪制規(guī)劃了
創(chuàng)建HealthBarAttributeDrawer 并集成OdinAttributeDrawer碴倾,需要兩個(gè)參數(shù)逗噩,第一個(gè)參數(shù)是需要繪制的特性掉丽,第二個(gè)參數(shù)是繪制這個(gè)特性中的那種類型字段,因?yàn)槲覀兝L制的是float Health
,所以第二個(gè)參數(shù)填寫float
下面的代碼主要實(shí)現(xiàn)如下幾步
- 獲取此類型float對應(yīng)的值
ValueEntry.SmartValue
- 獲取一塊繪制區(qū)域
Rect rect = EditorGUILayout.GetControlRect();
- 繪制底色
SirenixEditorGUI.DrawSolidRect(rect, new Color(0f, 0f, 0f, 0.3f), false);
- 按照百分比出現(xiàn)的紅色
SirenixEditorGUI.DrawSolidRect(rect.SetWidth(rect.width * width), Color.red, false);
- 健康條的Outline(邊框)
SirenixEditorGUI.DrawBorders(rect, 1);
#if UNITY_EDITOR
// Place the drawer script file in an Editor folder or wrap it in a #if UNITY_EDITOR condition.
public class HealthBarAttributeDrawer : OdinAttributeDrawer<HealthBarAttribute, float>
{
protected override void DrawPropertyLayout(GUIContent label)
{
// 讓此label傳遞下去异雁,便于其他的特性進(jìn)行繪制
this.CallNextDrawer(label);
// 找一個(gè)矩形來繪制健康條捶障。您也可以使用GUILayout,但是使用rects使繪制健康欄變得更簡單纲刀。
Rect rect = EditorGUILayout.GetControlRect();
// Draw the health bar.
float width = Mathf.Clamp01(this.ValueEntry.SmartValue / this.Attribute.MaxHealth);
SirenixEditorGUI.DrawSolidRect(rect, new Color(0f, 0f, 0f, 0.3f), false);
SirenixEditorGUI.DrawSolidRect(rect.SetWidth(rect.width * width), Color.red, false);
SirenixEditorGUI.DrawBorders(rect, 1);
}
}
#endif
注意
自定義繪制的時(shí)候需要一些Unity原本GUI的知識(shí)项炼,Odin本身的API就已經(jīng)眾多,如果要達(dá)到和Odin原始提供特性一樣的出色效果示绊,還是有一些難度的锭部。
而且在使用Unity原本EditorAPI的時(shí)候,更推薦使用Rect方式面褐,避免使用GUILayout相關(guān)拌禾。
完整示例代碼
#if UNITY_EDITOR
namespace Sirenix.OdinInspector.Demos
{
using System;
using UnityEngine;
#if UNITY_EDITOR
using Sirenix.OdinInspector.Editor;
using UnityEditor;
using Sirenix.Utilities.Editor;
using Sirenix.Utilities;
#endif
// 演示如何為屬性創(chuàng)建自定義drawer的示例。
[TypeInfoBox("這里是使用自定義屬性drawer繪制的HealthBar欄的可視化")]
public class HealthBarExample : MonoBehaviour
{
[HealthBar(100)]
public float Health;
}
// Attribute used by HealthBarAttributeDrawer.
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class HealthBarAttribute : Attribute
{
public float MaxHealth { get; private set; }
public HealthBarAttribute(float maxHealth)
{
this.MaxHealth = maxHealth;
}
}
#if UNITY_EDITOR
// Place the drawer script file in an Editor folder or wrap it in a #if UNITY_EDITOR condition.
public class HealthBarAttributeDrawer : OdinAttributeDrawer<HealthBarAttribute, float>
{
protected override void DrawPropertyLayout(GUIContent label)
{
// 讓此label傳遞下去展哭,便于其他的特性進(jìn)行繪制
this.CallNextDrawer(label);
// 找一個(gè)矩形來繪制健康條湃窍。您也可以使用GUILayout闻蛀,但是使用rects使繪制健康欄變得更簡單。
Rect rect = EditorGUILayout.GetControlRect();
// Draw the health bar.
float width = Mathf.Clamp01(this.ValueEntry.SmartValue / this.Attribute.MaxHealth);
SirenixEditorGUI.DrawSolidRect(rect, new Color(0f, 0f, 0f, 0.3f), false);
SirenixEditorGUI.DrawSolidRect(rect.SetWidth(rect.width * width), Color.red, false);
SirenixEditorGUI.DrawBorders(rect, 1);
}
}
#endif
}
#endif