Search Unity

Feedback Addressables AssetLoading is blocked by Async Scene Loading

Discussion in 'Addressables' started by DRI-Ross, May 1, 2019.

  1. DRI-Ross

    DRI-Ross

    Joined:
    Sep 24, 2018
    Posts:
    5
    Possibly a bug, definitely something that needs flagging, if only to save someone else.
    I just had a very annoying issue for the past day, which looked something like this:

    1. I had a boot scene which initialised and download some UI data as well as setting up some gameplay scenes.
    2. I used a simple coroutine to load everything in, with the scenes not allowed to activate until all the boot functions read as complete.

    However, I found this: if you have a scene in the 'is Loading' state, the Addressable LoadAsset/LoadAssets Functions are blocked until you load the scenes in.

    There is no warning or console error for this, it just appears as though the addressable system has stopped.

    Moral of the story - don't prevent scenes from loading pending addressable operations completeing - you just lock your whole system.
     
    wavs and lanpartygamesstudio like this.
  2. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    That's quite a gotcha. Have you put a bug through? It definitely does not sound like desired behaviour to me.
     
  3. DRI-Ross

    DRI-Ross

    Joined:
    Sep 24, 2018
    Posts:
    5
    Not yet, I'll need to assemble an example case so they can see the problem in action.
     
  4. DRI-Ross

    DRI-Ross

    Joined:
    Sep 24, 2018
    Posts:
    5
    Submitted a bug report and they've reproduced it, so now it's a waiting game. For now the workaround is to simply not set AsyncOperation.allowSceneActivation to false while the addressable system is active.
     
    flashframe and AlkisFortuneFish like this.
  5. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    All async operations go through the same single background loading system (PreloadManager). So if you prevent an async scene load call using this method, all other async calls in the PreloadManager that were added after it will be stuck waiting for it to finish.
     
    User414322 and flashframe like this.
  6. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
    I just ran into the issue posted here while trying to resolve this issue https://forum.unity.com/threads/ord...scene-loading-completion-not-the-same.736520/

    I want to trigger multiple Addressables.LoadSceneAsync() with allowSceneActivation to false and once they're all loaded, activate them in the order that I need. This works in Fast Mode but not in Play Packed mode nor in Builds.

    Would loading them one after another instead of in "parallel" be less efficient or is it the same? Would there be any other way to resolve this?
     
    lanpartygamesstudio likes this.
  7. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    Loading sequentially is just as efficient as they are all loaded sequentially anyways internally as there is a single background system responsible for loading data. That being said, the behavior of Addressables.LoadSceneAsync not returning the loaded results in the same order I would classify as a bug that we should fix. Please open a fogbug case with this issue for Addressables.
     
  8. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
    Our project is huge so I tried reproducing in a small repro project with Repro Project Wizard but no success so far.

    In our main project, I noticed the following, when calling
    1. addressables 1.1.5: No bug. In the Editor hierarchy, I can see all 4 scenes loaded async additive appear at once, greyed out and empty. Then they start loading in order.
    2. addressables 1.1.7 and 1.1.10: Bug. In the editor, scene 4 appears, then loads first, then scenes 2 and 3 appears greyed out, then loads, then scene 1 appears last and is loaded.
    We call Addressables.LoadSceneAsync() on the 4 scenes in the same frame in order.
    Scene 1 is in a bundle and scene 2, 3, 4 and the main scene from which we call LoadSceneAsync is in another bundle.

    I will try to have a smaller repro project and create a bug report.
     
  9. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
    Ok, while typing out the previous message and making a small repro project, I managed to find the root cause of my problem.

    When calling Addressables.LoadSceneAsync on multiple scenes in the same frame, scenes from the same bundle as the current scene will always be loaded first, then scenes from other bundles will be loaded afterwards. This is new from Addressables v1.1.7

    Detailed info in the bug report: https://fogbugz.unity3d.com/default.asp?1182127_o2mi81jj62vbad0a

    The workaround is to change the setup of our scene bundles.
     
    Last edited: Sep 5, 2019
  10. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    Hmm, I could see that being as designed as Loading a bundle is an async operation that takes place separately from Loading a scene. So when you think about it this way, internally what happens is that you trigger scene loading for 5 scenes, the first 2 are in bundles that are not already loaded so you end up with an async operation stack like this:

    LoadBundle1 (scene1)
    LoadBundle2 (scene2)
    LoadScene3
    LoadScene4
    LoadScene5

    Then once the bundles are loaded, the load scene operation gets pushed onto the stack:

    LoadScene3
    LoadScene4
    LoadScene5
    LoadScene1
    LoadScene2
     
  11. sameng

    sameng

    Joined:
    Oct 1, 2014
    Posts:
    184
    This is still an issue for me.

    I have a multi-scene setup where a level is split off into several scenes that should be loaded at once.

    I would like to load all the scenes from disk, and then activate them at once, in the order I choose.

    Here's the problem setup.

    Code (CSharp):
    1.         //asyncA should activate whenever it's ready, because activateOnLoad = true.
    2.         var asyncA = sceneA.LoadSceneAsync(LoadSceneMode.Additive, true);
    3.  
    4.         //asyncB should NOT activate whenever it's ready, because activateOnLoad = true.
    5.         var asyncB = sceneB.LoadSceneAsync(LoadSceneMode.Additive, false);
    6.  
    7.         //sceneA and sceneB should now be loading at the same time.
    8.  
    9.         //when asyncA is finished, activate async B.
    10.         asyncA.Completed += (e) => { asyncB.Task.Result.ActivateAsync(); };
    Unity's proposed solutions are

    1. Queue asynchronous loading synchronously one after another.
    This is a problem if you are loading two large scenes.
    If sceneA and sceneB take 10 seconds to load each,
    SceneA takes 10 seconds to load, then activates. Then sceneB takes 10 seconds to load, while sceneA is already activate and playing. Not ideal.

    2. Allow the scenes to race, and activate whichever gets loaded, first.
    This is bad design. This means that loading order is now random, and unreliable across platforms.

    I just want to load two scenes, and have sceneA get activated before sceneB.
    Without having sceneA active and waiting for sceneB to load from disk and activate.

    This took off days of my development time. I hope I do not come off as rude, I just feel very disappointed that I spent so much time wrestling with this ultra invisible bug and see that it's "by design" with zero signposting.
     
    Last edited: Jun 21, 2020
    ProGameDevUser likes this.
  12. flashframe

    flashframe

    Joined:
    Feb 10, 2015
    Posts:
    797
    Have to say, I didn't expect "allowSceneActivation" to stop the entire Addressables system loading assets. That really caught me out.
     
  13. sameng

    sameng

    Joined:
    Oct 1, 2014
    Posts:
    184
    This is what I really want to do:

    sceneA and sceneB are addressable scenes that each take > 30 sec to load.

    sceneA.LoadAsync();
    sceneB.LoadAsync();

    when sceneA and sceneB are both loaded from disk...

    ActivateScene(sceneA, additive);
    ActivateScene(sceneB, additive);

    any way to do this? @Ryanc_unity
     
  14. Ryanc_unity

    Ryanc_unity

    Unity Technologies

    Joined:
    Jul 22, 2015
    Posts:
    332
    @sameng off the top of my head, this would need to be a feature request for addressables as it would require package changes to add an api like that and engine changes to de-couple integration from loading so allowSceneActivation set to false doesn't pause all background loading. That second part is the change that scares me a bit.
     
  15. sinjimonkey

    sinjimonkey

    Joined:
    Jul 31, 2013
    Posts:
    72
    This has been an issue for a long time with Asset Bundles. I had a work around with those where I would have a static boolean that I set whenever I was preloading a scene, and then I would syncronously load the Asset Bundles. Since there is no Syncronized ability for Addressables, this workaround no longer works, and will be one of the main reasons why I will have to resist using Addressables in favour of my Asset Bundles implementation. I'm frequently hitting 'gotchas', with it, like again now. I'd really like to be able to use addressables, but for now the only practical way to make this work is still to have everything load into memory during an initialization scene - which works for small games, but will be impossible for larger projects.

    Is there any conceivable reason why anyone would want to block their asset bundles and addressables on load? I can't think of one. It doesn't make sense why these things are tied together.

    My main use case is to preload the scene while I get information and asset bundles from the server. I want these loaded into memory before the scene loads, so that I can populate the scene. (My current project isn't a game - I need to menu data for the current AR events going on before I can populate the main menu and the map markers.)

    This is very strongly not in keeping with what these features seem to exist for.
     
    Last edited: Aug 6, 2020
  16. Deleted User

    Deleted User

    Guest

    Hi, I'm interesting this issue.

    In my project case, scene transition time is sensitive for user experience, so that I tried to preload multiple scenes in background.
    I tried to use Addressables.LoadSceneAsync with passing false to activateOnLoad and SceneLoadMode.Additive to loadMode.
    At first, I thought it will be worked correctly, but I found out that it may not be worked correctly in some condition which depend on the order of actual loading completion.

    The order of loading completion seemed to be different by 'Play Mode Script' state in 'Addressables Group Window'.
    Build Path is specified to 'LocalBuildPath' and Load Path is specified to 'LocalLoadPath' in Asset Group Inspector.

    For instance:

    1) Play Mode Script state is 'Use AssetDatabase (fastest)' and Addressables.LoadSceneAsync is called in following order;

    Scene1
    Scene2
    Scene3

    and then, the order of loading completion (but not be called SceneInstance.ActivateAsync yet, where all PercentComplete are more than 0.9) is;

    Scene1
    Scene2
    Scene3

    This case is ok, following SceneInstance.ActivateAsync is not be blocked.

    2) Play Mode Script state is 'Simulate Group (advanced)' and Addressables.LoadSceneAsync is called in following order;

    Scene1
    Scene2
    Scene3

    and the order of actual loading completion is;

    Scene3
    Scene1
    Scene2

    Subsequently, following SceneInstance.ActivateAsync is blocked because I call SceneInstance.ActivateAsync in order of calling LoadSceneAsync but not in order of actual loading completion.

    This issue caused a complicated bug that blocking scene activation and that preventing from playing a game.

    I understood a workaround that ensuring the order of scene activation to be corresponding to the order of actual loading completion, but this approach lead to order scene activations in non-deterministic.
    In my project, the order of scene activation is important for scene transition, which assumed to be loaded with SceneLoadMode.Additive, to avoid flicker.
    With priority argument, it was no effect. (What's priority...?)
    I finally gave up to implement loading multiple scenes in background using Addressables for above reason unwillingly.

    I used Addressables ver. 1.8.4 (2019.4 verified) and ver. 1.13.1 in Unity 2019.4.8f1.
    I strongly hope that this issue will be resolved in the future release. Thanks.
     
  17. sameng

    sameng

    Joined:
    Oct 1, 2014
    Posts:
    184
    Unfortunately it looks like you just cannot load multiple scenes "at once" with addressables. You must wait for each scene to finish loading before you queue another one up. They block each other.

    I really hope this is fixed in the future.

    In my project I am sadly "queuing" up each scene and just waiting for them to load in order. It's significantly slower and messier code, but it's really the only way, otherwise you run into that race condition you are describing. Disappointing to be quite honest, as the dogmatic "async-only" addressables package must be used in a synchronous way. Worst of both worlds.
     
  18. FuriousEX

    FuriousEX

    Joined:
    Mar 13, 2014
    Posts:
    51
    I agree this behavior is unexpected, silent, inconsistent, unintuitive, poorly documented and difficult to debug. I hate losing time to tedious gotchas, and this one already hit me more than once. The use case here is extremely common (e.g. loading screen scene). Please prioritize improving the scene loading behavior - at the very least some messaging indicating the addressable system is blocked by an unactivated scene.
    If the real problem solve lies with a different department and they are not prioritizing a solution then, organizationally, you should ask: are addressables supposed to be the road forward for memory and scene management or are they just an incomplete experimental feature?
     
  19. Deleted User

    Deleted User

    Guest

    @sameng @FuriousEX Thank you for your response.
    I'd like to watch this post continuously, although I'v gave up implementing to load multiple scenes in background for reason our system's maintainability.
     
  20. sameng

    sameng

    Joined:
    Oct 1, 2014
    Posts:
    184
    With the Addressables system as of today, I give a warning to anyone who finds this thread to NOT do multi-scene loading.



    It is an incredibly common use case to want to activate two scenes at the same time.

    With Addressables, the only way is to let scenes start running--scripts will run start() awake() and maybe even do a few update() loops before the other scenes even loads. Music will start playing, etc.

    I had to edit so many scripts in my game to accommodate for this behavior. It is not fun to lose weeks of work.
    The most fun part is when you can't edit an asset or script to accommodate this behavior.

    How do you edit internal unity components?!
    Well, I ended up freezing time.timescale while scenes are loading. I am quite uncomfortable with this hacky solution.

    I will be very happy if one day async multiple scene loading is decoupled from addressables loading queue.
    Although I like many parts of the package, there are some serious gotchas. I hope one day this use case is covered.
     
  21. AlkisFortuneFish

    AlkisFortuneFish

    Joined:
    Apr 26, 2013
    Posts:
    973
    The issue is at a much lower level than addressables, it will take changes to the engine to resolve.
     
  22. popMark

    popMark

    Joined:
    Apr 14, 2013
    Posts:
    114
    Anyone come up with any cleaner solutions for this? I'm thinking as part of the addressable build pipeline I could maybe copy all the root objects from by multiscenes into a new temporary single scene, but that sounds like a big undertaking
     
  23. popMark

    popMark

    Joined:
    Apr 14, 2013
    Posts:
    114
    Got a 'solution' that fits my situation well enough.

    A PostProcessScene method disables all the active root objects in the scene as the Addressables are built, then at runtime the scenes (8 in this case) are all loaded with allowSceneAtivation=true, then once all are loaded I run through and activate all the root objects again.
     
  24. MrAkroMenToS

    MrAkroMenToS

    Joined:
    Nov 16, 2013
    Posts:
    41
    Hi @Ryanc_unity do you have an update for us on this issue? I noticed that this is still possibly the case when i tried to load multiple scenes asynchronously (and then activate them asynchronously).