- Home /
Why is play mode reverting my scriptableobject to a previous serialized state?
I have an editor script I made and I am making a change to a ScriptableObject class I created through an editor window. It has the following structure:
public class A : ScriptableObject
{
[SerializedField]
private List<B> blist;
}
Here the kind of ScriptableObject class A would refer to:
public class B : ScriptableObject
{
public int whatever;
}
I get the reference to ScriptableObject B by loading it via the AssetDatabase api and then call Undo.RecordObject on ScriptableObject A then making the change to A, then setting A dirty usign EditorUtility.SetDirty(a). Here is what that looks like:
B b_obj = (B) AssetDatabase.LoadAssetAtPath(somepath, typeof(B));
if (b_obj == null) {
return;
}
Undo.RecordObject(a, "Made some change");
a.AddB(b_obj);
EditorUtility.SetDirty(a);
This all works wonderfully when not in playmode and working in my editorwindow, the objects seem to get serialized properly because undo and redo events work perfectly but when I hit play mode, regardless of whether the ScriptableObject "a" is in the scene or not, it reverts to a previously serialized state. I know this because sometimes, seemingly at random it seems to decides to save its state and reverts to that one instead of a fresh empty one when it was created. I have no idea why this is happening as this works fine in editor and persists when I close and reopen Unity. Anyone have any ideas why this is happening?
Answer by Dankey_Kang · Aug 07, 2019 at 09:24 PM
Ok, I figured out my problem. I do not understand why this is a problem but apparently it is. One thing I did not mention is I am implementing ISerializeCallbackReciever for certain structures. The problem was that serialized arrays containing my custom class that inherit from ScriptableObject were being completely erased (except sometimes when I got lucky) between the OnBeforeSerialize and OnAfterDeserialize. Looking in debug, the serialized arrays were fine coming out of OnBeforeSerialize and not fine when they came out in OnAfterDeserialize only in play mode. The way I was initializing and assigning those arrays was that I would check in OnBeforeSerialize if they were null and I would assign them a value if they had a null reference. DON'T DO THAT. Assigning them upon initialization of the object was the correct way to do that . For some strange reason this has only happened when it came to ScriptableObjects because every other type I used this structure of assignment with has worked fine for me, so this issue appears to me to be related specifically to referencing ScriptableObjects in a serialized array or list. Sometimes, I suppose you gotta learn the hard way.
Actually this didn't work, it worked for a day then stopped working for some reason. I have no idea what is going on with this issue.
Answer by JonPQ · Aug 08, 2019 at 06:29 PM
When you make a new SCOB... make sure you create it from scratch, by right clicking on the script and selecting create instance.... DO NOT copy an existing SCOB... bad things will happen. There are sometimes links to data in the other scob... paradox, time travel etc.... just don't copy / duplicate scobs.
I am creating them through an editor script and I create making use of ScriptableObject.CreateInstance(), I don't think I have ever copied or duplicated them.