Unity version: 2017.3.1f1
I'm trying to work with a HashSet
in the Unity inspector. Specifically, I need some MonoBehaviour
s to have HashSet
fields which can have their contents modified via the inspector.
To achieve this goal, I've created a concrete class that subclasses HashSet
, and uses a List
internally for (de)serialisation, in a very similar manner to the Dictionary in this guide:
However I'm encountering an issue where the list displays in the inspector, but I cannot set more than 1 value within it. If I set the size of the list to 2 or greater, it immediately is set back to 1.
In an attempt to debug the problem, I found that the OnBeforeSerialize
(and not OnAfterDeserialize
) was being executed every frame, continuously resetting the value. I'm not sure why it was setting it to 1 though.
Note that if I entered a string into the 1 available slot, it would not be reset. So this approach is currently "functional" for a HashSet
of 0 or 1 strings, but not more. Also, the outcome does not change if I use a HashSet
field instead of inheriting from it (like what was done in the above link).
Here is a minimal example:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TEST : MonoBehaviour
{
public StringHashSet test;
}
[System.Serializable]
public class SerializableHashSet<T> : HashSet<T>, ISerializationCallbackReceiver
{
public List<T> values = new List<T> ();
public void OnBeforeSerialize ()
{
values.Clear ();
foreach (T val in this) {
values.Add (val);
}
}
public void OnAfterDeserialize ()
{
this.Clear ();
foreach (T val in values) {
this.Add (val);
}
}
}
[System.Serializable]
public class StringHashSet : SerializableHashSet<string>
{
}
- How can I get this working as expected (arbitrary sized list of strings being (de)serialized to a
HashSet
)? - Also, why is
OnBeforeSerialize
being executed every frame, even if no changes are being made in the inspector?
More information
I've figured out it's because when the size of the list is changed, all the new elements in the list by default have the same value as the previous element, which will therefore all be squished to 1 value in the HashSet
.
Thus while question 2 remains from above, question 1 has evolved to ask for a workaround for this while maintaining the desired HashSet
functionality.