using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; namespace GameFramework { /// /// 场景异步加载器(持久化单例)。带黑色淡入淡出过渡。 /// 场景名可在 Inspector 配置,默认 MainMenu / Gameplay / Scoring。 /// /// 搭建:把 SceneLoader 挂到一个空物体上(放第一个场景 MainMenu 里), /// 它会 DontDestroyOnLoad。transitionImage 是它子物体 Canvas 上的 Image(全屏黑), /// Canvas 设为 Screen Space - Overlay、sortingOrder 设很高(如 1000)。 /// public class SceneLoader : PersistentSingleton { [Header("过渡")] [SerializeField] private Image transitionImage; [SerializeField] private float fadeTime = 1.5f; [Header("场景名(按你工程里的实际名称填)")] [SerializeField] private string mainMenuScene = "MainMenu"; [SerializeField] private string gameplayScene = "Gameplay"; [SerializeField] private string scoringScene = "Scoring"; private Color color; public void LoadGameplayScene() => Load(gameplayScene); public void LoadMainMenuScene() => Load(mainMenuScene); public void LoadScoringScene() => Load(scoringScene); public void Load(string sceneName) { StopAllCoroutines(); StartCoroutine(LoadingCoroutine(sceneName)); } private IEnumerator LoadingCoroutine(string sceneName) { var loadingOperation = SceneManager.LoadSceneAsync(sceneName); loadingOperation.allowSceneActivation = false; if (transitionImage != null) { transitionImage.gameObject.SetActive(true); color = transitionImage.color; color.a = 0f; // 淡入到黑 while (color.a < 1f) { color.a = Mathf.Clamp01(color.a + Time.unscaledDeltaTime / fadeTime); transitionImage.color = color; yield return null; } } // 等异步加载到 90% yield return new WaitUntil(() => loadingOperation.progress >= 0.9f); loadingOperation.allowSceneActivation = true; if (transitionImage != null) { // 淡出到透明 while (color.a > 0f) { color.a = Mathf.Clamp01(color.a - Time.unscaledDeltaTime / fadeTime); transitionImage.color = color; yield return null; } transitionImage.gameObject.SetActive(false); } } } }