• Unity编辑器扩展之CustomPropertyDrawer理解


    一、引言,

    在上一篇文章中提到,CustomEditor只能自定义单一类,被其他类持有的类自定义没有作用,这个时候就需要使用CustomPropertyDrawer属性。

    二、PropertyDrawer介绍

    PropertyDrawer用于自定义属性绘制器的基类。使用PropertyDrawer来控制它在Inspector中的样式。可以使用CustomPropertyDrawer 特性将 PropertyDrawer附加到 Serializable类,然后传入绘制器进行渲染。使用此基类有两种用途:

    1. 对使用[Serializable]的自定义类,可以自定义绘制实例的GUI。
    2. 使用自定义属性,绘制属性自定义脚本成员的GUI。例如:[Range(0f, 10f)]
    用途一

    之前
    没使用CustomPropertyDrawer
    之后
    使用CustomPropertyDrawer自定义绘制
    代码:

    [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"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    用途二

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    结果
      我们仿照Unity内置的Range,自定义一个属性,以后咱们就可以使用代码[RangeTest(-1, 100)],来使用属性功能(在后面跟了一个小尾巴,显示当前滑动条的数值)。如下:

    	//[Range(-1, 100)]
        [RangeTest(-1, 100)]
        public float enumValue;
    
    • 1
    • 2
    • 3

    效果图:
    自定义效果

    至此这篇文章就结束了,当然如果是实际使用中,就还有很多效果没有实现,知道使用方法之后,查一下官网的API文档就能实现,不过同时还要结合GUI的API,才能自由的愉快的玩耍。

  • 相关阅读:
    Highcharts JS 10.3.1 开心没水印
    冲压模具在线检测技术,解决过哪些问题?
    maven-idea新建和导入项目
    修正能力是智能的关键之一
    经典算法之直接插入排序法
    小成本搏大流量:微信/支付宝小程序搜索排名优化
    PHP 共享茶室棋牌室无人软硬件结合开发小程序系统的开发优势
    day38
    Vue生命周期
    Lambda 表达式:解锁编程世界的魔法之门
  • 原文地址:https://blog.csdn.net/Ling_SevoL_Y/article/details/134072603