一、引言,
在上一篇文章中提到,CustomEditor只能自定义单一类,被其他类持有的类自定义没有作用,这个时候就需要使用CustomPropertyDrawer属性。
二、PropertyDrawer介绍
PropertyDrawer用于自定义属性绘制器的基类。使用PropertyDrawer来控制它在Inspector中的样式。可以使用CustomPropertyDrawer 特性将 PropertyDrawer附加到 Serializable类,然后传入绘制器进行渲染。使用此基类有两种用途:
- 对使用[Serializable]的自定义类,可以自定义绘制实例的GUI。
- 使用自定义属性,绘制属性自定义脚本成员的GUI。例如:[Range(0f, 10f)]
用途一
之前
 
 之后
 
 代码:
[CustomPropertyDrawer(typeof(MonoTest))]
public class MonoTestEditor : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        var nameRect = new Rect(position.x, position.y, 222, position.height);
        var amountRect = new Rect(position.x + 222, position.y, 222, position.height);
        var unitRect = new Rect(position.x + 222 + 222, position.y, 222, position.height);
        EditorGUIUtility.labelWidth = 100;
        EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("intValue"));
        EditorGUI.PropertyField(amountRect, property.FindPropertyRelative("boolValue"));
        EditorGUI.PropertyField(unitRect, property.FindPropertyRelative("enumValue"));
    }
}
用途二
Unity中,有一些内置属性可直接使用,例如:[Range(0,100)]、[Header(“Header Name”)]、[Tooltip(“Tips”)]等,当然自己也可以自定义属性,一个简单实例(仅做示例,不论功能):需要在滑动条后面,显示当前滑动条的值
 代码如下:
//定义自定义属性类
public sealed class RangeTestAttribute : PropertyAttribute
{
    public readonly float min;
    public readonly float max;
    public RangeTestAttribute(float min, float max)
    {
        this.min = min;
        this.max = max;
    }
}
//对属性类自定义显示
[CustomPropertyDrawer(typeof(RangeTestAttribute))]
public class RangeTestAttributeDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        RangeTestAttribute range = (RangeTestAttribute)attribute;
        //类型是float
        if (property.propertyType == SerializedPropertyType.Float)
        {
            EditorGUI.Slider(new Rect(position.x, position.y, position.width * 0.8f, position.height), property, range.min, range.max);
            EditorGUI.LabelField(new Rect(position.x + position.width * 0.8f, position.y, position.width - (position.x + position.width * 0.8f), position.height), "滑到了" + property.floatValue);
        }
        else
        {
            EditorGUI.HelpBox(new Rect(position.x, position.y, position.width, position.height), "只支持float类型属性", MessageType.Error);
        }
    }
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        return base.GetPropertyHeight(property, label);
    }
}
结果
   我们仿照Unity内置的Range,自定义一个属性,以后咱们就可以使用代码[RangeTest(-1, 100)],来使用属性功能(在后面跟了一个小尾巴,显示当前滑动条的数值)。如下:
	//[Range(-1, 100)]
    [RangeTest(-1, 100)]
    public float enumValue;
效果图:
 



















