using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
/// <summary>
/// GAME 1303 Tier 1 — Loads levels with an optional fade to black.
///
/// SETUP
/// 1. One GameObject with this script (it survives scene changes automatically).
/// 2. Optional fade: create a Canvas (Sort Order 999) with a full-screen black Image,
/// set the Image's alpha to 0, drag it into Fade Image. Set Raycast Target off.
/// 3. Add every scene to File -> Build Settings in the order you want them played.
///
/// Call from anything:
/// SceneLoader.Instance.LoadNext(); // level exit trigger
/// SceneLoader.Instance.ReloadCurrent(); // game over / retry
/// SceneLoader.Instance.LoadScene("MainMenu");
/// SceneLoader.Instance.LoadScene(3);
/// These are also wired as public methods so UI Buttons can call them directly.
/// </summary>
public class SceneLoader : MonoBehaviour
{
public static SceneLoader Instance { get; private set; }
[Header("Fade (optional)")]
public Image fadeImage;
public float fadeDuration = 0.4f;
private bool loading;
void Awake()
{
if (Instance != null && Instance != this) { Destroy(gameObject); return; }
Instance = this;
DontDestroyOnLoad(gameObject);
}
void Start()
{
// Fade in on first scene
if (fadeImage != null) StartCoroutine(Fade(1f, 0f));
}
public void LoadScene(string sceneName) => StartCoroutine(LoadRoutine(sceneName, -1));
public void LoadScene(int buildIndex) => StartCoroutine(LoadRoutine(null, buildIndex));
public void ReloadCurrent() => LoadScene(SceneManager.GetActiveScene().buildIndex);
public void LoadNext()
{
int next = SceneManager.GetActiveScene().buildIndex + 1;
if (next >= SceneManager.sceneCountInBuildSettings)
{
Debug.Log("SceneLoader: no next scene — returning to index 0.");
next = 0;
}
LoadScene(next);
}
public void QuitGame()
{
Application.Quit();
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#endif
}
IEnumerator LoadRoutine(string name, int index)
{
if (loading) yield break;
loading = true;
Time.timeScale = 1f; // in case we were paused
if (fadeImage != null) yield return Fade(0f, 1f);
AsyncOperation op = name != null ? SceneManager.LoadSceneAsync(name) : SceneManager.LoadSceneAsync(index);
while (!op.isDone) yield return null;
if (fadeImage != null) yield return Fade(1f, 0f);
loading = false;
}
IEnumerator Fade(float from, float to)
{
fadeImage.gameObject.SetActive(true);
float t = 0f;
Color c = fadeImage.color;
while (t < fadeDuration)
{
t += Time.unscaledDeltaTime;
c.a = Mathf.Lerp(from, to, t / fadeDuration);
fadeImage.color = c;
yield return null;
}
c.a = to;
fadeImage.color = c;
if (to == 0f) fadeImage.gameObject.SetActive(false);
}
}