Source file unity-csharp/scene-flow/LoadingScreen.cs from the GDnD code examples. Download raw file

// GDnD wiki example
// Demonstrates: SceneManager.LoadSceneAsync with a progress bar and allowSceneActivation
// Related pages: [[unity-scene-management]]
 
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
 
// Put this on the Title scene's Canvas. The loading panel is an overlay in the
// current scene; it disappears by itself when the new scene activates.
public class LoadingScreen : MonoBehaviour
{
    [SerializeField] private GameObject loadingPanel;
    [SerializeField] private Slider progressBar;          // Min 0, Max 1
    [SerializeField] private float minimumShowSeconds = 0.75f; // small scenes load too fast to see
 
    private bool isLoading;
 
    // Wire a Play button's On Click () to this and type the scene name.
    public void LoadWithProgress(string sceneName)
    {
        if (!isLoading)
        {
            StartCoroutine(LoadRoutine(sceneName));
        }
    }
 
    private IEnumerator LoadRoutine(string sceneName)
    {
        isLoading = true;
        Time.timeScale = 1f;
 
        if (loadingPanel != null)
        {
            loadingPanel.SetActive(true);
        }
 
        AsyncOperation operation = SceneManager.LoadSceneAsync(sceneName);
        if (operation == null)
        {
            isLoading = false; // scene missing from the scene list; Unity has logged why
            yield break;
        }
 
        // Hold the new scene back so the bar can reach the end first.
        // While activation is held, progress stops at 0.9 and isDone stays false.
        operation.allowSceneActivation = false;
 
        float shownFor = 0f;
        while (operation.progress < 0.9f || shownFor < minimumShowSeconds)
        {
            shownFor += Time.unscaledDeltaTime;
            if (progressBar != null)
            {
                progressBar.value = Mathf.Clamp01(operation.progress / 0.9f);
            }
            yield return null;
        }
 
        if (progressBar != null)
        {
            progressBar.value = 1f;
        }
 
        operation.allowSceneActivation = true; // the new scene replaces this one
    }
}