Scriptable Object resets randomly between scenes

I’m using several scriptable objects to store data between scenes. I’ve noticed recently that some of the data are being reset to what I put in the inspector. I don’t have any Awake, OnEnable or OnDisable methods in the scriptable objects.

It feels so random because some of the scriptable objects never reset and behave correctly. Some data persists between two scenes, but when I go to a third scene and come back, that data resets. I do not touch the data in that third scene at all.

The only methods that touch the data are a few setters / getters that I log and they do not get called.

Is there some settings/script that I’m missing to keep my scriptable object data from resetting?

I also noticed that if I have the scriptable object open in the inspector the data persists and works correct; but if I don’t have the inspector open the data resets.

I understand perfectly what did you want to achieve. You wanted to use scriptable objects assets as mutable data containers synchronized in all scenes during runtime(and in the build of course). The problem with “resets” is the following: when a scene is loading, serialized references to assets in this scene will cause instantiating of these assets as new runtime objects, and scriptable object assets are not an exception, therefore, if you have mutated data in the instantiated Asset A in scene 1, in scene 2 you often will have another instance of Asset A with all state “resetted” because its object was created from serialized “blueprint” of Asset A.


And I said “often” for a purpose.
I have tested assets behaviour when scene are loaded in editor and in builed app. It turns out, you CAN actually have the same asset (at least scriptable object) instance in different scenes. This is not happening randomly of course. If you have e reference to the Asset A in scene 1 and you are loading scene 2 where you also have a reference to the same Asset A, for some mysterious reason your asset instance “pass through” and in scene 2 you will have the same mutaded object. However, if you load some another scene without any reference to the Asset A, the instance of this asset is “disabled” and when you load again any scene with a reference to the Asset A, the new instance is created (you can see “awake” and “enable” callbacks being called).
So, in order to have your mutated instance of an asset (scriptable object asset) to be the same in all the scenes, you should provide a reference to that asset in every single scene. And this may be easily achieved by creating persistent (DoNotDestroyOnLoad) gameobject in the first scene and make it reference all assets for which you want preserved instances across all scenes.


Now, I really have no idea why this all behaves like this, and I wanted someone to explain this, and the most importantly confirm if it is a correct thing or maybe a bug? Can we actually use this “feature” in production safely? Personally I really like it, because I can make use of scriptable objects in place of singletons without any need for a static references, using Unity’s “dependency injection” via inspector.

Uhm you know that just changing values of a ScriptableObject through code does not automatically store / serialize those changes? The inspector uses the SerializedObject and SerializedProperty classes to edit the data of a ScriptableObject (or any serialized object for that matter).

When you use your mutating methods like “AddPoints”, “ResetPoints”, “AddBits”, … you just change the value of the instance in memory but the data is not serialized. Serialization only happens in the editor and only when you tell the editor to serialize the data. It’s not clear how and where you use those methods so it’s difficult to suggest the best approach.

Though if you actually work with a ScriptableObject that is stored in the project as asset, you could change your mutators to something like this:

void ForceSerialization()
{
#if UNITY_EDITOR
    UnityEditor.EditorUtility.SetDirty(this);
#endif
}

public void AddPoints(int value)
{
    points += value;
    pointsChange.Invoke(points);
    ForceSerialization();
}

Though it’s generally recommended to seperate editor code and editor functionality from runtime code.

“random” does not exist in coding. so do troubleshooting.

  • does the same thing happens when u create another scriptable object?
  • if not find what script is modifying the scriptable obj.
  • if yes there is logic linked to your obj

we could help u more if you give us the code of the relevant scripts. via pastebin.com
i hope that helped u

I had something similar happen (also seemed random, when switching scenes).

My issue was that I had mutiple classes in the same file. ScriptableObjects should be in separate files, and the filename must be the same as the name of the class. Could that be the case here?