在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 }
看看效果