关于Unity中字典在Inspector的显示
字典在Inspector的显示
方法一:实现ISerializationCallbackReceiver接口
《unity3D游戏开发第二版》记录
在编辑面板中可以利用序列化监听接口特性对字典进行序列化。
主要继承ISerializationCallbackReceiver接口 实现OnAfterDeserialize() OnBeforeSerialize() 的方法进行监听序列化和反序列化之前的事件。
例子:
配置的ScriptableObject脚本:
[CreateAssetMenu(fileName = "FileName2PathConfig", menuName = "xasset/Custom/FileName2PathConfig")]
public class FileName2PathConfig : ScriptableObject
{
public SerializationDic<string, string> fileDictionary;
}
// Dictionary<TKey, TValue> 可序列化字典
[Serializable]
public class SerializationDic<TKey, TValue> :ISerializationCallbackReceiver
{
[SerializeField]
List<TKey> keys;
[SerializeField]
List<TValue> values;
Dictionary<TKey, TValue> target;
public Dictionary<TKey, TValue> ToDictionary() { return target; }
public SerializationDic(Dictionary<TKey, TValue> target)
{
this.target = target;
}
public void OnBeforeSerialize()
{
keys = new List<TKey>(target.Keys);
values = new List<TValue>(target.Values);
}
public void OnAfterDeserialize()
{
var count = Math.Min(keys.Count, values.Count);
target = new Dictionary<TKey, TValue>(count);
for (var i = 0; i < count; ++i)
{
target.Add(keys[i], values[i]);
}
}
}
控制Inspector面板显示的脚本:
[CustomEditor(typeof(SerializationDic<string,string>))]
public class SerializationDicEditor : Editor
{
public override void OnInspectorGUI()
{
//更新数据
serializedObject.Update();
SerializedProperty propertyKey=serializedObject.FindProperty("keys");
SerializedProperty propertyValue=serializedObject.FindProperty("values");
int size=propertyKey.arraySize;
GUILayout.BeginVertical();
for(int i=0;i<size;i++)
{
GUILayout.BeginHorizontal();
SerializedProperty key=propertyKey.GetArrayElementAtIndex(i);
SerializedProperty value=propertyValue.GetArrayElementAtIndex(i);
key.stringValue=EditorGUILayout.TextField("key",key.stringValue);
value.stringValue=EditorGUILayout.TextField("value",value.stringValue);
GUILayout.EndHorizontal();
}
GUILayout.EndVertical();
//保存数据
serializedObject.ApplyModifiedProperties();
}
}
效果
方法二 使用插件Odin Inspector 官网
代码:
[CreateAssetMenu(fileName = "FileName2PathConfig", menuName = "xasset/Custom/FileName2PathConfig")]
public class FileName2PathConfig : SerializedScriptableObject
{
[DictionaryDrawerSettings(KeyLabel = "资源名字", ValueLabel = "资源路径")]
public Dictionary<string, string> fileDictionary;
}
效果: