在使用Odin Inspector开发时,想要使得折叠时的面板可以显示一些有用的信息。
最终效果如下
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;
}
}