I’m having trouble getting a scriptable object to retain data. Currently it resets on each domain reload (every time I change some code in my project and every editor restart). I have tried all the usual things (below) but nothing seems to work.
The object being inspected:
public class GameTagTree : ScriptableObject
{
[SerializeField]
GameTag root = new GameTag("root", "root", 0, null);
// Has simple add function that adds a tag to the above root as a child
}
Gametag class - simplified:
[System.Serializable]
public class GameTag : IComparable<GameTag>
{
[SerializeField] string fullName;
[SerializeField] string partName;
[SerializeField] int uid;
[SerializeField] GameTag parent;
[System.NonSerialized] List<GameTag> children;
public GameTag(string partName, string fullName, int id, GameTag parent)
{
this.partName = partName;
this.fullName = fullName;
this.uid = id;
this.parent = parent;
children = new List<GameTag>();
}
}
My current editor:
[CustomEditor(typeof(GameTagTree))]
public class GameTagTreeEditor : Editor
{
const string gameTagTreePath = "Assets/0 Main/Tags/GameTagTree.asset";
string newTagName;
GameTagTree tree;
public override void OnInspectorGUI()
{
newTagName = "some.random.tag ";
GameTagTree targetTree = (GameTagTree)target;
if (GUILayout.Button("Add tag"))
{
targetTree.AddTag(newTagName);
EditorUtility.SetDirty(targetTree);
EditorUtility.SetDirty(target);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
List<GameTag> tags = new List<GameTag>();
targetTree.GetRoot().GetChildrenRecursive(ref tags);
for (int i = 0; i < tags.Count; i++)
{
EditorGUILayout.LabelField(tags[i].Uid + " - " + tags[i].FullName);
}
}
}
From looking through documentation, I was able to fnd that AssetDatabase.SaveAssets();
definitely works (i.e. it shows that it is saving the ScriptableObject asset) but somehow on any recompilation of the editor the object just resets to default values and all added tags are gone.
I tried using AssetDatabase
to get the scriptableObject asset but this does the same as GameTagTree targetTree = (GameTagTree)target;
above.
I suspect it has something to do with using the custom class not derived from UnityEngine.Object
or nesting a list<GameTag>
- but I’ve run out of ideas on how to fix.
I tried using SerializedProperty
but didn’t have any luck because SerializedProperty
does not support objects not derived from UnityEngine.Object
.
public override void OnInspectorGUI()
{
serializedObject.Update();
SerializedProperty sp = rootProp.Copy(); // copy so we don't iterate the original
if (sp.isArray)
{
sp.Next(true); // skip generic field
sp.Next(true); // advance to array size field
// Get the array size
int arrayLength = sp.intValue;
sp.Next(true); // advance to first array index
// Write values to list
List<string> values = new List<string>(arrayLength);
for (int i = 0; i < arrayLength; i++)
{
// copy the value to the list
// Doesnt work for `GameTag`, even when using the object field in the property
values.Add(sp.stringValue);
// advance without drilling into children
if (i < arrayLength - 1) // TODO is this lastIndex thing needed?
sp.Next(false);
}
// iterate over the list displaying the contents
for (int i = 0; i < values.Count; i++)
EditorGUILayout.LabelField(i + " = " + values[i]);
serializedObject.ApplyModifiedProperties();
}
}
After running through many forums which do not seem to have the answer I’ve tried putting a minimal replication above of the problem. Any suggestions on where to look appreciated.
I realized I put this in because I kept getting an error of serialization depth going over 10, but then realized this is because I am assigning the
– Pekingchildren
var in every tag so it infinitely keeps making tag children. Took that out and too the[NonSerialized]
tag and all is well. Thank you.