Unity編輯器開發CustomPropertyDrawer


  在unity中我們有時候需要自定義結構類型,比如我們自定義一個結構浮點數的范圍FloatRange,在最大和最小的范圍中取隨機數。

 using UnityEngine;
[System.Serializable]
public struct FloatRange
{
    public float min, max;
    public float RangeValueInRange
    {
        get
        {
            return Random.Range(min, max);
        }
    }
}

 如果我們想設置一個FloatRange類型的字段,在編輯器中可能會顯示成這樣。但是一個屬性占了兩行,不太美觀,我們可以自己修改編輯器,Unity編輯器顯示字段時,會調用OnGUI方法,我們通過重寫這個方法,修改屬性顯示;
image

創建Editor文件夾

 第一步,我先創建一個Editor文件夾,告訴Unity這里面放與編輯器有關的代碼。不會參與游戲的構建。接下來,創建一個C#文件,命名為FloatRangeDrawer,在這里寫修改FloatRange類型在編輯器中顯示的相關代碼。
image

繼承PropertyDrawer

 對編輯器屬性操作,需要繼承PropertyDrawer類,同時還依賴UnityEditor命名空間。類名上加上[CustomPropertyDrawer(typeof(FloatRange))],告訴Unity這是一個CustomPropertyDrawer,並且typeof(FloatRange)指定是FloatRange類型的CustomPropertyDrawer;

using UnityEngine;
using UnityEditor;//編輯器依賴

//告訴Unity要創建FloatRange類型的CustomPropertyDrawer
[CustomPropertyDrawer(typeof(FloatRange))]
public class FloatRangeDrawer : PropertyDrawer
{

}

具體代碼

1.重寫Unity本身onGUI的函數,里面分別帶有位置,屬性和標簽三個參數。EditorGUI.BeginPropertyEditorGUI.EndProperty告訴Unity要創建屬性的UI,在這兩個方法之間寫我們的代碼

	//覆蓋Unity本身OnGUI函數,它在每次要顯示FloatRange時被調用。
	//三個參數 position 定義繪制的區域 property 定義浮點數的范圍值
	//label使用的默認標簽
	public override void OnGUI(
		Rect position, SerializedProperty property, GUIContent label
	){
		EditorGUI.BeginProperty(position, label, property);
		EditorGUI.EndProperty();
	}

2.通過EditorGUI.PropertyField方法顯示我們的屬性UI,方法有兩個參數,一個是顯示的位置,一個是屬性,可以通過 property.FindPropertyRelative("屬性名")獲取屬性

		EditorGUI.BeginProperty(position, label, property);

 		EditorGUI.PropertyField(position, property.FindPropertyRelative("min"));
		EditorGUI.PropertyField(position, property.FindPropertyRelative("max"));

		EditorGUI.EndProperty();

  現在我們編輯器里已經顯示了min和max兩個屬性了,但是因為他們的位置都是position,所以重疊在一起了,我們把兩個屬性的寬度都縮小一半,然后將其中一個屬性的位置后移自身的寬度。這樣兩個屬性就並排顯示了

		EditorGUI.BeginProperty(position, label, property);
		//區域寬度設為一半
		position.width = position.width / 2f;
 		EditorGUI.PropertyField(position, property.FindPropertyRelative("min"));
		//max屬性右移
		position.x += position.width;
		EditorGUI.PropertyField(position, property.FindPropertyRelative("max"));

		EditorGUI.EndProperty();

image

3.現在屬性的Label太寬了,我們可以通過EditorGUIUtility.labelWidth進行調整

		EditorGUI.BeginProperty(position, label, property);
		//區域寬度設為一半
		position.width = position.width / 2f;
		//調整標簽Label寬度為 當前寬度的一半
        EditorGUIUtility.labelWidth = position.width / 2f;
 		EditorGUI.PropertyField(position, property.FindPropertyRelative("min"));
		//max屬性右移
		position.x += position.width;
		EditorGUI.PropertyField(position, property.FindPropertyRelative("max"));

image

4.現在很好,但是別忘了我們的字段標簽; EditorGUI.PrefixLabel方法設置字段標簽,返回值是添加字段標簽后剩余的位置

		EditorGUI.BeginProperty(position, label, property);

 		//顯示字段標簽,返回標簽占用后剩余的區域
      	position = EditorGUI.PrefixLabel(position, label);
		//區域寬度設為一半
		position.width = position.width / 2f;
		//調整標簽Label寬度為 當前寬度的一半
        EditorGUIUtility.labelWidth = position.width / 2f;
 		EditorGUI.PropertyField(position, property.FindPropertyRelative("min"));
		//max屬性右移
		position.x += position.width;

		EditorGUI.PropertyField(position, property.FindPropertyRelative("max"));

這樣我們自定義屬性列表就做好啦
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM