If you have empty scene, and open any ScriptableObject in inspector, than close it,
OnBeforeSerialize of this ScriptableObject will be called each time you do any code changes in your project even if it not related to this SO.
I have massive SO that represent graph with nodes. And it took 40 seconds Reload Domain each time I do any code changes in my project, because I have reference to this SO in my scene. Even if I do not have references but once opened graph SO in inspector, it start keep getting into Reload Domain no matter what.
This is a feature, not a bug.
SOs are persistent throughout the lifetime of the game.
The reason OnBeforeSerialize is called is because the entire domain is reloaded when you recompile.
What you could do is check whether the Application is running inside your OnBeforeSerialize (which would only be required inside the editor, so you could envelope this check in a #if UNITY_EDITOR so itâs not present in a build).
That would reload only when you enter PlayMode.
The problem is only about Editor mode. It is not related to Play Mode at all. Why should I wait this SO will reloaded each time my code recompiled if I only once opened it in inspector and close it. I donât have references to this SO in my scene.
Just checked, and apparently youâre not allowed to check Application.isPlaying in a OnAfterDeserialize (though you are allowed to check it in OnBeforeSerialize?).
Because the entire object is considered to be a âSerializedObjectâ. Itâs loaded as soon as you open the inspector.
The inspector window doesnât talk to the C# api to figure out what the values of the properties of whatever it is inspecting is. It asks the object to serialize itself, and then displays the serialized data. Once serialized, the SO will persist.
I test it with new clean project, simple scriptable object from documentation. How do I get reference to SO that unity load in memory when inspector was opened in order to Resources.UnloadAsset()? I donât think there is a way.
Unity re-serialises all assets assets on domain reload, which is a part of it resetting the overall âstateâ of everything. Worth noting that domain reloads do a lot more than just recompile code, which is just a very small part of the overall process.
Iâll also note that Unity serialises and deserialises assets open in the inspector every repaint too, so youâll probably be experiencing issues here.
If large serialised assets are causing issues with recompiling, I recommend saving the pure C# data as a binary asset that you access only when necessary. As Unity canât and wonât to attempt to serialise the binary asset, it wonât be a part of domain reloads. This is common practice when working with large amounts of data.
You can find all loaded instances of your object by calling Resources.FindObjectsOfTypeAll<YourScriptableObject>(), then calling Resources.UnloadAsset() on them.
EDIT: Missed the context that this was in an inspector. @SF_FrankvHoof is correct that you can use the editor target as the argument for UnloadAsset. No FindObjects call needed.
Actually you should not try to fight against major Unity features. If the serialization of your nodes is slow, you may try including a âversionâ int in your object. Whenever you actually change your nodes you would increase the version. That way you can compare it to a serialized version and only reserialize / convert your node structure to the serializable data when the version has changed. Of course the object still needs to be deserialized if itâs still loaded in memory after an assembly reload. Though you could avoid unnecessary re-serializations that way.