I want to see the Dictionary used by Unity on the Inspector. But I don't know if it's possible or not, and I don't know how.
Please tell me how to see the Dictionary on the inspector. Or you can tell me about other data structures similar to Dictionary in Unity.
CodePudding user response:
As suggested by @Daniel, odds are you can get away with using a Serializable
attribute on a class with your desired data structure, then store it in a List
.
However, if you insist on creating a Seraliable
dictionary, you could use SerializableDictionary<TKey, TValue>
as follows:
[System.Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
[SerializeField]
private List<TKey> keys = new();
[SerializeField]
private List<TValue> values = new();
public void OnBeforeSerialize()
{
keys.Clear();
values.Clear();
foreach (var pair in this)
{
keys.Add(pair.Key);
values.Add(pair.Value);
}
}
public void OnAfterDeserialize()
{
Clear();
if (keys.Count != values.Count)
throw new System.Exception(
$"There are {keys.Count} keys and {values.Count} values after deserialization. Make sure that both key and value types are serializable.");
for (var i = 0; i < keys.Count; i )
Add(keys[i], values[i]);
}
}
Then implement a SerializableDictionary
in your code as follows:
[SerializeField]
private SerializableDictionary<string, int> _exampleSerializableDictionary = new()
{
{"A", 10},
{"B", 20},
{"C", 30}
};
CodePudding user response:
Short answer is no, you can't serialize them.
But you have some options, I'll provide you with one.
Suppose you want to create a Dictionary<string, int>
. You can create a class/struct that holds this information:
using System;
[Serializable]
public class StringIntPair {
public string key;
public int value;
}
And then, in your code, you can create a List<StringIntPair>
, that will be visible on your inspector. This way you can set the values you want in the inspector.
Lastly, you can create a Dictionary<string, int>
and populate it in Awake
/ Start
method as you wish:
using System;
[Serializable]
public class YourClass : MonoBehaviour {
public List<StringIntPair> exposedDictionary;
Dictionary<string, int> hiddenDictionary;
void Awake(){
foreach(StringIntPair pair in exposedDictionary)
hiddenDictionary[pair.key] = pair.value;
}
}
And then you can use hiddenDictionary
in the code as you wish.