6.场景模块

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

×

喜欢就点赞,疼爱就打赏