在前人的基础上,整出来了一些完善一些的版本
首先,在\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>,让我挺恼火的,折腾了半天总算是解决了,因此发出来,希望以后如果有人也遇到这个问题时可以提供一点帮助。
标签:检视,name,自定义,CustomLabelAttribute,label,Inspector,property,type,string From: https://blog.csdn.net/m0_69630773/article/details/139781003