在检视器Inspector中通过自定义属性实现显示中文名称

在前人的基础上,整出来了一些完善一些的版本
首先,在\Scripts下创建一个类CustomLabelAttribute 

using System;
using UnityEngine;

#if UNITY_EDITOR
[AttributeUsage(AttributeTargets.Field)]
#endif

/// <summary>
/// 使字段在Inspector中显示自定义的名称。
/// </summary>
public class CustomLabelAttribute : PropertyAttribute
{
    public string name;
    /// <summary>
    /// 使字段在Inspector中显示自定义的名称。
    /// </summary>
    /// <param name="name">自定义名称</param>
    public CustomLabelAttribute(string name)
    {
        this.name= name;
    }
}

建立了一个自定义属性,具体用法为:
 

    [CustomLabel("自定义的名称")]
    private bool flag;

然后,我们在\Editor下面创建另一个类CustomLabelDrawer (具体绘制时执行用的类)

using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using System.Reflection;
using System.Text.RegularExpressions;
#endif
using System;

#if UNITY_EDITOR
    /// <summary>
    /// 定义对带有 `CustomLabelAttribute` 特性的字段的面板内容的绘制行为。
    /// </summary>
[CustomPropertyDrawer(typeof(CustomLabelAttribute))]
public class CustomLabelDrawer : PropertyDrawer{
    private GUIContent _label = null;
    private bool reProperty = true;
    private Dictionary<string, string> customEnumNames = new Dictionary<string, string>();

该类继承PropertyDrawer,在 OnGUI 方法中进行绘制

  public override void OnGUI(Rect position, SerializedProperty property, GUIContent label){

        
        reProperty = true;
        //判断是否为集合类型
        bool isElement = Regex.IsMatch(property.displayName, "Element \\d+");
        //判断是否为枚举类型
        bool isEnum = property != null && property.propertyType == SerializedPropertyType.Enum;
        if (_label == null)
        {
            GetPropertyHeight(property, label);
            string reName="";
            //绘制自定义的名称
            string name = (attribute as CustomLabelAttribute).name;
            //如果是集合,那么修改其中的前缀
            if (isElement)
            {
                //如果是枚举类型就返回“元素X”,否则返回这个元素的“name”
                //这里我不知道如何获取集合中的序号,始终会返回 0,只能等后续有人改进了
                if (isEnum) name = "元素" + property.enumValueIndex;
                else name = property.displayName;
            }
            _label = new GUIContent(name+ reName);
        }

        if (isEnum)//如果是枚举,单独绘制
        {
            DrawEnum(position, property, _label);
            reProperty = false;
        }



        if (reProperty) EditorGUI.PropertyField(position, property, _label, true);
    }

获取存在[CustomLabelAttribute(string)]中的名称并返回

如果存在一些折叠的变量(集合等)会导致布局错乱,所以我抄了一个大佬的作品来优化了一下布局的高度

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        float baseHeight = base.GetPropertyHeight(property, label);
        if (property.isExpanded)
        {
            if (property.propertyType == SerializedPropertyType.Generic)
            {
                return baseHeight + EditorGUIUtility.singleLineHeight * property.CountInProperty();
            }
        }
        return baseHeight;
    }
    //作者:MUXIGameStudio https://www.bilibili.com/read/cv9094952/

绘制枚举时有点麻烦,因此单独提取成一个方法

    private void DrawEnum(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginChangeCheck();
        Type type = fieldInfo.FieldType;
        string[] names = property.enumNames;
        string[] values = new string[names.Length];

        //这里是判断List<enum>以及其他集合类型时将type转为其中的具体类型
        while (!type.IsArray&&typeof(System.Collections.IEnumerable).IsAssignableFrom(type))
        {
            type = type.GenericTypeArguments[0];
        }

        //这里是判断enum[]时将type转为其中的具体类型
        while (type.IsArray)
        {
            type = type.GetElementType();
        }

        for (int i = 0; i < names.Length; ++i)
        {
            FieldInfo info = type.GetField(names[i]);
            var enumAttributes = (CustomLabelAttribute[])info.GetCustomAttributes(typeof(CustomLabelAttribute), false);
            values[i] = enumAttributes.Length == 0 ? names[i] : enumAttributes[0].name;//+" "+ i;

        }

        int index = EditorGUI.Popup(position, label.text, property.enumValueIndex, values);
        if (EditorGUI.EndChangeCheck() && index != -1)
        {
            property.enumValueIndex = index;
        }
    }

之前的代码是只能判断emum[],而不能判断List<enum>,让我挺恼火的,折腾了半天总算是解决了,因此发出来,希望以后如果有人也遇到这个问题时可以提供一点帮助。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值