I. Introduction,
As mentioned in the previous article, CustomEditor can only customize a single class. Customization of classes held by other classes has no effect. At this time, you need to use the CustomPropertyDrawer attribute.
2. Introduction to PropertyDrawer
PropertyDrawer Base class for custom property painters. Use the PropertyDrawer to control its style in the Inspector. You can use the CustomPropertyDrawer attribute to attach a PropertyDrawer to the Serializable class and then pass it into the painter for rendering. There are two uses for using this base class:
- For
[Serializable]
the custom classes used, the GUI of the drawing instance can be customized. - Use custom properties to draw properties to the GUI of custom script members. For example:
[Range(0f, 10f)]
Purpose 1
Before
After
Code:
[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"));
}
}
Use two
In Unity, there are some built-in properties that can be used directly, such as: [Range(0,100)]
, [Header(“Header Name”)]
, etc. Of course, you can also customize properties yourself. A simple example (just an example, regardless of function): you need to display the value code [Tooltip(“Tips”)]
of the current slide bar behind the slide bar.
as follows:
//定义自定义属性类
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);
}
}
As a result
, we imitated Unity's built-in Range and customized an attribute. In the future, we can use code [RangeTest(-1, 100)]
to use the attribute function (followed by a small tail to display the current value of the slider). as follows:
//[Range(-1, 100)]
[RangeTest(-1, 100)]
public float enumValue;
Rendering: