您的位置:首页 > 移动开发 > Unity3D

Unity编辑器开发CustomPropertyDrawer

2021-05-06 01:17 1076 查看

在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方法,我们通过重写这个方法,修改属性显示;

创建Editor文件夹

 第一步,我先创建一个Editor文件夹,告诉Unity这里面放与编辑器有关的代码。不会参与游戏的构建。接下来,创建一个C#文件,命名为FloatRangeDrawer,在这里写修改FloatRange类型在编辑器中显示的相关代码。

继承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();

3.现在属性的Label太宽了,我们可以通过EditorGUIUtilit 56c y.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"));

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(posi
56c
tion, property.FindPropertyRelative("max"));

这样我们自定义属性列表就做好啦

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: