Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug WaitForCompletion() crashes the game if called from animation event or physics callbacks

Discussion in 'Addressables' started by Alunze, Nov 4, 2021.

  1. Alunze

    Alunze

    Joined:
    Jun 2, 2013
    Posts:
    11
    Hello!

    Way to reproduce this:

    - Load a scene via Addressables.LoadSceneAsync() (in Additive mode, in case it matters)
    * I think Addressables.UnloadSceneAsync() might cause the issue too *
    - While it's loading in the background, use WaitForCompletion() in another asset from an animation event, physics trigger/contact callback, or OnValidate.
    - WaitForCompletion() can't complete the operation (freezing the game), producing this error constantly:

    As WaitForCompletion (regretfully) also needs to complete the previously launched scene loading/unloading, and this loading/unloading at some point needs to destroy GameObjects (probably more related to unloading), and this is not allowed during animation events or triggers/contacts, the operation can't complete and engages in an endless loop, freezing the game.

    In order to be safe, WaitForCompletion (and the underlyng code for async load/unload) should support this case too.

    Another option (probably even better) would be for WaitForCompletion() to focus on loading the asset it's been passed on and not needing to interfere in any other asynchronous task taking place in the background, but I guess that's as it is by design and out of scope :(

    Thanks for your time!
     
  2. EmilieCollard191

    EmilieCollard191

    Joined:
    May 8, 2019
    Posts:
    77
    I have the same problem. On editor it crash but on device the scene do not finish unloading.
    To avoid the bug I did this:
    Code (CSharp):
    1.  
    2. public static object SafeWaitForCompletion(this AsyncOperationHandle handle)
    3. {
    4.     if (!sceneIsUnloading) return handle.WaitForCompletion();
    5.     Debug.LogWarning($"WaitForCompletion was called when scene:{unloadingScene} was unloading");
    6.     return default;
    7. }
    8.  
    sceneIsUnloading Is set in a LoadSceneAsync function
    Like this:
    Code (CSharp):
    1.  
    2. if (Application.isEditor)
    3.     Debug.unityLogger.logEnabled = false;
    4. else
    5.     LogKeeper.Lock = true;
    6.  
    7. unloadingScene = SceneManager.GetActiveScene().name;
    8. sceneIsUnloading = true;
    9. await SceneManager.LoadSceneAsync(EMPTY_SCENE_NAME);
    10. sceneIsUnloading = false;
    11. unloadingScene = "";
    12.  
    13. if(Application.isEditor)
    14.     Debug.unityLogger.logEnabled = true;
    15. else
    16.     LogKeeper.Lock = false;
    17.  
    18. await SceneManager.LoadSceneAsync(scene);
    19.  
    Im loading an empty scene just so no Awake are called when
    sceneIsUnloading == true
     
  3. Alunze

    Alunze

    Joined:
    Jun 2, 2013
    Posts:
    11
    Hello Emilie, thanks for your response, much appreciated!

    If I understand correctly, SafeWaitForCompletion() is indeed safe, but won't always return the loaded asset. This approach can indeed be useful in some cases, but unfortunately not mine :(

    In my use case, I need WaitForCompletion() to always return the asset (that's the advertised result). I can't afford launching a fireball and have it appear one second later because a scene load operation happened to be happening at the same time (my game loads pieces of the world asynchronously so this could happen anytime). I can live with the game freezing until the scene is loaded, but not with the whole game hardlocking if the fireball was loaded from a physics callback or animation event at the wrong moment.

    Is there any official statement on this issue? At the very least it's a dangerous behaviour that should be documented (maybe it already is). But as something that can basically crash your application I think something should be done to prevent this - maybe add some checks to the code behind WaitForCompletion() so any object destruction that happens because of it is done safely?

    Thanks!
     
  4. Alunze

    Alunze

    Joined:
    Jun 2, 2013
    Posts:
    11
    I forgot to mention - the Unity version I'm testing on is 2019.4.32 (in case it helps)

    Regards!
     
  5. EmilieCollard191

    EmilieCollard191

    Joined:
    May 8, 2019
    Posts:
    77
    It not the loading that is dangerous it's the unloading of the scene. It happen when the WaitForCompletion is called in an animation event when the scene is unloading. I dont know if it append when you unload a scene that was loaded in addition mode. If it appen a work around for you could be to use event so it not called directly by the animation.