I was surprised by that.
Is it all values or just what unit knows how to serialize?
If you put logic in SO how do you deal with that? Init privates inside onenable?
The serialization rules apply to values being permanently serialized. The private fields of SOs (without SerializeField) won’t be saved to disk, will be reset when Unity is restarted and won’t make it into builds.
For UnityEngine.Objects that are not part of a scene, however, Unity will preserve private fields that it knows how to serialize. The documentation does mention this, although it’s very vague on the details of what counts as a “script”:
As mentioned, you want to add the NonSerialized attribute to private fields you don’t want to be preserved.
What this bit of the documentation omits is that it works differently for scenes. When entering/exiting play mode, Unity will reload the scene and not preserve any private fields. This e.g. means that the private fields of a MonoBehaviour on a prefab asset will be preserved – on an instance of the prefab in a scene, they won’t.
Funky! I’m sure I have bugs that come from poking at prefabs directly so I’ll start sprinkling NonSerialized. Thanks!
Yeah, this surprised the heck out of me too.
Welcome to the club.
It bit me with the typical private bool initialized; pattern and for whatever reason, my init code wouldn’t run a second time!
Definitely worth the time to inspect carefully. It can lead to some really subtle bugs.
This is exactly what was happening ![]()
How do you initialize SO that contain logic? Like I’m trying to move some of the systems that were singletons to SO, for example the Localizer. I’m thinking of doing initialization (loading) if Dictionary count is zero on each call to public method.
Oh exactly the same way… I just make sure to mark my initialized boolean with NonSerialized!
I could see using this way too, but there is some undeniably nice self-documenting-ness about bool initialized;
You’re right, .Count looked too hacky, I changed it to initialized.