08. 场景加载
1.02. 创建房间的 Prefab2.03. 设计地图配置表3.04. 生成地图上的房间4.07. 泛型事件框架
5.08. 场景加载
6.09. 保存地图场景7.10. 房间进出逻辑8.11. 制作卡牌 Prefab9.12. 创建卡牌数据类10.13. 对象池11.14. 制作卡牌库实现抽卡12.15. 创建卡牌布局13.16. 抽卡动画14.17. 实现卡牌扇形布局15.18. 实现鼠标事件16.19. 卡牌拖拽17.20. 攻击牌的拖拽指针18.21. 实现洗牌逻辑19.22. 导入Spine人物素材20.23. 人物基类代码21.24. 执行卡牌效果22.25. 制作血条的 UI Document23.26. 绑定血条数据24.27. 创建USS血条样式25.28. 制作 Gameplay Panel26.29. 绑定 Gameplay Panel 数据27.30. 回合转换28.31. 出牌能量判断29.32. 防御牌及 UI30.33. 回血的苹果牌及特效31.34. 增加力量牌及 UI32.35. 更多卡牌33.36. 人物动画34.37. 敌人意图 AI 逻辑35.38. 敌人的动画执行逻辑36.39. 对战胜负逻辑37.40. 制作胜利和抽卡面板38.41. 抽卡面板的实际逻辑39.42. GameOver 及 Menu 面板40.43. 实现休息房间的逻辑41.44. Boss 制作和整体流程42.45. 淡入淡出及打包游戏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
场景,之后就能正常进入关卡和退出关卡了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?