Hi!
I would like to raise some concerns I have about ScriptableObjects. I have been starting to use them a lot recently after a few talks were made highlighting their power, and they are definitely very useful. In some aspects, however, they are very inconsistent:
-The serialization of ScriptableObjects is somewhat related to the editor session: OnEnable will be called when you create the object, and when it is linked to an active scene object, or on Play if it is referenced by a scene object or another ScriptableObject, but also when you click on an object that is not actively in memory in the editor!
This is inconsistent because it means that the same method is called for initialization purpose when creating an asset or loading an asset in the editor, and during the applicationâs normal behavior when creating/enabling a ScriptableObject. Shouldnât a ScriptableObjectâs OnEnable only be called when it would actually be Enabled during play, or when marked âExecuteInEditModeâ, like for MonoBehaviours? I think this would be much clearer (the same thing goes for Awake).
-It is not possible to use a ScriptableObject as a singleton without having to place it in the resources folder: if the SO is not referenced by any scene GameObjectâs Component, it wonât be present in the build, so if I only call it from a method, this wonât work in the build. I understand where this comes from, but having the ability to mark an asset as âTo be builtâ would allow having cleaner folders.
-Last, but most importantly, the state of a ScriptableObject is not properly preserved during a Unity session. This is really inconsistent with the usual âEntering and Exiting Playâ behavior. Consider the following example:
using System;
using UnityEngine;
public class TestSOSerialization : ScriptableObject
{
private bool privateValue = false;
[NonSerialized]
private bool value = false;
void OnEnable () {
Debug.Log(value);
Debug.Log(privateValue);
value = true;
privateValue = true;
}
}
With this code, after exiting play, privateValue will be true until I close the editor. On the contrary, value will remain false. Not only this is inconsistent with the usual serialization behavior, but also this can create bugs that can be hard to track down, especially when you are getting started with SO.
I donât even understand why privateValue retains its value after Play: I understand the SO is in the memory and therefore the value is kept (although I would argue this should not be the case), but then why isnât it the same for value?
It would be great to have some explanation as of why is it this way, but I would also like to point out that this isnât exactly the cleanest behavior from my perspective: maybe this could be improved a bit?