Asynchronous scene loading

I have 3 scenes - a starting scene, a loading scene and a level scene.
On the starting scene there is a button - - new game. When the button is pressed, the player is taken to a loading scene.

There is a script on the loading scene (listed below) that performs asynchronous loading of the level scene.

The loading scene has text with the loading percentage and a progress bar. They are updated depending on the level loading progress.

When a level loads, the player enters the level stage.

If in the code below we remove
yield return new WaitForSeconds(1f); // Delay of 1 second (needed to display this scene).

then we will not see the loading scene, progressbar and any elements on it. We will see a black screen. But the level will load.

If we leave a delay of 1 second, then we will see the progress bar, its change, percentages - everything will work as it should.

Why does it work this way?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using System;

public class LoadingSceneScript : MonoBehaviour
{
    public Image loadingBarFill;
    public Text loadingText;
    private AsyncOperation asyncOperation;

    void OnEnable()
    {
        DataHolder.ReadAllLocalizationData(() =>
        {
         StartCoroutine(LoadSceneCoroutine());
        });
    }


 
    IEnumerator LoadSceneCoroutine()
    {
        yield return new WaitForSeconds(1f); // Delay of 1 second (needed to display this scene).
        asyncOperation = SceneManager.LoadSceneAsync("Level1Scene");
      
        while (!asyncOperation.isDone)
        {
            float progress = asyncOperation.progress / 0.9f;
            loadingBarFill.fillAmount = progress;
            loadingText.text = "Loading " + string.Format("{0:0}%", progress * 100f);
            yield return 0;
        }         
    }
}

If I remember correctly loading a scene synchronously in Awake, Start and OnEnable will fail. Async may exhibit the issue you’re having. Assuming the scene has just loaded or this script is in the first scene.

It should suffice to yield return null in the coroutine either once or twice.

Why it works this way I don’t know but I suppose when you load a scene from within a scene that was just loaded then the loading occurs before rendering the first frame in the original scene, therefore everything remains black. But this is just a guess.

While this technically works it’s non-standard. It should return null not 0.

Unity hasn’t finished initializing everything when the first wave of Awake, Start, and OnEnable occur. A short delay, regardless of whether it’s a single second or a single frame as mentioned by @CodeSmile , stops the code from executing during the initialization phase.