using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; namespace XFramework { /// /// 场景状态 /// public abstract class SceneState { protected UIManager panelManager; /// /// 场景名称 /// protected string sceneName = ""; /// /// 场景id /// protected int sceneIndex = -1; /// /// 是否异步加载 /// protected bool async = false; /// /// 是否显示加载界面 /// protected bool loadPanel = false; /// /// 继承了Mono的场景管理类 /// protected GameMain Game { get => GameMain.Instance; } ///// ///// 加载界面名称 ///// //protected string LoadPanelName { get => Game.loadPanelName; } public SceneState() { } /// /// 准备加载新场景时 /// public virtual void OnEnter() { if (!async) LoadScene(); else LoadSceneAsync(); } /// /// 场景准备退出时 /// public virtual void OnExit() { panelManager.PopAll(); } /// /// 加载场景完毕后执行的方法 /// /// /// protected virtual void SceneLoaded(Scene scene, LoadSceneMode mode) { panelManager = new UIManager(); Game.UIManager = panelManager; SceneManager.sceneLoaded -= SceneLoaded; Resources.UnloadUnusedAssets();//新场景加载完成时释放旧场景资源 Debug.Log($"{sceneName}场景加载完毕!"); } /// /// 同步加载场景 /// protected virtual void LoadScene() { if (sceneIndex < 0) SceneManager.LoadScene(sceneName); else SceneManager.LoadScene(sceneIndex); SceneManager.sceneLoaded += SceneLoaded; } /// /// 异步加载场景 考虑大场景互相跳转时内存高分情况 待优化 /// protected virtual void LoadSceneAsync() { Game.StartCoroutine(AsyncLoad()); SceneManager.sceneLoaded += SceneLoaded; } /// /// 异步加载场景的实现 /// /// protected virtual IEnumerator AsyncLoad() { AsyncOperation operation; if (loadPanel)//需要显示加载面板时延迟0.5S等待面板加载完成后开始异步加载场景 避免卡顿 { panelManager = new UIManager(); Game.UIManager = panelManager; panelManager.Push(new SceneLoadingPanel()); yield return new WaitForSeconds(0.5f); } if (sceneIndex < 0) operation = SceneManager.LoadSceneAsync(sceneName); else operation = SceneManager.LoadSceneAsync(sceneIndex); if (loadPanel) { operation.allowSceneActivation = false; float progressValue = 0; while (!operation.isDone) { if (operation.progress < 0.9f) progressValue = operation.progress; else progressValue = 1.0f; panelManager.ChangePanel(progressValue); if (progressValue >= 0.9f) { panelManager.ChangePanel(1); operation.allowSceneActivation = true; } yield return null; } } } } }