Search Unity

SceneManagement.LoadLevelAsync goes straight to 90%?

Discussion in 'Scripting' started by GladGoblinGames, Dec 20, 2015.

  1. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Hi guys,

    Not sure if its just because my scene probably isn't as detailed as some, so it may be quick to load. However, I've done a loading script...rough version. No matter what I change, the async.progress goes straight from 0% to 90% then freezes, then loads the level.

    Here is the script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.SceneManagement;
    4.  
    5. public class LoadingScreen : MonoBehaviour {
    6.  
    7.     AsyncOperation async;
    8.     LoadingSceneManager loadingSceneManger;
    9.     public Texture backgroundTexture;
    10.  
    11.     // Use this for initialization
    12.     void Start () {
    13.         loadingSceneManger = new LoadingSceneManager();
    14.         loadingSceneManger.ReturnLevelName = "demo_night";
    15.         StartCoroutine(LoadLevelName());
    16.     }
    17.    
    18.     // Update is called once per frame
    19.     void Update () {
    20.         Debug.Log(async.progress * 100);
    21.     }
    22.  
    23.     IEnumerator LoadLevelName()
    24.     {
    25.         async = SceneManager.LoadSceneAsync(loadingSceneManger.ReturnLevelName);
    26.         yield return null;
    27.     }
    28.  
    29.     void OnGUI()
    30.     {
    31.         Debug.Log("On GUI has been called");
    32.         GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), backgroundTexture, ScaleMode.ScaleToFit);
    33.         GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 100, 100), "Loading..." + (async.progress * 100).ToString("F0") + "%");
    34.      
    35.     }
    36. }
    Have I done something wrong? Or am I missing something?
     
    Filip8429 likes this.
  2. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Just a little update...

    I tried adding this to the Update() function to see if it even went to 50%...apparently, it does not :/ it just goes straight from 0 to 0.9f without anything in between.

    Code (CSharp):
    1.         if(async.progress == 0.5f)
    2.         {
    3.             Debug.Break();
    4.         }
    NEW UPDATE:

    Okay, so I have no idea why the hell its started working kinda...my script hasn't changed. Basically, my Unity crashed, re-opened, and now the loading text works fine? Still freezes at 90% though.

    This is the script I am now using, you can see nothing has changed...

    Not sure if this is a Unity5 Bug or something?

    Code (CSharp):
    1. /* LoadingScreen.cs - Versionf0.1
    2.      
    3.             ** Change Log **
    4.  
    5. - First creating of script 20/12/2015
    6.  
    7.             ** Bugs **
    8.  
    9. - Loading text jumps straight from 0% to 90%
    10.  
    11. */
    12.  
    13. using UnityEngine;
    14. using System.Collections;
    15. using UnityEngine.SceneManagement;
    16.  
    17. public class LoadingScreen : MonoBehaviour {
    18.  
    19.     AsyncOperation async = null;
    20.  
    21.     LoadingSceneManager loadingSceneManger;
    22.     public Texture backgroundTexture;
    23.  
    24.     // Use this for initialization
    25.     void Start () {
    26.         loadingSceneManger = new LoadingSceneManager();
    27.         loadingSceneManger.GetSetLevelName = "demo_night";
    28.         StartCoroutine(LoadLevelName());
    29.     }
    30.  
    31.     // Update is called once per frame
    32.     void Update () {
    33.         Debug.Log(async.progress * 100);
    34.     }
    35.  
    36.     private IEnumerator LoadLevelName()
    37.     {
    38.         async = SceneManager.LoadSceneAsync(loadingSceneManger.GetSetLevelName, LoadSceneMode.Single);
    39.         yield return null;
    40.     }
    41.  
    42.     void OnGUI()
    43.     {
    44.         GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), backgroundTexture, ScaleMode.ScaleToFit);
    45.         GUI.Label(new Rect(Screen.width / 2, Screen.height / 2, 100, 100), "Loading..." + (async.progress * 100).ToString("F0") + "%");
    46.     }
    47. }
    48.  
    UPDATE:

    Sorry, guys. Its gone back to how it was before after simply changing the background texture. Makes no sense, right? I've no idea what's going on. It now no longer displays numbers between 0% and 90%
     
    Last edited: Dec 20, 2015
  3. mikeymike

    mikeymike

    Joined:
    Oct 21, 2014
    Posts:
    35
    try adding this line somewhere in the coroutine
    Code (csharp):
    1.  
    2. async.allowSceneActivation=true;
    3.  
     
  4. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Already tried, I've tried doing the while statement, the scene activation's, if statements, the whole shabang. Nothing seems to work
     
  5. mikeymike

    mikeymike

    Joined:
    Oct 21, 2014
    Posts:
    35
    is the scene youre trying to load definitely in the build settings for your game? if not add it. otherwise you could try loading the scene by its build index value or its string. SceneManager.LoadSceneAsync(1); or SceneManager.LoadSceneAsync("YOURLEVELNAME"); see if that works.
     
  6. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    I use something like this:
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class LoadAsync : MonoBehaviour
    6. {
    7.     private string loadProgress = "Loading...";
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         StartCoroutine(LoadRoutine());
    12.     }
    13.  
    14.     private string lastLoadProgress = null;
    15.     private IEnumerator LoadRoutine()
    16.     {
    17.         AsyncOperation op = Application.LoadLevelAsync(1);
    18.         op.allowSceneActivation = false;
    19.         while (!op.isDone)
    20.         {
    21.             if (op.progress < 0.9f)
    22.             {
    23.                 loadProgress = "Loading: " + (op.progress * 100f).ToString("F0") + "%";
    24.             }
    25.             else // if progress >= 0.9f the scene is loaded and is ready to activate.
    26.             {
    27.                 if (Input.anyKeyDown)
    28.                 {
    29.                     op.allowSceneActivation = true;
    30.                 }
    31.                 loadProgress = "Loading ready for activation, Press any key to continue";
    32.             }
    33.             if (lastLoadProgress != loadProgress) { lastLoadProgress = loadProgress; Debug.Log(loadProgress); } // Don't spam console.
    34.             yield return null;
    35.         }
    36.         loadProgress = "Load complete.";
    37.         Debug.Log(loadProgress);
    38.     }
    39. }
    40.  
    Note I'm using the old Application api as I haven't upgraded yet.
    Should be pretty much interchangeable with the new scenemanager api.
    This waits until progress is 0.9f (which strangely enough is when the loading is as done as it can be) then lets you press any key to actually load next scene. Also prints debugs everytime something changes.
    Note that the last debug probably won't happen as the object containing this code gets destroyed, and so does the coroutine.

    More on the issue:
    The things you describe seems in line with how it's been all the time. If it goes from 0 to 0.9 directly it is probably because your scene is so small and has very little for unity to load.
    Not though, that Start / Awake and such in the new scene is not called asynchronously. So if you have lots of code and generation stuff going on in the new scene, this is what will cause a hickup between 0.9f and when you see the scene loaded.
     
  7. mikeymike

    mikeymike

    Joined:
    Oct 21, 2014
    Posts:
    35
    why dont you just upgrade that code from @ThermalFusion, just tried it seems to be working fine for me


    Code (csharp):
    1.  
    2. using UnityEngine.SceneManagement;
    3.  
    4. public class test : MonoBehaviour {
    5.  
    6.    private string loadProgress = "Loading...";
    7.    // Use this for initialization
    8.    void Start ()
    9.    {
    10.      StartCoroutine(LoadRoutine());
    11.    }
    12.  
    13.    private string lastLoadProgress = null;
    14.    private IEnumerator LoadRoutine()
    15.    {
    16.      AsyncOperation op = SceneManager.LoadSceneAsync (1);
    17.      op.allowSceneActivation = false;
    18.      while (!op.isDone)
    19.      {
    20.        if (op.progress < 0.9f)
    21.        {
    22.          loadProgress = "Loading: " + (op.progress * 100f).ToString("F0") + "%";
    23.        }
    24.        else // if progress >= 0.9f the scene is loaded and is ready to activate.
    25.        {
    26.          if (Input.anyKeyDown)
    27.          {
    28.            op.allowSceneActivation = true;
    29.          }
    30.          loadProgress = "Loading ready for activation, Press any key to continue";
    31.        }
    32.        if (lastLoadProgress != loadProgress) { lastLoadProgress = loadProgress; Debug.Log(loadProgress); } // Don't spam console.
    33.        yield return null;
    34.      }
    35.      loadProgress = "Load complete.";
    36.      Debug.Log(loadProgress);
    37.    }
    38. }
    39.  
    40.  
     
  8. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Thanks for the help. I did wonder if my scene was too small for it to have anything detailed enough to load. I will try this code now and see what happens :)
     
  9. GladGoblinGames

    GladGoblinGames

    Joined:
    Dec 14, 2011
    Posts:
    118
    Well, its working. So far there hasn't been a jump from 0 - 0.9f yet, but if it happens again I'll let you know. After pressing any key to continue, it does seem to take about an extra 1 or 2 seconds to enter the scene. But as @ThermalFusion said, I will play around with my code in the next scene in Start and Awake functions to see if that solves the problem :D

    UPDATE: Well, I got no idea what's going on. The moment I tried out this code, it showed all numbers between 0 and .9f. However, after a couple of runs in the editor, its gone back to jumping again. Question, my scene has a fairly detailed block of flats with furniture objects all over the place. Out of curiosity, could that be the reason for the 1 - 2 second delay after hitting any key? Also, would this block of flats with furniture objects make the loading time slower? I thought it would have done xD
     
    Last edited: Dec 21, 2015
  10. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    It really depends. Perhaps you can use the profiler to find out exactly. You should also measure in an actual build rather than in editor. Id say large textures are what takes longest to load. if you have lots of those, it should take a little longer.
     
  11. kosted

    kosted

    Joined:
    Mar 14, 2015
    Posts:
    104
    Hi, I'm facing the same problem when i run on android. Is it possible to swith directly (keeping of course the system of op.allowSceneActivation) without asking the player to press any key ?
     
  12. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    If you want to wait for something else just replace the Input.anyKey statement with your own logic. If you dont want to wait, just leave the allow scene activation as true
     
  13. kosted

    kosted

    Joined:
    Mar 14, 2015
    Posts:
    104
    ok, thanks. I'm gonna try this
     
  14. kosted

    kosted

    Joined:
    Mar 14, 2015
    Posts:
    104
    Everything works fine when want to go from my scene "regles" to my Main Menu. But when I want to go back to the scene "regles" the game stops during 40 seconds (on mobile), then load the scene.
    In Unity I have when I go from scene Menu to regle :
    regle.PNG

    and when I back to menu I have this :

    menu.PNG

    My code :
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4. using UnityEngine.SceneManagement;
    5. using System;
    6.  
    7. public class LoadLevel : MonoBehaviour {
    8.  
    9.     public GameObject LoadingScene;
    10.     public Image LoadingBar;
    11.     public Text textPourcentage; //The text with the percentage increasing
    12.     private String nomScene;
    13.     private Boolean estActive = false;
    14.  
    15.     public void ChargementScene(String nom)
    16.     {
    17.         nomScene = nom;
    18.         estActive = true;
    19.     }
    20.  
    21.     void Update()
    22.     {
    23.         if (estActive)
    24.         {
    25.             StartCoroutine(LevelCoroutine(nomScene));
    26.  
    27.         }
    28.     }
    29.  
    30.     IEnumerator LevelCoroutine(System.String nomScene)
    31.     {
    32.    
    33.         LoadingScene.SetActive (true);  
    34.         AsyncOperation async = SceneManager.LoadSceneAsync(nomScene);
    35.  
    36.         async.allowSceneActivation = false;
    37.  
    38.         while (!async.isDone) {
    39.  
    40.             float pourcentage = 0;
    41.             if (async.progress < 0.9f)
    42.             {
    43.                 Debug.Log("c'est le "+async.progress);
    44.  
    45.                 LoadingBar.fillAmount = async.progress / 0.9f;
    46.                 pourcentage = async.progress * 100;
    47.                 textPourcentage.text = (int)pourcentage + "%";
    48.             }
    49.             else
    50.             {
    51.                 LoadingBar.fillAmount = async.progress / 0.9f;
    52.                 pourcentage = (async.progress/0.9f) * 100;
    53.                 textPourcentage.text = (int)pourcentage + "%";
    54.                 //yield return new WaitForSeconds(0.30f);
    55.                 async.allowSceneActivation = true;
    56.                 Debug.Log("scene activé");
    57.  
    58.             }
    59.        
    60.             yield return null;
    61.  
    62.         }
    63.  
    64.  
    65.  
    66.     }
    67. }
    68.  
    Any ideas bout this ?

    Note : I don't know where come from the function dontdestroynOnLoad, and others scenes not loaded in the picture. But when I remove allowSceneActivation, I saw in the hieracrchie these scenes not loaded, but there are cleared automatically after the loading. But when i bring back the allowSceneActivation, there are not destroyed
     
    Last edited: Dec 30, 2015
  15. arkon

    arkon

    Joined:
    Jun 27, 2011
    Posts:
    1,122
    I'm convinced Unity scene loading is bugged. It works fine in the editor but in IOS and Android async is taking 15 times longer for me than just calling loadLevel.
     
    WILEz1975 likes this.
  16. mikeymike

    mikeymike

    Joined:
    Oct 21, 2014
    Posts:
    35

    Your loading the scene over and over. Just change the update function to something like this

    Code (csharp):
    1.  
    2. void Update()
    3. {
    4. if(estActive)
    5. {
    6. StartCoroutine(LevelCoroutine(nomScene));
    7. estActive = false;
    8. }
    9. }
    10.  
     
    kosted likes this.
  17. kosted

    kosted

    Joined:
    Mar 14, 2015
    Posts:
    104
    Thanks people. I made a tuto to explain how to do. here the link
     
  18. Rond

    Rond

    Joined:
    Oct 21, 2009
    Posts:
    175
    AsyncOperation never reaches 1 nor sets the isDone to true... wtf?
     
  19. AlanG97

    AlanG97

    Joined:
    Feb 25, 2015
    Posts:
    5
    The way LoadAsync works is 0 - 0.9 is Loading of the Level and then 0.9 to 1 is the activation of the level. If you want your progress bar to go from 0 - 1 then you would need to add a line of code to alter it.
    Do something like this:

    Code (CSharp):
    1.  
    2. float progress = Mathf.Clamp01(async.progress / 0.9f);
     
    aloften and Rond like this.
  20. Rond

    Rond

    Joined:
    Oct 21, 2009
    Posts:
    175
    Ah, very nice man, thanks!

    What about isDone? Does it ever turns true?