Search Unity

Releasing AssetReferences in ScriptableObjects

Discussion in 'Addressables' started by SagoRich, Dec 13, 2018.

  1. SagoRich

    SagoRich

    Joined:
    Jul 21, 2014
    Posts:
    15
    Are there any suggested strategies to handle releasing AssetReferences that are loaded via ScriptableObjects?

    If you have a MonoBehaviour that exposes, say, a property of type GameObject, the calling code does not need to know about where that GameObject came from, because if it was loaded via an AssetReference with LoadAsset, the MonoBehaviour can clean up (ReleaseAsset) in various ways, like in its OnDestroy method.

    If you have a ScriptableObject that exposes a similar property, and still want to abstract away where it came from, such as having the object be loaded via an AssetReference with LoadAsset, when can you call ReleaseAsset?

    ScriptableObjects have OnDisable and OnDestroy, but they are not called in any "normal" way, and are inconsistent between the player and the editor. A major benefit of ScriptableObjects is being able to serialize a reference to them, but then those instances are not treated the same way / they do not get all the messages. Even when the referring object is gone, and UnloadUnusedAssets is called, they just do not go away. This leaves non-zero reference counts, which keeps AssetBundles loaded, etc.

    Of course, we could force the calling code to do the loading, but that code could also be in a ScriptableObject too, so we are back to the same problem.

    This is more of a problem with ScriptableObjects, but it is particularly apparent when using Addressables, which is why I am hoping someone here has worked through this before.
     
  2. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    While this case is somewhat complex, in general, it should unfold similarly to any case of losing something that's holding an asset reference. Even if it's a game object, if the game object goes away, the references need to be cleaned up. If you only used Instantiate to interact with the reference, then things are cleaned up for you when the scene they are in closes. But if you use load, a release does not automatically happen.

    If the specific timing of how a SO gives you the opportunity to clean up (OnDisable or OnDestroy) you may need to add some kind of PreDestroy on the SO. You wold then have whoever is bout to unload the SO call this first. Or you could have a manager of some kind that kept up with all the SO's and references.
     
    rocky1138 and phobos2077 like this.