Odin Inspector 系列教程 --- 自定義Drawer特性

本章簡述如何基于Odin制作可繪制的特性

本示例是在一個屬性上面添加一個自定義特性,然后這個屬性會基于這個特性按照我們定于的效果繪制。

創建一個我們示例類
    // 演示如何為屬性創建自定義drawer的示例。
    [TypeInfoBox("這里是使用自定義屬性drawer繪制的HealthBar欄的可視化")]
    public class HealthBarExample : MonoBehaviour
    {
        public float Health;
    }
隨后我們要創建一個特性,放在 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)]

    // 演示如何為屬性創建自定義drawer的示例。
    [TypeInfoBox("這里是使用自定義屬性drawer繪制的HealthBar欄的可視化")]
    public class HealthBarExample : MonoBehaviour
    {
        [HealthBar(100)]
        public float Health;
    }

這樣我們在使用的層面上算是完成了,但是我們怎么自定義繪制呢?接下來就需要給這個特性HealthBarAttribute做詳細的繪制規劃了
創建HealthBarAttributeDrawer 并集成OdinAttributeDrawer,需要兩個參數,第一個參數是需要繪制的特性,第二個參數是繪制這個特性中的那種類型字段,因為我們繪制的是float Health,所以第二個參數填寫float
下面的代碼主要實現如下幾步

  • 獲取此類型float對應的值ValueEntry.SmartValue
  • 獲取一塊繪制區域Rect rect = EditorGUILayout.GetControlRect();
  • 繪制底色SirenixEditorGUI.DrawSolidRect(rect, new Color(0f, 0f, 0f, 0.3f), false);
  • 按照百分比出現的紅色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傳遞下去,便于其他的特性進行繪制
            this.CallNextDrawer(label);

            // 找一個矩形來繪制健康條。您也可以使用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



注意

自定義繪制的時候需要一些Unity原本GUI的知識,Odin本身的API就已經眾多,如果要達到和Odin原始提供特性一樣的出色效果,還是有一些難度的。
而且在使用Unity原本EditorAPI的時候,更推薦使用Rect方式,避免使用GUILayout相關。

完整示例代碼
#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

    // 演示如何為屬性創建自定義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傳遞下去,便于其他的特性進行繪制
            this.CallNextDrawer(label);

            // 找一個矩形來繪制健康條。您也可以使用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

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

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

推薦閱讀更多精彩內容