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;
}
}
}
}
}