using System;
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
namespace SK.Framework
{
///
/// 场景加载器
///
public class SceneLoader : MonoBehaviour
{
private GetSceneMode getSceneMode = GetSceneMode.Name;
private LoadSceneMode loadSceneMode = LoadSceneMode.Single;
private string sceneName;
private int sceneBuildIndex;
private float sceneActivationDelay = 3f;
//加载开始事件
private Action onBegan;
//加载中事件
private Action onLoading;
//加载完成事件
private Action onCompleted;
private Action onDelay;
///
/// 加载进度 0-1
///
public float Progress { get; private set; }
private IEnumerator LoadCoroutine()
{
yield return null;
//调用加载开始事件
onBegan?.Invoke();
yield return null;
AsyncOperation asyncOperation;
switch (getSceneMode)
{
case GetSceneMode.Name: asyncOperation = SceneManager.LoadSceneAsync(sceneName, loadSceneMode); break;
case GetSceneMode.BuildIndex: asyncOperation = SceneManager.LoadSceneAsync(sceneBuildIndex, loadSceneMode); break;
default: asyncOperation = null; break;
}
//不允许场景激活
asyncOperation.allowSceneActivation = false;
while (asyncOperation.progress < .9f)
{
//真实加载进度占总进度20%
Progress = Mathf.Clamp01(asyncOperation.progress / .9f) * .2f;
onLoading?.Invoke(Progress);
Debug.Log(string.Format("场景加载进度:{0}", Progress));
yield return null;
}
//开始延时时间
float delayBeginTime = Time.realtimeSinceStartup;
while ((Time.realtimeSinceStartup - delayBeginTime) < sceneActivationDelay)
{
//延时进度
float t = (Time.realtimeSinceStartup - delayBeginTime) / sceneActivationDelay;
//延时进度占总进度的80%
Progress = Mathf.Clamp01(t) * .8f + .2f;
onLoading?.Invoke(Progress);
Debug.Log(string.Format("场景加载进度:{0}", Progress));
yield return null;
}
//延时完成后允许场景激活
asyncOperation.allowSceneActivation = true;
while (!asyncOperation.isDone)
{
yield return null;
}
Debug.Log("场景加载完成");
//调用加载完成事件
onCompleted?.Invoke();
Destroy(gameObject);
}
public SceneLoader LoadAsync()
{
StartCoroutine(LoadCoroutine());
return this;
}
public SceneLoader LoadAsync(string sceneName, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
{
this.sceneName = sceneName;
getSceneMode = GetSceneMode.Name;
this.loadSceneMode = loadSceneMode;
StartCoroutine(LoadCoroutine());
return this;
}
public SceneLoader LoadAsync(int sceneBuildIndex, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
{
this.sceneBuildIndex = sceneBuildIndex;
getSceneMode = GetSceneMode.BuildIndex;
this.loadSceneMode = loadSceneMode;
StartCoroutine(LoadCoroutine());
return this;
}
///
/// 设置场景激活延时
///
/// 延时时长
///
public SceneLoader SetSceneActivationDelay(float sceneActivationDelay)
{
this.sceneActivationDelay = sceneActivationDelay;
return this;
}
///
/// 设置开始加载事件
///
///
///
public SceneLoader OnBegan(Action onBegan)
{
this.onBegan = onBegan;
return this;
}
///
/// 设置激活延迟事件
///
/// 激活延迟事件
/// 场景加载器
public SceneLoader OnDelay(Action onDelay)
{
this.onDelay = onDelay;
return this;
}
///
/// 设置加载中事件
///
///
///
public SceneLoader OnLoading(Action onLoading)
{
this.onLoading = onLoading;
return this;
}
///
/// 设置加载完成事件
///
///
///
public SceneLoader OnCompleted(Action onCompleted)
{
this.onCompleted = onCompleted;
return this;
}
///
/// 异步加载场景
///
/// 场景名称
/// 激活延迟时长
/// 场景加载方式
///
public static SceneLoader LoadAsync(string sceneName, float sceneActivationDelay = 3f, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
{
var loader = new GameObject(string.Format("[SceneLoader.{0}]", sceneName)).AddComponent();
DontDestroyOnLoad(loader);
loader.SetSceneActivationDelay(sceneActivationDelay);
loader.LoadAsync(sceneName, loadSceneMode);
return loader;
}
///
/// 异步加载场景
///
/// 场景指针
/// 激活延迟时长
/// 场景加载方式
///
public static SceneLoader LoadAsync(int sceneBuildIndex, float sceneActivationDelay = 3f, LoadSceneMode loadSceneMode = LoadSceneMode.Single)
{
var loader = new GameObject(string.Format("[SceneLoader.{0}]", sceneBuildIndex)).AddComponent();
DontDestroyOnLoad(loader);
loader.SetSceneActivationDelay(sceneActivationDelay);
loader.LoadAsync(sceneBuildIndex, loadSceneMode);
return loader;
}
}
}