Search Unity

Load Scene Asynchronously - loading bar

Discussion in 'Scripting' started by loppirob, Mar 17, 2020.

  1. loppirob

    loppirob

    Joined:
    Jan 31, 2018
    Posts:
    10
    I make a Player that read a XML file and create dinamicaly the scene (camera, objects, light, materials, ecc)
    (in HDRP)
    All works ok but when i load the scene the screen is black for many seconds

    My problem is: how to show a progress bar while parsing the XML file in C#?
    for now (testing) i use a simple button and a static variable
    The big problem is that the SceneManager.LoadSceneAsync ending before execution of my script (the main loop in the AWAKE event) that i have attached on a empty gameobject in scene to load

    on the button onClick:

    AsyncOperation operation = SceneManager.LoadSceneAsync(sceneIndex);
    Text mytext = thebutton.GetComponent<Text>();
    while (!operation.isDone)
    {
    mytext.text = "Test " + StaticValues.myprogress;
    yield return null;
    }

    I created 2 scene: the first is the main scene with a canvas and one button (for testing), the second one with the parsing script attached to one empty gameobject.
    I make also a script with a static variable:

    public class StaticValues : MonoBehaviour
    {
    public static int myprogress = 0;

    }

    when i click on the button in the first scene the follow script start:

    public GameObject thebutton;

    public void LoadLevel(int sceneIndex)
    {
    StartCoroutine(LoadAsynchronously(sceneIndex));
    }
    IEnumerator LoadAsynchronously(int sceneIndex)
    {
    StaticValues.myprogress = 0;
    AsyncOperation operation = SceneManager.LoadSceneAsync(sceneIndex);
    Text mytext = thebutton.GetComponent<Text>();
    while (!operation.isDone)
    {
    mytext.text = "Test " + StaticValues.myprogress;
    yield return null;
    }
    }

    In the scene loaded by LoadSceneAsync in one empty GameObject i attached my parsing script:

    void Awake()
    {
    myCaricaScena(1);
    }
    bool myCaricaScena(int numero_scena)
    {
    ....

    StreamReader reader = new StreamReader(NomeFileXML);
    while ((line = reader.ReadLine()) != null)
    {
    StaticValues.myprogress++;

    ... create mesh and other objects

    I can't show StaticValues.myprogress in the button because operation.isDone = true before
    myCaricaScena(1) start;

    Is it possible to solve this problem?
     
  2. VishwasGagrani

    VishwasGagrani

    Joined:
    May 12, 2018
    Posts:
    84
    I think you will need to create an empty scene called preloader with a preloader component. And then show it loading while the next scene is loading. Because it will have a single game object it won't take more than a second to load.

    while (!operation.isDone)
    {
    // You can increase the localScale of progress bar game object at this place
    progressbar.transform.localScale = new Vector3( x_val++, y_flt,z_flt) ;
    yield return null;
    }
     
  3. loppirob

    loppirob

    Joined:
    Jan 31, 2018
    Posts:
    10
    I already created an empty scene with a preloader component (script attached to a button)
    and the main scene is in the second scene.
    the problem is that i read the objects from an external file (XML) in the second scene, create GameObjects at runtime (may be 100 objects or more).
    While i read the lines of external file XML i have the progress variable in my hands (i know how many objects are and the current one) but i dont know how write that on the button.
     
  4. loppirob

    loppirob

    Joined:
    Jan 31, 2018
    Posts:
    10
    ... or must i create a
    third preload scene between my two scene ... I go to work !!!
     
  5. loppirob

    loppirob

    Joined:
    Jan 31, 2018
    Posts:
    10
    Not work !!!(may be i don't understand Unity ...)
    in scene 1 where i click the button that load the scene 2 and wait (SceneManager.LoadSceneAsync...)
    OnDisable() execute before Awake() in the scene 2.
    My loop that read XML is in Awake(), so its IMPOSSIBLE for me write on Button in scene 1
    Or not?
    Unity is so bad? I only 3 weeks on Unity, this is my first big problem with it
     
  6. loppirob

    loppirob

    Joined:
    Jan 31, 2018
    Posts:
    10
    I solved by StartCoroutine(myCaricaScena()); in AWAKE

    For testing i make a Canvas with a Text component and add one script:
    ...
    void Update()
    {
    if (lastProgress != StaticValues.myprogress)
    {
    lastProgress = StaticValues.myprogress;
    MyText2.text = "Test " + StaticValues.myprogress;
    }
    }

    in myCaricaScena()
    in the loop where i read the lines of XML and create objects i execute the
    yield return null;
    (only fiew times regardless the positions in the file )
    and set the variable StaticValues.myprogress

    I must create all the objects with SetActive(false)
    and reactivate at the and of the loop
    maybe i understood StartCoroutine

    It was very symple :D

    This is my scene described in the xml showed by player without changing anytings by the editor

    upload_2020-3-19_11-19-35.png