Simple asynchronous scenarios Unity tools of loading (loading comprises loading schedule and synchronization methods) class implemented LoadSceneManager
table of Contents
Second, the realization principle
Fifth, the implementation steps
First, a brief introduction
Unity tools, some games might be used to develop their own modules finishing alone used independently to facilitate game development.
Simple asynchronous scene is loaded (load schedule includes synchronization and loading method) class, made a singleton class alone, provide loading and loading method Scene progress, for the outside world to call.
Second, the realization principle
1, Singleton ensure that the entire scene is only one class loading management scenario;
2, LoadSceneManager.Instance.LoadSceneAsync to asynchronous loading scenario;
3, LoadSceneManager.Instance.LoadScene synchronous load to the scene;
4, LoadSceneManager.Instance.ProgressLoadSceneAsync to get asynchronous loading progress;
Third, pay attention
1, scene management enumeration name;
2, acquisition schedule, transformed according to the actual situation, the progress value range is between 0 and 100;
Fourth, the effect preview
Fifth, the implementation steps
1, open Unity, create a new project, a new Start scene, the scene of some scenes loaded UI layout progress, as shown below
2, a new Game scene layout add UI, which can prompt scene, as in FIG.
3, the new script, Singleton management class loading scenario, and a test scenario loaded class, as shown below
4, mounted to the test script class Start scene, and a corresponding assignment, as shown below
5, to add to the Build Settings in the scene, as shown below
6, run the scenario, the following results
Sixth, the key code
1、TestScript
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestScript : MonoBehaviour
{
public Slider progressSlider;
public Text progressText;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) {
Debug.Log("GetKeyDown(KeyCode.Space)");
LoadSceneAsync();
}
}
void LoadSceneAsync() {
progressSlider.value = 0;
progressText.text = "进度";
LoadSceneManager.Instance.LoadSceneAsync(ScenesName.Game, ShowProgress, ()=> { Debug.Log("开始异步加载场景..."); }, () => { Debug.Log("开始异步加载完成,跳转场景"); } );
}
void ShowProgress(float progress) {
Debug.Log("progress:" + progress);
progressSlider.value = progress / 100;
progressText.text = "进度: " + progress +" %";
}
}
2、LoadSceneManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
/// <summary>
/// 场景枚举
/// </summary>
public enum ScenesName {
Start,
Game,
}
public class LoadSceneManager : MonoSingleton<LoadSceneManager>
{
//异步加载对象
private AsyncOperation prog;
// 异步加载进度参数
int toProgress = 0;
int showProgress = 0;
// 异步加载事件
System.Action<float> loadingAction = null;
System.Action loadBeforeAction = null;
System.Action loadedEndAction = null;
/// <summary>
/// 同步加载场景
/// </summary>
/// <param name="scenesName">场景名称</param>
public void LoadScene(ScenesName scenesName) {
SceneManager.LoadScene(scenesName.ToString());
}
/// <summary>
/// 异步加载
/// </summary>
/// <param name="scenesName">场景名称</param>
/// <param name="loadingAction">加载中的事件</param>
/// <param name="loadBeforeAction">异步加载前的事件</param>
/// <param name="loadedEndAction">异步加载完成后的事件</param>
public void LoadSceneAsync(ScenesName scenesName, System.Action<float> loadingAction, System.Action loadBeforeAction = null, System.Action loadedEndAction = null) {
// 事件赋值
this.loadBeforeAction = loadBeforeAction;
this.loadingAction = loadingAction;
this.loadedEndAction = loadedEndAction;
StartCoroutine(LoadingScene(scenesName));
}
/// <summary>
/// 异步加载进度
/// </summary>
/// <returns></returns>
public float ProgressLoadSceneAsync() {
return showProgress;
}
/// <summary>
/// 协程加载场景
/// </summary>
/// <param name="scenesName">场景名称</param>
/// <param name="loadingAction">加载中的事件</param>
/// <param name="loadBeforeAction">异步加载前的事件</param>
/// <param name="loadedEndAction">异步加载完成后的事件</param>
/// <returns></returns>
private IEnumerator LoadingScene(ScenesName scenesName)
{
// 异步加载前的事件
if (this.loadBeforeAction != null) {
this.loadBeforeAction.Invoke();
}
prog = SceneManager.LoadSceneAsync(scenesName.ToString()); //异步加载场景
prog.allowSceneActivation = false; //如果加载完成,也不进入场景
toProgress = 0;
showProgress = 0;
//测试了一下,进度最大就是0.9
while (prog.progress < 0.9f)
{
toProgress = (int)(prog.progress * 100);
while (showProgress < toProgress)
{
showProgress++;
// 异步加载中的事件
if (this.loadingAction != null)
{
this.loadingAction.Invoke(showProgress);
}
}
yield return new WaitForEndOfFrame(); //等待一帧
}
//计算0.9---1 其实0.9就是加载好了,我估计真正进入到场景是1
toProgress = 100;
while (showProgress < toProgress)
{
showProgress++;
// 异步加载中的事件
if (this.loadingAction != null)
{
this.loadingAction.Invoke(showProgress);
}
yield return new WaitForEndOfFrame(); //等待一帧
}
// 异步加载完成后的事件
if (this.loadedEndAction != null)
{
this.loadedEndAction.Invoke();
}
yield return new WaitForEndOfFrame(); //等待一帧
prog.allowSceneActivation = true; //如果加载完成,进入场景
}
}
3、MonoSingleton
using UnityEngine;
public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T instance = null;
private static readonly object locker = new object();
private static bool bAppQuitting;
public static T Instance
{
get
{
if (bAppQuitting)
{
instance = null;
return instance;
}
lock (locker)
{
if (instance == null)
{
instance = FindObjectOfType<T>();
if (FindObjectsOfType<T>().Length > 1)
{
Debug.LogError("不应该存在多个单例!");
return instance;
}
if (instance == null)
{
var singleton = new GameObject();
instance = singleton.AddComponent<T>();
singleton.name = "(singleton)" + typeof(T);
singleton.hideFlags = HideFlags.None;
DontDestroyOnLoad(singleton);
}
else
DontDestroyOnLoad(instance.gameObject);
}
instance.hideFlags = HideFlags.None;
return instance;
}
}
}
private void Awake()
{
bAppQuitting = false;
}
private void OnDestroy()
{
bAppQuitting = true;
}
}
Seven, reference works
Click to download