Unity3D研究院之Inspector面板枚举的别名与排序
虽然mono是支持unicode的。可以在枚举里写中文,但是我还是觉得写英文好一些。可是在编辑器上策划是希望看到的是中文的,还有就是枚举的展示排序功能,策划在编辑的时候为了方便希望把常用的枚举排上前面。
把如下代码放到你的工程里就可以直接用了。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | using UnityEngine; using System; #if UNITY_EDITOR using UnityEditor; using System.Collections.Generic; using System.Linq; using System.Reflection; #endif  [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field)] public class EnumLabelAttribute : PropertyAttribute {     public string label;     public int[] order = new int[0] ;     public EnumLabelAttribute(string label)     {         this.label = label;     }     public EnumLabelAttribute(string label,params int[] order)     {         this.label = label;         this.order = order;     } } #if UNITY_EDITOR [CustomPropertyDrawer(typeof(EnumLabelAttribute))] public class EnumLabelDrawer : PropertyDrawer {     private Dictionary<string, string> customEnumNames = new Dictionary<string, string>();     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)     {         SetUpCustomEnumNames(property, property.enumNames);         if (property.propertyType == SerializedPropertyType.Enum)         {             EditorGUI.BeginChangeCheck();             string[] displayedOptions = property.enumNames                     .Where(enumName => customEnumNames.ContainsKey(enumName))                     .Select<string, string>(enumName => customEnumNames[enumName])                     .ToArray();             int[] indexArray = GetIndexArray (enumLabelAttribute.order);             if(indexArray.Length != displayedOptions.Length)             {                 indexArray = new int[displayedOptions.Length];                 for(int i =0; i< indexArray.Length; i++){                     indexArray[i] = i;                 }             }             string[] items = new string[displayedOptions.Length];             items[0] = displayedOptions[0];                    for (int i=0; i<displayedOptions.Length; i++) {                 items[i] =  displayedOptions[indexArray[i]];             }             int index = -1;             for (int i=0; i<indexArray.Length; i++) {                 if (indexArray[i] == property.enumValueIndex) {                     index = i;                     break;                 }             }             if ( (index == -1) && (property.enumValueIndex != -1) ) { SortingError (position,property,label); return; }             index = EditorGUI.Popup(position, enumLabelAttribute.label,index, items);             if (EditorGUI.EndChangeCheck())             {                 if (index >= 0)                     property.enumValueIndex = indexArray[index];             }         }     }     private EnumLabelAttribute enumLabelAttribute     {         get         {             return (EnumLabelAttribute)attribute;         }     }     public void SetUpCustomEnumNames(SerializedProperty property, string[] enumNames)     {             object[] customAttributes = fieldInfo.GetCustomAttributes(typeof(EnumLabelAttribute), false);             foreach (EnumLabelAttribute customAttribute in customAttributes)             {                 Type enumType = fieldInfo.FieldType;                 foreach (string enumName in enumNames)                 {                     FieldInfo field = enumType.GetField(enumName);                     if (field == null) continue;                     EnumLabelAttribute[] attrs = (EnumLabelAttribute[])field.GetCustomAttributes(customAttribute.GetType(), false);                     if (!customEnumNames.ContainsKey(enumName))                     {                         foreach (EnumLabelAttribute labelAttribute in attrs)                         {                             customEnumNames.Add(enumName, labelAttribute.label);                         }                     }                 }             }     }     int[] GetIndexArray (int[] order)     {         int[] indexArray = new int[order.Length];         for (int i = 0; i < order.Length; i++) {             int index = 0;             for (int j = 0; j < order.Length; j++) {                                 if (order[i] > order[j]) {                                       index++;                                 }                            }             indexArray[i] = index;         }         return (indexArray);     }     void SortingError (Rect position, SerializedProperty property, GUIContent label)     {         EditorGUI.PropertyField(position, property, new GUIContent(label.text + " (sorting error)"));         EditorGUI.EndProperty();     } } public class EnumLabel {     static public object GetEnum(Type type, SerializedObject serializedObject, string path)     {         SerializedProperty property =  GetPropety(serializedObject,path);         return  System.Enum.GetValues(type).GetValue(property.enumValueIndex);     }     static public object DrawEnum(Type type, SerializedObject serializedObject, string path)     {         return DrawEnum(type,serializedObject, GetPropety(serializedObject,path));     }     static public object DrawEnum(Type type, SerializedObject serializedObject,SerializedProperty property)     {         serializedObject.Update();         EditorGUILayout.PropertyField(property);         serializedObject.ApplyModifiedProperties();         return  System.Enum.GetValues(type).GetValue(property.enumValueIndex);     }     static public SerializedProperty GetPropety(SerializedObject serializedObject, string path)     {         string []contents = path.Split('/');         SerializedProperty property =  serializedObject.FindProperty(contents[0]);         for(int i=1; i< contents.Length; i++){             property = property.FindPropertyRelative(contents[i]);         }         return property;     } } #endif | 
使用是这样的,第二个参数就是排序。接收int的不固定参数。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour {     [EnumLabel("我是的类型",10,1,5,2)]     public NewType newType = NewType.One; } public enum NewType : byte {     [EnumLabel("我是1")]     One = 10,     [EnumLabel("我是2")]     Two = 1,     [EnumLabel("我是3")]     Three = 5,     [EnumLabel("我是4")]     Four = 2 } | 
OK 中文与排序都OK了。
但是,有时候我们做编辑器的时候是自己调用OnInspectorGUI来绘制面板的。而且我的枚举对象可能会在另外一个子对象里,或者在子对象里的一个List<T>里面的子对象里。
比如这样, class.data.newType 就是这个类对象的结构,你可以按照你自己类的结构去拼这个字符串。
| 1 2 3 4 5 6 7 8 9 10 |         public override void OnInspectorGU()         {             NewType oldType = (NewType)EnumLabel.GetEnum(typeof(NewType),serializedObject,"class/data/newType");             NewType newType = (NewType)EnumLabel.DrawEnum(typeof(NewType),serializedObject,"class/data/newType");             if(oldType != newType)             {                 //类型发生改变             }         } | 
还有一种特殊的就是可能枚举在list<T>里,这样在绘制的时候是需要遍历的。
| 1 2 3 4 5 6 7 8 9 10 |        public override void OnInspectorGU()         {             SerializedProperty property = EnumLabel.GetPropety(serializedObject,"class/datas");             for(int i =0; i<  count; i++)             {                 SerializedProperty eProperty = property.GetArrayElementAtIndex(i);                 NewType newType = (NewType)EnumLabel.DrawEnum(typeof(NewType),serializedObject                             ,eProperty.FindPropertyRelative("newType"));             }         } | 
OK大功告成。
参考文章:
https://github.com/anchan828/property-drawer-collection/blob/master/EnumLabel/EnumLabelAttribute.cs
http://forum.unity3d.com/threads/enum-inspector-sorting-attribute.357558/
- 本文固定链接: http://www.xuanyusong.com/archives/4213
- 转载请注明: 雨松MOMO 2016年07月13日 于 雨松MOMO程序研究院 发表
    失败是什么?没有什么,只是更走近成功一步;成功是什么?就是走过了所有通向失败的路,只剩下一条路,那就是成功的路。
 
                    
                
 
                
            
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号