We currently use Addressables scenes for our projects and have noticed that list/array of ScriptableObjects are unloaded as soon as the Addressable scene is not the active scene anymore.
How to reproduce:
Game starts with Boot_Scene. This scene initializes Addressable system and loads the Splash Scene. This scene has almost no asset references, for optimization purposes.
Splash Screen scene (Adddressable) is loaded.
2.1) In Splash Screen there is ScreenController that references mutiple Screens (scriptable objects) in a List. Each screen scriptable object references an AssetReferences for the screen.
As soon as another scene is loaded (“Main Menu”, for example), ALL screen scriptable references are unloaded (and thus result in null references).
Since the ScreenController is marked as “DontDestroyOnLoad”, I don’t expect those scriptable objects to be unloaded.
Note: We created a hack to log a list with all screens, as soon as we change scenes after Splash_Screen we get an error indicating that the reference is null on the list.
A quick update to this: apparently Addressables system has serious issues when considering what assets to unload when you have an Addressable scene with objects that are set to “DontDestroyOnLoad”.
A few cases that I have noticed:
Scriptable Objects references are lost;
The scene loses references to some sprites.
For some reason there are weird rules for which assets are not unloaded. For example:
If the assets are addressables or not.
If the assets are contained in directories marked as Addressable or not.
When the directory is marked as an Addressable and the asset is also marked as an Addressable, things tend to not work well.
Prefabs references sometimes are not kept properly. E.g. some GFX that should be instanced in runtime.
I’ll post more things while I find out what’s going on and how to fix all issues.
If you load an Addressable scene and mark a Game Object as DontDestroyOnLoad, it will not be destroyed when you load another scene, as expected.
However, if this Game Object reference components with UnityEngine.Object references, most of those references will be lost except if:
You mark each of those references as an Addressable by itself. In my case I put them in the Default Local Group.
If you want, you can organize those files in directories and mark those directories as Addressables.
Be cautious though, because if you mark an “object inside that directory” as an individual addressable, it will most likely be unloaded (probably due to it effectively being marked as an Addressable twice: once due to the directory and one by itself.
I might be overreacting, but what I expected was: “If I set an object as “DontDestroyOnLoad”, don’t unload its dependencies when the parent scene is unloaded, even if those dependencies are not addressables.”
This behavior is giving us some headaches, as we assumed the established Unity behavior would be consistent over different systems.
Sounds like the usual issues that arise due to mixing non-addressable assets and addressable assets. Namely that it causes duplicated assets, which often manifests in what looks to be references breaking as you saw.
When using addressables you need to ensure all your assets are addressable. It doesn’t work to have your assets partially addressable.
During this migration to use only Addressable scenes we had a lot of trouble.
There were even builds in which the game worked well in the first section, but not on the next ones.
Currently our issue is that when loading Addressables in a local area server, it works.
When we tried a release candidate build, it stops working. It loses references to a lot of (shared) assets after loading a game from the main menu.
A few details:
Those “shared assets” are Addressables and are loaded in the Splash Scene (also an addressable). The gameObjects that reference these Addressables stay alive for the entire session (they are marked as DontDestroyOnLoad)
When we load a scene from the Main Menu, the correct assets briefly show up in the game scene and then disappear
Please note that around 28 seconds we open an activity, and when it opens the correct menu icons show up for a few frames. (sorry for the long video)
We can also notice a particle with a missing material/texture in the Menu.
To clarify, this is a sample of our scenes structure:
Boot Scene (the only non-addressable scene)
Splash scene
Main Menu scene
In-Game scenes (lots of scenes)
If needed, we are willing to share the repository to help fix those issues.
I’ll keep trying other solutions/workarounds and will let you know of any progress.
My next workaround try will be to hold a reference to AssetReferences (including some folders), load them when the game inits and keep a reference of them forever. Ugly, but it should work.
EDIT: I was using Addressables Report, but not very much. It is indeed very useful to identify Assets dependencies to other bundles or “raw assets”
EDIT: I just added a Resources.UnloadUnusedAssets() to my “Game” scene and I did not lose the Asset in the Editor Play mode, but I did in the Windows and Android build. So I think some of this might be the fact that the Editor is not garbage collecting the same way the player is. You can feel free to submit a bug as well, but I’m going to discuss around here to see if we can come up with some way to make this work better. I can definitely see how it would be frustrating to have things working in the Editor that break in the build.
The latest documentation explains about not using DontDestroyOnLoad and how to keep track of handles. That’s the correct way to do things, but I don’t think that solves the problem where it appears to be working in the Editor. We don’t want you wasting time on patterns that won’t work.
I just tried to setup something similar. I basically built a loading screen, handed off to a main menu where I marked the canvas for the UI as “DontDestroyOnLoad” then loaded the “Game” scene and my game object showed up as well as the UI with canvas. All of this using Addressables.LoadSceneAsync. It worked in Play mode, an Android build, and a Windows build.
I think this is probably something that we’d need a repro project to troubleshoot fully.
Thanks a lot for clarifying it. I have removed it from the build and it did work.
In some cases, however, I had to implement that workaround to manually load everything and keep a reference to it for the entire session.
It worked but I also had to implement another workaround to load an entire Addessable directory. I used the “load assets by label” solution for this.
In summary, the Addressables system currently has the following issues:
Resources.UnloadUnusedAssetsBehaviour works differently in the Editor than on builds. This might be the main cause for inconsistent Addressable unload behaviour in builds;
There is no efficient way to load entire “Directory asset references”, you need to use a workaround for it.
DontDestroyOnLoad does not guarantee that the resources allocated by a given gameObject are safe from unload.