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

LoadSceneAsync is the same as LoadScene?

Discussion in 'Scripting' started by Warrior1424, Oct 22, 2016.

  1. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    So SceneManager.LoadScene is supposed to load a scene instantly right?
    It just freezes the game until the scene is loaded?

    But SceneManager.LoadSceneAsync is supposed to load it in the background right?
    So if you wanted to load in the next level seamlessly this would be the way to go?

    In my game, using LoadSceneAsync causes the game to freeze until the level is loaded in (even in the built game). Is there anyway to spread this load out at all?
    There's this command:
    Code (CSharp):
    1. Application.backgroundLoadingPriority = ThreadPriority.BelowNormal;
    But it only seems to work on the now obsolete: Application.LoadLevelAsync

    Am I just using SceneManager.LoadSceneAsync wrong? Here's a sample of my code:

    Code (CSharp):
    1. AsyncOperation loadingScene = SceneManager.LoadSceneAsync(nextScene, LoadSceneMode.Additive);
    2.             while (!loadingScene.isDone)
    3.                 yield return null;
    4. //do stuff
     
  2. Rotavele

    Rotavele

    Joined:
    Jan 28, 2016
    Posts:
    29
    From my (admittedly small amount of) understanding on Asynchronous Operations: this should still work on the new LoadLevelAsync.

    Also are you sure it's freezing for the whole loading time, or at a certain point in progress as it could it be another issue/bug?
     
  3. Warrior1424

    Warrior1424

    Joined:
    Sep 30, 2010
    Posts:
    984
    I tried it and it didn't appear to make any noticeable difference, even in a built game.

    I can tell its freezing for the whole time because in the editor (which I know loads slower than a built game, but it still should load in the background) the game freezes for like 1.5 seconds then freezes for 15 seconds as the level is loading in (you can see it grayed out in the Hierarchy). I also don't know what could be causing freezing but only for a few frames that isn't related to the level loading in.
     
  4. DonLoquacious

    DonLoquacious

    Joined:
    Feb 24, 2013
    Posts:
    1,667
    Async operations are still done on the main thread, and while they break things up in the smallest possible chunks for loading, there are some things that they can't break up. Application.backgroundLoadingPriority can only have an effect in situations where the chunks are small enough to be under that limit, but in the situations where people tend to find themselves with the main thread blocked by the load operation, it's usually beyond its ability to make a big difference.

    ... or maybe it just doesn't work on LoadSceneAsync, as you've suggested- I don't know for sure, but I don't think it would make a difference anyways.

    Use the performance profiler to really get a good look at what's going on- yeah, it's the load operation, but which part of it? Throw in a unique random number generated a the start of coroutine and print it to make sure the action isn't being called twice for whatever reason, print the time that the operation starts, print the time when it ends, and make an integer variable that increments on each yield and then print that out when it ends too so you have a clear "X frames over Y seconds" value to look at, if you find the profiler hard to read.

    Maybe you want to set the allowSceneActivation of the AsyncOperation to false to see if it's specifically the loading or the activating that's causing problems. All of that said, it's perfectly possible that this is running entirely as intended and the async operation just can't break certain parts down into smaller chunks, like for high-poly models. You can't really "load" things on separate threads, since Unity isn't thread-safe, but if the blocking is being caused by the startup routines for each of the new components, you can offset some of that processing to other threads if needed.
     
    Jugibur likes this.
  5. everygamer

    everygamer

    Joined:
    Jan 15, 2012
    Posts:
    3
    I'm not sure if things have changed since 2016, but for the purpose of helping others, looking over the documentation for LoadSceneAsync recommends using a Coroutine to load the scene in the background. The step of calling it via a coroutine might be what launches a separate thread so that it doesn't impact the main thread.

    https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadSceneAsync.html

    Code (CSharp):
    1.  
    2.  
    3. void Update()
    4.     {
    5.         // Press the space key to start coroutine
    6.         if (Input.GetKeyDown(KeyCode.Space))
    7.         {
    8.             // Use a coroutine to load the Scene in the background
    9.             StartCoroutine(LoadYourAsyncScene());
    10.         }
    11.     }
    12.  
    13.     IEnumerator LoadYourAsyncScene()
    14.     {
    15.         // The Application loads the Scene in the background as the current Scene runs.
    16.         // This is particularly good for creating loading screens.
    17.         // You could also load the Scene by using sceneBuildIndex. In this case Scene2 has
    18.         // a sceneBuildIndex of 1 as shown in Build Settings.
    19.  
    20.         AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("Scene2");
    21.  
    22.         // Wait until the asynchronous scene fully loads
    23.         while (!asyncLoad.isDone)
    24.         {
    25.             yield return null;
    26.         }
    27.     }
    28.  
    The original poster might have been doing this but just didn't include all the code to see it, not sure. Plus, I don't know if Unity used this mechanic back then, but hopefully this helps someone these days.
     
  6. everygamer

    everygamer

    Joined:
    Jan 15, 2012
    Posts:
    3
    Then again, after reading the docs for StartCoroutine its not starting a new thread. It's still operating in the main thread, but it is checking the yeild status each frame until it returns, then it takes back over. So technically the Coroutine should allow the rest of the application to run while its processing load scene until the yield returns and then switch you to the new scene. So I'm now just not sure if the original poster was using a coroutine at the time to call LoadSceneAsync because it wasn't included in the code they posted.