zoukankan      html  css  js  c++  java
  • Unity编辑器开发,使用CustomPropertyDrawer实现枚举中文显示

            在Unity开发中,枚举常常被用到。但是Unity自身对于枚举值,并不能做好中文的支持。无论是Head或者ToolTip.如下例:

    using UnityEngine;
    
    public class EnumTest : MonoBehaviour
    {
        public EmAniType AniType;
    }
    
    public enum EmAniType
     {
         Idle,
         Walk,
         Run,
         Atk,
         Hit,
         Die
     }

    QQ截图20170523065015

            为了将这些枚举值变成中文,这里使用了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
    }

            看看效果

    QQ截图20170523065123

    个人博客请访问:http://www.cnblogs.com/CodeGize/
  • 相关阅读:
    阿里P8架构师谈:阿里双11秒杀系统如何设计?
    秒杀系统设计的知识点
    秒杀系统架构优化思路
    秒杀系统解决方案
    Entity Framework Code First (七)空间数据类型 Spatial Data Types
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
  • 原文地址:https://www.cnblogs.com/CodeGize/p/6892299.html
Copyright © 2011-2022 走看看