Search Unity

Async loading

Discussion in 'Scripting' started by Vedrit, Mar 28, 2017.

  1. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    So, let me start off by saying that I don't really understand the mechanics behind SceneManager.LoadSceneAsync, only that it seems to work well for a loading screen.
    See, in my project, every tree, rock and all but a handful of cities are spawned by the server, and sent to the client to be spawned when they connect. This means at least 2000 objects that need to be instantiated and run their own attached scripts.
    As it is, those object get created, 5-10 objects per frame, after the character has been spawned and can be controlled. This means that the player gets exposed to framerates of 30fps and lower. Obviously, this is not ideal.
    I do have a loading screen, using the following script to transition
    Code (csharp):
    1. IEnumerator changeScreenByName(string name)
    2.     {
    3.         yield return new WaitForSeconds(1);
    4.         async = SceneManager.LoadSceneAsync(name);
    5.         async.allowSceneActivation = true;
    6.         while (!async.isDone)
    7.         {
    8.             if (async.progress > 0.8f)
    9.             {
    10.                 async.allowSceneActivation = true;
    11.             }
    12.             yield return null;
    13.         }
    14.     }
    I don't know how I'd be able to spawn the objects during this loading scene, into the new scene that is about to be activated, without them being removed when the loading scene objects are destroyed.

    Any suggestions would be greatly appreciated.
     
  2. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    Have you tried using additive mode for LoadSceneAsync and explictly destroying the loading screen yourself?
     
  3. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    You use an event call to control when to activate the scene.

    You'd have that coroutine listen to a static event and set allow scene activation to false. then in the scene some GameObject with a LoadManager Script loads in objects via Awake (which should fire even the scene is not activated as long as the GameObject itself is spawned enabled) once the load manager finishes instantiating objects it invokes that static event, at which point the listening Coroutine can set allowSceneActivation to true.
     
  4. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    So, something along the lines of this? And objects I instantiate during this loading scene will not be removed upon scene activation?
    Code (csharp):
    1.  
    2. IEnumerator changeScreenByName(string name)
    3.     {
    4.         yield return new WaitForSeconds(1);
    5.         async = SceneManager.LoadSceneAsync(name);
    6.         async.allowSceneActivation = true;
    7.         while (!async.isDone)
    8.         {
    9.             if (async.progress > 0.8f && objectLoader.finished)
    10.             {
    11.                 async.allowSceneActivation = true;
    12.             }
    13.             yield return null;
    14.         }
    15.     }
     
  5. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Am I on the right track of thinking with this?
     
  6. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    That'll basically work, depending on how you are accessing the objectLoader instance. not sure how you are accessing that instance which is why I mentioned static events.

    as long as you're instantiating them into the new scene and not the "DontDestroyOnLoad" scene or whichever sub-scene is running that coroutine.

    Scene activation basically takes those objects out of stasis (they're created, but things like Update(), physics, audio, etc. won't run until the scene activates), it has nothing to do with removing them (unless you have code that would remove them)
     
    Last edited: Mar 30, 2017
    Vedrit likes this.
  7. Vedrit

    Vedrit

    Joined:
    Feb 8, 2013
    Posts:
    514
    Oh, I get it. The object running the instantiation needs to be in the new scene.
    Thanks!