虽然mono是支持unicode的。可以在枚举里写中文,但是我还是觉得写英文好一些。可是在编辑器上策划是希望看到的是中文的,还有就是枚举的展示排序功能,策划在编辑的时候为了方便希望把常用的枚举排上前面。

把如下代码放到你的工程里就可以直接用了。

 
 
 

C#

 
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的不固定参数。

 
 
 

C#

 
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 就是这个类对象的结构,你可以按照你自己类的结构去拼这个字符串。

 
 
 

C#

 
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>里,这样在绘制的时候是需要遍历的。

 
 
 

C#

 
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/

Unity3D研究院之Inspector面板枚举的别名与排序的更多相关文章

  1. Unity3D研究院之Inspector视图中的get/set使用

    get set 使用起来很方便,但是编辑时在Inspector视图中问题就来了,因为get/set的属性即使是public了,但是在Inspector视图中依然不显示..谷歌一下估计就是下面这样的答案 ...

  2. Unity3d Inspector面板实现set/get访问器

    简单说一下属性和字段的区别:字段就是成员变量,而属性确实提供给外部访问内部成员变量的接口.之所以会有属性的出现,就是为了避免外部对类的成员的直接访问,通俗的说就是OOP中的封装思想. using Un ...

  3. Unity3D:Text在Inspector面板中中无法显示,需转换成UTF-8格式

    环境:Win10 读取text内容后unity报错:Input string was not in the correct format 同时在Inspector面板中无法预览Text文本内容 随后发 ...

  4. Unity3D研究院编辑器之脚本获取资源内存和硬盘大小

    内存 使用Profiler可以查看某个资源的内存占用情况,但是必须启动游戏,并且待查看的资源已经载入游戏中.我希望的是不启动游戏,也能看到它的内存好做统计. 硬盘 由于unity中的资源压缩格式记录在 ...

  5. Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条

    Unity3D研究院之异步加载游戏场景与异步加载游戏资源进度条 异步任务相信大家应该不会陌生,那么本章内容MOMO将带领大家学习Unity中的一些异步任务.在同步加载游戏场景的时候通常会使用方法 Ap ...

  6. 使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法

    使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法 效果展示 一个很简单的组件脚本 运行状态在Inspector面板可以随便修改字段和调用方法 方法调用日志 设计由来 最近在 ...

  7. Unity编辑器环境在Inspector面板中显示变量

    Serialize功能Unity3D 中提供了非常方便的功能可以帮助用户将 成员变量 在Inspector中显示,并且定义Serialize关系. 简单的说,在没有自定义Inspector的情况下所有 ...

  8. Unity3D研究院之Jenkins的使用(七十八)

    长夜漫漫无心睡眠,来一篇嘿嘿.我相信如果已经用Shell脚本完成IOS和Android打包的朋友一定需要Jenkins 怎么才能让策划打包ipa和apk?怎么才能彻底省去程序的时间,只要在同一局域网内 ...

  9. Unity3D研究院之与Android相互传递消息

    原地址:http://www.xuanyusong.com/archives/676 上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了. ...

随机推荐

  1. tableviewcell的取消选中,高亮

    1.取消多余cell的分割线 UIView *view = [UIView new]; view.backgroundColor = [UIColor clearColor]; [tableView ...

  2. stm32的软件架构问题

    1. 架构组成:程序代码分为四种结构a) 顺序执行代码定义:按照顺序逐行执行的代码优点:是思路简单,代码可靠不易被干扰.缺点:占用资源用途:只用来各种变量.函数的定义,硬件的初始化程序位置:main. ...

  3. MATLAB里的正则表达式 [转]

    正则表达式在处理字符串及文本时显得十分方便,在perl, python等脚本语言,以及java, .net等平台上都支援正则表达式.事实上,在MATLAB中也提供了正则表达式的支持.主要包含三个常用的 ...

  4. HDU 4888 (网络流)

    Poroblem Redraw Beautiful Drawings (HDU4888) 题目大意 一个n行m列的矩形,只能填0~k的数字. 给定各行各列的数字和,判定有无合法的方案数.一解给出方案, ...

  5. Google Polymer以及Web UI框架

    时代在进步,原本前端只是用来简单的数据显示以及提交数据到后端处理逻辑的地方,而随着SPA的发展,前端的逻辑也越来越是庞大,恰巧,今天看微博的时候,发现一个概念讨论的比较多,就是 Web Compone ...

  6. java学习第八天

    第九次课 目标 1.  多态 2.  抽象类 3.  接口 4.  内部类(了解) 一.多态polymorphism 追求”高内聚低耦合”通过三大特性: 封装继承及多态来实现. 多态:多种形态,”出去 ...

  7. NSFileHandle 、 沙箱机制 、 属性列表

    1 使用NSFilehandle进行数据读写 1.1 问题 NSFileManager用于实现对文件的操作,而NSFileHandle是IOS提供的对文件内容(二进制数据)进行操作的类,例如数据的读写 ...

  8. C#山寨版本【天翼拨号客户端】---内含详细抓包,模拟数据---万事俱备,只欠东风。

    官方的客户端的最大缺点: 1.一台电脑不允许使用同时启动多个网卡(目的是禁止使用虚拟WIFI或通过网卡后共享网络到路由器?): 2.使用路由器无法拨号(提示:不允许NAT后登录) 3.之前用某哥们破解 ...

  9. D - 排列

    #include<cstdio> #include<algorithm> #include<string.h> using namespace std; #defi ...

  10. 传话游戏—C++

    编程之美一道简单的热身题,也是我们生活中常玩的传话游戏.(~.~芒果台玩过的) 题意如下: Alice和Bob还有其他几位好朋友在一起玩传话游戏.这个游戏是这样进行的:首先,所有游戏者按顺序站成一排, ...