Categories

Tags

在使用Odin Inspector开发时,想要使得折叠时的面板可以显示一些有用的信息。

最终效果如下 image-center Odin插件已经提供了许多非常方便的特性,这里主要使用了Title,LableText,FoldoutGroup这三个特性

//定义枚举
public enum E_CompareType {
    [LabelText("<")]
    Less,
    [LabelText("<=")]
    LessEqual,
    [LabelText("==")]
    Equal,
    [LabelText(">")]
    Large,
    [LabelText(">=")]
    LargeEqual
}

//定义扩展
public static class CompareType_Ex {
        public static string ToGoolLook(this E_CompareType _compareType) {
            //Enum enumValue = _compareType;
            var fieldInfo = _compareType.GetType().GetField(_compareType.ToString());
            var objs = fieldInfo.GetCustomAttributes(typeof(LabelTextAttribute), true);
            //return (objs == null || objs.Length == 0) ? _compareType.ToString() : objs[0].ToString();
            return (objs == null || objs.Length == 0) ? _compareType.ToString() : ((LabelTextAttribute)objs[0]).Text;

        }
    }

定义Condition的数据结构,添加ISerializationCallbackReceiver 来响应Unity 的序列化回调

为了让Condition存储的数据可以支持多种数据类型,把数据的显示和存储分离,使用dynamic 类型来显示当前的数据,用byte[] 来存储原始数据,参考网络数据的传输

public struct Condition : ISerializationCallbackReceiver
{
       [FoldoutGroup("$TitleShow")]
       public string m_key;
       [FoldoutGroup("$TitleShow")]
       public E_CompareType m_compareType;

       [FoldoutGroup("$TitleShow")]
       [OnValueChanged("ValueTypeChange")]
       public E_ValueType m_valueType;

       [HideInInspector]
       public byte[] m_data;

       [FoldoutGroup("$TitleShow")]
       [ShowInInspector,HideLabel,InlineProperty]
       public dynamic m_vlaue;

       //显示格式
       public string TitleShow {
           get { return string.Format("{0} {1} {2}", m_key,
               m_compareType.ToGoolLook(),
               m_vlaue); }
       }

       public bool IsSatisfied(WorldState _worldState) {
            var worldData = _worldState.GetState(m_key);

            dynamic worldValue = DataCovert.ConvertFromByte(m_valueType, worldData);
            dynamic targetValue = DataCovert.ConvertFromByte(m_valueType, m_data);

            bool result = false;
            switch (m_compareType)
            {
                case E_CompareType.Less:
                    result = worldValue < targetValue;
                    break;
                case E_CompareType.LessEqual:
                    result = worldValue <= targetValue;
                    break;
                case E_CompareType.Equal:
                    result = worldValue == targetValue;
                    break;
                case E_CompareType.Large:
                    result = worldValue > targetValue;
                    break;
                case E_CompareType.LargeEqual:
                    result = worldValue >= targetValue;
                    break;
                default:
                    result = false;
                    break;
            }
            return result;
        }


#if UNITY_EDITOR

        void ValueTypeChange()
        {

            switch (m_valueType)
            {
                case E_ValueType.Int32:
                    m_vlaue = 0;
                    break;
                case E_ValueType.Boolean:
                    m_vlaue = false;
                    break;
                case E_ValueType.String:
                    m_vlaue = "";
                    break;
                case E_ValueType.Single:
                    m_vlaue = 0.0f;
                    break;
                case E_ValueType.Byte:
                    m_vlaue = (byte)0;
                    break;
                default:
                    break;
            }
            m_data = DataCovert.ConvertToByte(m_valueType, m_vlaue);
        }

        public void OnBeforeSerialize()
        {
            m_data = DataCovert.ConvertToByte(m_valueType, m_vlaue);
        }

        public void OnAfterDeserialize()
        {
            m_vlaue = DataCovert.ConvertFromByte(m_valueType, m_data);
        }
#endif
}

辅助类:帮助数据转换

public class DataCovert
    {
        public static byte[] ConvertToByte(E_ValueType _valueType, dynamic _data)
        {
            if (_data == null) {
                switch (_valueType)
                {
                    case E_ValueType.Int32:
                        _data = 0;
                        break;
                    case E_ValueType.Boolean:
                        _data = false;
                        break;
                    case E_ValueType.String:
                        _data = "";
                        break;
                    case E_ValueType.Single:
                        _data = 0.0f;
                        break;
                    case E_ValueType.Byte:
                        _data = (byte)0;
                        break;
                    default:
                        break;
                }
            }


            if (_valueType == E_ValueType.String)
            {
                return Encoding.UTF8.GetBytes(_data);
            }
            else
            {
                return BitConverter.GetBytes(_data);
            }
        }
        public static dynamic ConvertFromByte(E_ValueType _valueType, byte[] _data) {
            dynamic value;
            switch (_valueType)
            {
                case E_ValueType.Int32:
                    value = BitConverter.ToInt32(_data, 0);
                    break;
                case E_ValueType.Boolean:
                    value = BitConverter.ToBoolean(_data, 0);
                    break;
                case E_ValueType.String:
                    value = Encoding.UTF8.GetString(_data);
                    break;
                case E_ValueType.Single:
                    value = BitConverter.ToSingle(_data, 0);
                    break;
                case E_ValueType.Byte:
                    value = _data[0];
                    break;
                default:
                    value = BitConverter.ToInt32(_data, 0);
                    break;
            }
            return value;
        }

        public static dynamic Calculate(byte[] _data1 , byte[] _data2, E_ValueType _valueType, E_Operate _operate) {
            dynamic data1 = ConvertFromByte(_valueType, _data1);
            dynamic data2 = ConvertFromByte(_valueType, _data2);
            dynamic result;
            switch (_operate)
            {
                case E_Operate.Add:
                    result = data1 + data2;
                    break;
                case E_Operate.Multiply:
                    result = data1 * data2;
                    break;
                default:
                    result = null;
                    break;
            }

            return result;
        }
    }