Search Unity

Order of calling LoadSceneAsync vs order of scene loading completion not the same.

Discussion in 'Addressables' started by bagelbaker, Aug 29, 2019.

  1. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
    Each of our levels are composed of multiple scenes loaded additively.

    There is a main scene that does a foreach on a list of scene and calls SceneManager.LoadSceneAsync( "levelXXX", LoadSceneMode.Additive ) all during the same frame. When not using addressables, the order of when they finished loading is the same order as the order of the calls to LoadSceneAsync;

    With addressbles, we use Addressables.LoadSceneAsync("levelXXX", LoadSceneMode.Additive), again all during the same frame. But now, the loading completion is not in the same order.

    Our code depends on the scene activation order i.e. Initalization code of GameObject of scene 2 assumes that GameObject of scene 1 already exists.

    What would be the best way to resolve this?
    1) Load them one after the other instead of all at the same time: will this be less optimal?
    2) Is there a way to control the scene activation? Regardless of the order of scene loading completion, we could activate them in order that we want.
    3) Is this behavior normal by design? Now that I think about it, Is it possible that the behavior changed since v1.1.7? We've been loading our levels using addressables for some time now and only now have this issue.
     
  2. jmilsonneau

    jmilsonneau

    Joined:
    Apr 24, 2019
    Posts:
    6
    You should not expect async calls to end in the same order as they are called because they probably won't. For scenes you can start the loadsceneasync with activateonload set to false and then activate your scenes in the order you want.
     
  3. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
    Oh! I didn't see the activateOnLoad parameter in Addressables.LoadSceneAsync()

    I was looking for an equivalent to AsyncOperation.allowSceneActivation but didn't find it in AsyncOperationHandle.

    Thanks!
     
  4. nik_d

    nik_d

    Joined:
    Apr 27, 2018
    Posts:
    66
    Look at method arguments:

    Addressables.LoadSceneAsync(object key, LoadSceneMode loadMode = LoadSceneMode.Single, bool activateOnLoad = true, int priority = 100)
     
  5. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
    Unfortunately, loading multiple scenes async with allowSceneActivation to false at the same time doesn't work. The first one will load and then the other ones will stall untill the first one sets allowSceneActivation to true.
    https://docs.unity3d.com/ScriptReference/AsyncOperation-allowSceneActivation.html
    https://fogbugz.unity3d.com/default.asp?951032_bmcdlfkbtkve4lr5
    https://forum.unity.com/threads/add...d-by-async-scene-loading.670822/#post-4498021

    I tried loading them one after the other instead and while it works, it's slower than loading them all at the same time with allowSceneActivation to true. So if I want quicker loading, I guess I must adapt some of my code so that it only starts initializing when all scenes are loaded.
     
    Favo-Yang likes this.
  6. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    two comments.
    1. yes, adapting your code is probably best.
    2. we've talked with the scene team at length about changing this behavior so that you could load all with activate false. No luck unfortunately. They have some good reasons to keep it as-is, so we've got what we've got.
     
  7. arielsan

    arielsan

    Joined:
    Dec 3, 2013
    Posts:
    47
    :( this sucks a bit, we have the same problem, we have multi scenes for our levels and with the previous API (not addressables) we loaded everything sync to avoid some scenes doing stuff before some others were loaded. Now, we can't block the load with activateOnLoad because it stuck if the first scene wasn't activated.

    We will have to change our code to consider activating by hand, like deactivating all the root objects and turn them on after loading all scenes, or having a static bool to block logic or something. There is probably a workaround but it really sucks to not be able to load all scenes and then activate them when we are sure all of them are loaded.

    UPDATE: we ended up registering to SceneManager.onSceneLoaded and disable all root objects and store them in a list and after all scenes were loaded, enable them again. Not sure if the best way but it seems to work.
     
    Last edited: Sep 5, 2019
  8. bagelbaker

    bagelbaker

    Joined:
    Jun 5, 2017
    Posts:
    67
  9. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    350
    Be that as it may, the entire point of Async methods is that you cannot and should not care about the order of completion or rely on them completing their tasks in any given order. You should not expect anything to result from reporting this behavior as though it were a bug or unexpected behavior.

    In all cases where you are using multiple async functions and the results of one must be present before another can act, then you *must* wait until the required call completes before initiating the next call(s).
     
    unity_bill likes this.