在Unity开发中,枚举常常被用到。但是Unity自身对于枚举值,并不能做好中文的支持。无论是Head或者ToolTip.如下例:
using UnityEngine; public class EnumTest : MonoBehaviour { public EmAniType AniType; } public enum EmAniType { Idle, Walk, Run, Atk, Hit, Die }
为了将这些枚举值变成中文,这里使用了CustomPropertyDrawer(https://docs.unity3d.com/ScriptReference/CustomPropertyDrawer.html)。
第一步,定义一个Unity属性标签PropertyAttribute。
using UnityEngine; public class EnumLabelAttribute : HeaderAttribute { public EnumLabelAttribute(string header) : base(header) { } }
这里没有继承PropertyAttribute,而是HeaderAttribute。原因是HeaderAttribute继承PropertyAttribute,而我想用到HeaderAttribute的header字段。当然我们也可以完全继承PropertyAttribute。
第二步,使用CustomPropertyDrawer。在Editor文件夹下创建一个脚本EnumLabelDrawer.cs。EnumLabelDrawer继承PropertyDrawer,并加上CustomPropertyDrawer标签。在复写OnGUI方法,通过C#的反射,获取到枚举中枚举值上的Head标签属性数据。最终将这些属性中的中文说明展示出来。
using System.Collections.Generic; using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(EnumLabelAttribute))] public class EnumLabelDrawer : PropertyDrawer { private readonly List<string> m_displayNames = new List<string>(); public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { var att = (EnumLabelAttribute)attribute; var type = property.serializedObject.targetObject.GetType(); var field = type.GetField(property.name); var enumtype = field.FieldType; foreach (var enumName in property.enumNames) { var enumfield = enumtype.GetField(enumName); var hds = enumfield.GetCustomAttributes(typeof(HeaderAttribute), false); m_displayNames.Add(hds.Length <= 0 ? enumName : ((HeaderAttribute)hds[0]).header); } EditorGUI.BeginChangeCheck(); var value = EditorGUI.Popup(position, att.header, property.enumValueIndex, m_displayNames.ToArray()); if (EditorGUI.EndChangeCheck()) { property.enumValueIndex = value; } } }
第三步,更改原有的枚举和脚本字段。在枚举值上加上Header标签,在脚本的字段上增加EnumLabel标签。
using UnityEngine; public class EnumTest : MonoBehaviour { [EnumLabel("动画类型")] public EmAniType AniType; } public enum EmAniType { [Header("待机")] Idle, [Header("走")] Walk, [Header("跑")] Run, [Header("攻击")] Atk, [Header("受击")] Hit, [Header("死亡")] Die }
看看效果