上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

Unity 编辑器篇|(十三)自定义属性绘制器(PropertyDrawer ,PropertyAttribute) (全面总结 | 建议收藏)

guduadmin86天前

目录

  • 1. 前言
  • 2. PropertyDrawer
    • 2.1 参数总览
    • 2.2 两种用途
    • 2.3 注意事项
    • 2.4 代码样例
    • 3. PropertyDrawer与PropertyAttribute结合使用

      1. 前言

      • 在Unity中,PropertyDrawer和PropertyAttribute是两个重要的工具,它们主要用于自定义属性的显示和行为。
      • PropertyDrawer是一个类,它定义了如何在编辑器中渲染属性的外观。你可以通过继承PropertyDrawer类并重写其方法来自定义属性的显示方式。PropertyDrawer主要关注的是在编辑器中如何显示属性,提供了一种灵活的方式来控制属性的外观和交互方式。
      • PropertyAttribute是一个标记特性,它可以应用于C#类中的字段或属性上,提供额外的元数据或改变默认的编辑行为。通过使用PropertyAttribute,你可以为属性添加各种功能,例如限制值的范围、添加提示信息等。PropertyAttribute主要关注的是在代码中提供更多关于属性的信息和行为,以便在编辑器中更好地处理和呈现这些属性。
      • 将PropertyDrawer和PropertyAttribute结合使用,可以实现更加丰富和灵活的编辑器自定义功能。通过定义自己的PropertyDrawer来控制属性的显示方式,并使用PropertyAttribute来提供额外的属性和行为信息,可以创建出高度定制化的编辑器界面,满足特定场景的需求。

        2. PropertyDrawer

        2.1 参数总览

        常用参数描述
        CreatePropertyGUI使用 UI Toolkit 为属性创建自定义 GUI。
        GetPropertyHeight重载此方法可指定此字段的 GUI 的高度(以像素为单位)。
        OnGUI重写此方法,为属性创建自己的基于 IMGUI 的 GUI。

        2.2 两种用途

        • 自定义可序列化类的每个实例的GUI。如果脚本中的属性是自定义类,并且需要在Inspector中显示,可以使用Serializable修饰符。
        • 自定义具有自定义PropertyAttribute的脚本成员的GUI。通过结合使用PropertyAttribute和PropertyDrawer,可以自定义自己的Attribute,如添加提示信息、范围限制等。

          2.3 注意事项

          • PropertyDrawer只对可序列化的类有效,非可序列化的类没法在Inspector面板中显示。
          • OnGUI方法里只能使用GUI相关方法,不能使用Layout相关方法。
          • PropertyDrawer对应类型的所有属性的显示方式都会修改,例如创建一个带string属性的MonoBehaviour。

            2.4 代码样例

            using UnityEngine;
            using UnityEditor;
            [CustomPropertyDrawer(typeof(string))]
            public class StringPropertyDrawer : PropertyDrawer
            {
                public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
                {
                    Rect btnRect = new Rect(position);
                    position.width -= 60;
                    btnRect.x += btnRect.width - 60;
                    btnRect.width = 60;
                    EditorGUI.BeginProperty(position, label, property);
                    EditorGUI.PropertyField(position, property, true);
                    if (GUI.Button(btnRect, "select"))
                    {
                        string path = property.stringValue;
                        string selectStr = EditorUtility.OpenFilePanel("选择文件", path, "");
                        if (!string.IsNullOrEmpty(selectStr))
                        {
                            property.stringValue = selectStr;
                        }
                    }
                    EditorGUI.EndProperty();
                }
            }
            
            using UnityEngine;
            public class Test : MonoBehaviour
            {
                public string str;
            }
            

            Unity 编辑器篇|(十三)自定义属性绘制器(PropertyDrawer ,PropertyAttribute) (全面总结 | 建议收藏),1,第1张

            • 为Inspector面板中的所有string属性添加一个选择文件按钮,选中文件的路径直接赋值给该变量。

              3. PropertyDrawer与PropertyAttribute结合使用

              • 想要修改部分类的指定类型的属性的显示,直接使用PropertyDrawer就无法满足条件,这时可以结合PropertyDrawer和PropertyAttribute来实现需求。
              • Unity中,有一些内置属性可直接使用,例如:[Range(0,100)]、[Header(“Header Name”)]、[Tooltip(“Tips”)] 等,当然自己也可以自定义属性,以下是一个简单实例:需要在滑动条后面,显示当前滑动条的值。
                using UnityEngine;
                public class Test : MonoBehaviour
                {
                    [Range(0.0F, 10.0F)]
                    public float myFloat = 0.0F;
                }
                
                using UnityEngine;
                public class RangeAttribute : PropertyAttribute
                {
                    public float min;
                    public float max;
                    public RangeAttribute(float min, float max)
                    {
                        this.min = min;
                        this.max = max;
                    }
                }
                
                using UnityEngine;
                using UnityEditor;
                using System;
                [CustomPropertyDrawer(typeof(RangeAttribute))]
                public class RangeDrawer : PropertyDrawer
                {
                    // 在给定的矩形内绘制属性
                    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
                    {
                        // 首先获取属性,因为它包含滑块的范围
                        RangeAttribute range = attribute as RangeAttribute;
                        // 现在,根据属性是浮点数还是整数,将属性绘制为 Slider 或 IntSlider。
                        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 if (property.propertyType == SerializedPropertyType.Integer)
                            EditorGUI.IntSlider(position, property, Convert.ToInt32(range.min), Convert.ToInt32(range.max), label);
                        else
                            EditorGUI.LabelField(position, label.text, "将 Range 与 float 或 int 一起使用。");
                    }
                }
                

                Unity 编辑器篇|(十三)自定义属性绘制器(PropertyDrawer ,PropertyAttribute) (全面总结 | 建议收藏),2,第2张

网友评论

搜索
最新文章
热门文章
热门标签