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
场景,之后就能正常进入关卡和退出关卡了