- Home /
Changes to custom serializable object not saved to disk
I already asked that question on the forum (link) but I got no answer.
I created my own asset type by deriving from ScriptableObject. Because my class contains data that Unity can't serialize I implemented ISerializationCallbackReceiver as well. I do pretty much the same thing than in the example from the documentation.
It looks like this
public partial class Graph : ScriptableObject, ISerializationCallbackReceiver
{
// Data that Unity can't serialize because INode is an interface
private List<INode> mNodes;
// Data that Unity can serialize because Connection is a serializable struct
[SerializeField] [HideInInspector] private List<Connection> mConnections;
// For serialization only
[SerializeField] [HideInInspector] private List<SpecificNode> mSpecificNodes;
public void OnBeforeSerialize()
{
// Move the nodes from mNodes to mSpecificNodes so they can be serialized
mSpecificNodes.Clear();
foreach (INode node in mNodes)
{
SpecificNode specificNode = node as SpecificNode;
if (specificNode != null)
mSpecificNodes.Add(specificNode);
}
}
public void OnAfterDeserialize()
{
// Move the nodes back from mSpecificNodes to mNodes
mNodes.Clear();
foreach (SpecificNode node in mSpecificNodes)
mNodes.Add(node);
mSpecificNodes.Clear();
}
}
Serialization works perfectly. I made my own editor to edit my assets and within it I use Undo.RecordObject() to record the changes on the undo stack and that works perfectly as well.
What doesn't work is that the changes I make to my asset into the OnBeforeSerialize() method are not saved. In my example above, the content of mConnections is saved, but not the content of mSpecificNodes. That mean if I quit Unity and then open my project again, I get my connections back but no my nodes (mSpecificNodes is empty).
I tried setting my object dirty with EditorUtility.SetDirty() after I modify it but it doesn't change anything. Unity doesn't seem to notice that anything needs to be saved.
What did I miss ?
One thing that is not obvious is when the values for your collections are set on your object. If you add some Debug.Log() statements in the OnBeforeSerialization(), can you dump out whether or not the collection is null? Also, add one in your foreach() loop so that you know the objects implementing the INode interface are indeed SpecificNode objects (or at least derive from it). Unfortunately I don't see enough information to deter$$anonymous$$e what could be broken.
Serialization works fine. I thoroughly tested it. The only problem is that the changes are not saved to the disk when I quit Unity (even if I hit Ctrl+S).
In the order of things, are you first using AssetDatabase.Refresh(), followed by EditorUtility.SetDirty(theObjectLoaded) and then AssetDatabase.SaveAssets()?
Answer by Karsten · Jun 24, 2018 at 01:52 PM
An interface does not contain any data... how is SpecificNode looking like ? Can you show it ? Also , ScriptableObject(and its derivates ofc) are not meant to be changed at runtime, they are fixed data containers altered only at designtime, you could think of them like a config file wich is write protected at runtime. Serialize your things to JSON (JsonUtil) or Xml (XmlSerializer) much more intuitive
I am not trying to modify the object while in play mode, only in editor mode. I am making a graphic scripting tool, somewhat like the animator window.
The SpecificNode class is just a class implementing the INode interface and some public fields of serializable types (such as int or string). It also has the Serializable attribute.
Your answer
Follow this Question
Related Questions
Undo issues in EditorWindow 0 Answers
Why is play mode reverting my scriptableobject to a previous serialized state? 2 Answers
Is there any way to implement 'Undo' for ScriptableObject assets? 1 Answer
How to Save and Load a list of Scriptable Objects from a File? 2 Answers
Modifying and Saving Scriptable Objects: SetDirty vs. Undo 1 Answer