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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

AsyncOperation UnloadAsync and LoadAsync .isDone never completes?

Discussion in 'Scripting' started by SamuraiMelon, Sep 3, 2020.

  1. SamuraiMelon

    SamuraiMelon

    Joined:
    Aug 26, 2020
    Posts:
    5
    Hi,

    I'm pretty new to Unity but I'm trying to make a scene transition, coping with an overall 'manager' scene that will hold all my persistent variables/preferences.

    The problem is, in the scene switching part of the script, I make the script yield until the previous scene unloads, and then the new scene loads (to make sure I can then set the new scene as the active one).

    Code (CSharp):
    1.  
    2. void Start()
    3.     {
    4.         fadeImage = gameObject.GetComponent<RawImage>();
    5.         fadeImage.enabled = true;
    6.         StartCoroutine(SwitchScenes(null, Direction.In)); /*Scene switching coroutine*/
    7.     }
    8.  
    9. private IEnumerator FadeAnimation(string Scene, Direction fadeDirection = Direction.Out)
    10. {
    11.  
    12. /*Some more code here until relevant part*/
    13.  
    14. if (Scene != null)
    15.         {
    16.             currentScene = SceneManager.GetSceneByName(Variables.Singleton.currentSceneName);
    17.             asyncUnload =  SceneManager.UnloadSceneAsync(currentScene);
    18.             while (!asyncUnload.isDone)
    19.             {
    20.                 Debug.Log("Waiting");
    21.                 yield return new WaitForSeconds(0.1f);
    22.             }
    23.             asyncLoad = SceneManager.LoadSceneAsync(Scene, LoadSceneMode.Additive);
    24.             asyncLoad.allowSceneActivation = true;
    25.  
    26.             while (!(asyncLoad.isDone))
    27.             {
    28.                 Debug.Log(asyncLoad.progress.ToString());
    29.                 yield return new WaitForSeconds(0.1f);
    30.             }
    31.  
    32.             Debug.Log("Finished Loading");
    33.             SceneManager.SetActiveScene(SceneManager.GetSceneByName(Scene));
    34.             Variables.Singleton.currentSceneName = Scene;
    35.             currentScene = SceneManager.GetSceneByName(Scene);
    36.         }
    37. yield return null;
    38. }
    39.  
    40.  
    The console only prints a single line of "Waiting" (and collapse is off), the code never seems to progress past the unloading i.e. just infinitely yields (but without printing ("Waiting") as I'd expect it to).

    Many thanks.
     
  2. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,063
    When you run a coroutine with StartCoroutine it is linked to the MonoBehaviour / GameObject that you call this on.
    If you unload the scene this MonoBehaviour you run the coroutine on will get destroyed.
    Whenever it is destroyed or disabled it will kill the coroutine.

    So either you have to run it on a monobehaviour that is on a gameobject that doesn't get destroyed on load
    or you could use the AsyncOperation.Completed event to do your handling.

    SceneManager.UnloadSceneAsync returns the AsyncOperation. Simply subscribe the Completed event and do your handling there. Same goes for LoadSceneAsync.

    https://docs.unity3d.com/ScriptReference/AsyncOperation.html
     
  3. TimBur

    TimBur

    Joined:
    Jan 17, 2013
    Posts:
    35
    Was just having this same problem, where the Coroutine was mysteriously stopping. Thanks for the insight! I didn't know that Coroutines were connected to callers in this way, and was getting super frustrated. Now that I understand the situation, all is good.