6.场景模块
6.1 知识点
场景模块的作用
提供了一个管理场景加载的工具,可以同步或异步加载 Unity 场景,并在加载完成后执行回调函数。这对于游戏和应用程序中的场景切换非常有用。
示意图
场景管理器
单例模式
代码继承了一个名为 BaseSingletonInCSharp 的类,这表明它是一个单例模式的实现。单例模式用于确保一个类只有一个实例,并提供了全局访问点。
类和方法注释
代码中使用了注释,这有助于提供代码文档和说明。类和方法的注释描述了它们的功能和参数。
LoadScene方法
LoadScene方法用于同步加载 Unity 场景。它接受两个参数,一个是要加载的场景名称(sceneName),另一个是加载完成后执行的回调函数(callback)。它使用 SceneManager.LoadScene 方法来加载场景,并在加载完成后调用回调函数。
LoadSceneAsyn方法
LoadSceneAsyn方法用于异步加载 Unity 场景。它也接受两个参数,一个是要加载的场景名称(sceneName),另一个是加载完成后执行的回调函数(callback)。它使用协程(Coroutine)来异步加载场景,通过 SceneManager.LoadSceneAsync 获取一个 AsyncOperation 对象,然后等待加载完成。一旦加载完成,它调用回调函数。
ReallyLoadSceneAsyn协程
ReallyLoadSceneAsyn是一个协程函数,用于在后台异步加载场景。它接受与 LoadSceneAsyn 相同的参数。在协程中,它使用 SceneManager.LoadSceneAsync 来启动异步加载操作,然后在加载完成前等待,同时可以返回加载进度。一旦加载完成,它调用回调函数。
进行测试
Lesson06_场景模块 类继承了 BaseSingletonInMonoBehaviour<Lesson06_场景模块>,表明它是一个单例类,并继承了 MonoBehaviour,因此可以附加到 Unity 游戏对象上。
DontDestroyOnLoad(this)
在 Start 方法中调用。这句代码的作用是防止在场景切换时销毁此脚本所附加的游戏对象。这通常用于保留全局性的管理器对象。
Update 方法中包含了四个条件判断,用于在按下不同的键时执行不同的场景加载操作:
- 当按下Q键时,通过 BaseSceneManager.Instance.LoadScene 同步加载名为 “Lesson06_场景模块测试切换” 的场景,并在加载完成后执行一个回调函数,回调函数中打印 “同步加载完成”。
- 当按下W键时,通过 BaseSceneManager.Instance.LoadSceneAsyn 异步加载名为 “Lesson06_场景模块测试切换” 的场景,并在加载完成后执行一个回调函数,回调函数中打印 “异步加载完成”。
- 当按下E键时,通过 BaseSceneManager.Instance.LoadScene 同步加载名为 “Lesson06_场景模块” 的场景,并在加载完成后执行一个回调函数,回调函数中打印 “同步加载完成”。
- 当按下R键时,通过 BaseSceneManager.Instance.LoadSceneAsyn 异步加载名为 “Lesson06_场景模块” 的场景,并在加载完成后执行一个回调函数,回调函数中打印 “异步加载完成”。
测试结果
6.2 知识点代码
BaseSceneManager
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
/// <summary>
/// 负责管理场景加载的类。
/// </summary>
public class BaseSceneManager : BaseSingletonInCSharp<BaseSceneManager>
{
/// <summary>
/// 同步加载场景,并在加载完成后执行回调。
/// </summary>
/// <param name="sceneName">要加载的场景名称。</param>
/// <param name="callback">加载完成后执行的回调函数。</param>
public void LoadScene(string sceneName, UnityAction callback)
{
// 使用SceneManager加载场景
SceneManager.LoadScene(sceneName);
// 如果回调不为null,则调用回调
callback?.Invoke();
}
/// <summary>
/// 异步加载场景,并在加载完成后执行回调。
/// </summary>
/// <param name="sceneName">要加载的场景名称。</param>
/// <param name="callback">加载完成后执行的回调函数。</param>
public void LoadSceneAsyn(string sceneName, UnityAction callback)
{
// 使用协程来异步加载场景
BaseMonoBehaviourManager.Instance.StartCoroutine(ReallyLoadSceneAsyn(sceneName, callback));
}
/// <summary>
/// 协程函数,用于异步加载场景,并在加载完成后执行回调。
/// </summary>
/// <param name="sceneName">要加载的场景名称。</param>
/// <param name="callback">加载完成后执行的回调函数。</param>
private IEnumerator ReallyLoadSceneAsyn(string sceneName, UnityAction callback)
{
// 异步加载场景,并将加载操作赋给asyncOperation
AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName);
// 在异步加载完成前等待
while (!asyncOperation.isDone)
{
// 返回加载进度,可以用于显示进度条等
yield return asyncOperation.progress;
}
yield return asyncOperation;
// 如果回调不为null,则调用回调
callback?.Invoke();
}
}
Lesson06_场景模块
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson06_场景模块 : BaseSingletonInMonoBehaviour<Lesson06_场景模块>
{
void Start()
{
DontDestroyOnLoad(this);
}
private void Update()
{
if(Input.GetKeyDown(KeyCode.Q))
{
BaseSceneManager.Instance.LoadScene("Lesson06_场景模块测试切换", () => { Debug.Log("同步加载完成"); });
}
if (Input.GetKeyDown(KeyCode.W))
{
BaseSceneManager.Instance.LoadSceneAsyn("Lesson06_场景模块测试切换", () => { Debug.Log("异步加载完成"); });
}
if (Input.GetKeyDown(KeyCode.E))
{
BaseSceneManager.Instance.LoadScene("Lesson06_场景模块", () => { Debug.Log("同步加载完成"); });
}
if (Input.GetKeyDown(KeyCode.R))
{
BaseSceneManager.Instance.LoadSceneAsyn("Lesson06_场景模块", () => { Debug.Log("异步加载完成"); });
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com