在Unity编辑器开发中,可能会遇到如下需求,想要自定义脚本属性字段在检查器中显示的名称,我们可以利用反射和自定义特性来实现这一点

我们平时常用的HeaderAttribute是通过以下内置代码实现的。

[AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = true)]
public class HeaderAttribute : PropertyAttribute
{
    //
    // 摘要:
    //     The header text.
    public readonly string header;

    //
    // 摘要:
    //     Add a header above some fields in the Inspector.
    //
    // 参数:
    //   header:
    //     The header text.
    public HeaderAttribute(string header)
    {
        this.header = header;
    }
}

实际上还有一个HeaderAttributePropertyDrawer,但是我们没办法在VS中查看。

官方对PropertyDrawer的介绍:

Base class to derive custom property drawers from. Use this to create custom drawers for your own Serializable classes or for script variables with custom PropertyAttributes.

在Unity中,PropertyDrawer类是用于从基类派生出自定义属性抽屉的基础类。通过继承这个类并实现特定的方法,可以创建自定义的Inspector界面绘制逻辑。

在Unity实现一个自定义编辑器特性,需要有一个Attribute和一个PropertyDrawer

/// <summary>
/// Label文本属性工具
/// 示例:[LabelText("显示自定义字段", "显示自定义提示")]
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class InspectorLabelTextAttribute : PropertyAttribute
{
    /// <summary>
    /// 自定义Label文本
    /// </summary>
    public string label;
    /// <summary>
    /// 提示文本
    /// </summary>
    public string tips;

    /// <summary>
    /// 设置自定义Label文本和提示文本
    /// </summary>
    /// <param name="label"></param>
    /// <param name="tips"></param>
    public InspectorLabelTextAttribute(string label, string tips = "")
    {
        this.label = label;
        this.tips = tips;
    }
}
using UnityEditor;
using UnityEngine;

namespace LingqiuInspector.Tools
{
    /// <summary>
    /// 自定义属性绘制器,用于绘制带有LabelTextAttribute的属性字段
    /// </summary>
    [CustomPropertyDrawer(typeof(InspectorLabelTextAttribute))]
    public class LabelTextDrawer : PropertyDrawer
    {
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            InspectorLabelTextAttribute labelTextAttr = (InspectorLabelTextAttribute)attribute;

            // 使用自定义的标签文本
            GUIContent newLabel = new GUIContent(labelTextAttr.label, labelTextAttr.tips);

            // 绘制属性字段
            EditorGUI.PropertyField(position, property, newLabel);
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
        {
            return EditorGUI.GetPropertyHeight(property, label);
        }
    }
}
Logo

盛京开源社区 SJOSC 官方论坛平台

更多推荐