08. 场景加载

awaitable 关键字

本节涉及到场景的加载和卸载,在勇士传说中,我们使用协程的方式来加载和卸载场景,在本节使用了 unity2023.3 最新的特性 awaitable

awaitable 具体是啥,我也不太清楚,见下图

加载场景

在上一节中,我们监听了 LoadRoomEvent 事件,成功调用了 SceneLoadManager.OnLoadRoomEvent,现在补全这个代码

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.SceneManagement;

public class SceneLoadManager : MonoBehaviour
{
    private AssetReference currentScene;
    public AssetReference map;

    /// <summary>
    /// 在房间加载事件中监听
    /// </summary>
    /// <param name="data"></param>
    public async void OnLoadRoomEvent(object data)
    {
        if (data is RoomDataSO)
        {
            RoomDataSO currentData = (RoomDataSO)data;
            // Debug.Log($"{currentData.roomType}");

            currentScene = currentData.sceneToLoad;
        }

        // 卸载当前场景
        await UnloadSceneTask();

        // 加载房间
        await LoadSceneTask();
    }

    /// <summary>
    /// 异步操作加载场景
    /// </summary>
    /// <returns></returns>
    private async Awaitable LoadSceneTask()
    {
        var s = currentScene.LoadSceneAsync(LoadSceneMode.Additive);
        await s.Task;

        if (s.Status == AsyncOperationStatus.Succeeded)
        {
            SceneManager.SetActiveScene(s.Result.Scene);
        }
    }

    private async Awaitable UnloadSceneTask()
    {
        await SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());
    }

    /// <summary>
    /// 监听返回房间的事件函数
    /// </summary>
    public async void LoadMap()
    {
        await UnloadSceneTask();

        currentScene = map;
        await LoadSceneTask();
    }
}

代码中,使用了 async、await 这些关键字

在 async 标注的方法中,我们可以直接调用异步方法,只需要在调用前添加 await 就行了,这样 unity 就会自动将该部分暂停,等到该部分直接结束之后再向下执行。

用 async 的好处可能就是方便访问局部变量吧

另外 async 标注的方法,也可以作为普通方法使用,如果是 IEnumerator 的话,就不能像下面这样操作了

参考:【Unity 2023.1】C# 正式支持 async/await? 试着用Awaitable吧!

卸载场景

上面加载场景中已经实现了,直接用await SceneManager.UnloadSceneAsync(SceneManager.GetActiveScene());

返回地图

进入场景战斗完毕之后,我们需要点击返回按钮回到地图,此时就需要让场景中的返回按钮发送LoadMapEvent事件

然后SceneLoadManager监听LoadMapEvent,事件发生时调用LoadMap

LoadMap里,会卸载掉当前场景,并加载 map 场景

测试

测试的话需要先激活Persistent场景,等程序起来之后,再激活Map场景,之后就能正常进入关卡和退出关卡了

项目相关代码

代码仓库:https://gitee.com/nbda1121440/DreamOfTheKingdom.git

标签:20240302_1325

posted @ 2024-03-02 23:19  hellozjf  阅读(64)  评论(0编辑  收藏  举报