Tuanjie 多场景异步叠加加载(Additive)
我在学习Tuanjie的过程中有过这样一个疑问:当我同一个模型资源需要在很多个Scene中使用,如果我给每个Scene中都放置一个GameObject,那么无疑会导致整个游戏的体积变得很大,那么有没有什么办法可以让这个模型资源可以被多个场景同时复用?
在Tuanjie 发布的Tower_Valley Demo中,有个名为Load Demo Scene的操作,点击该操作后多个零散Scene被加载到了一个名为Loader的Scene中最终叠加生成一个完整的Scene,并且这些场景可以随着游戏的运行动态加载以及卸载

这样就很好的解决了我前面的疑问,可以将整个游戏拆分成很多个独立的Scene,并通过叠加的方式来达到实现不同的组合;比如:在A场景和B场景中玩家游戏对象可能是挖掘机、铲车、飞机等其中的任意一项,如果所有的模型资源全部放在A场景与B场景中,那么游戏体积将十分庞大,而使用这种叠加的方式,不仅可以减少游戏体积,也可以让玩家实现在游戏过程中的游戏对象切换;
那么究竟是如何实现的呢?
第一步:需要将所有需要加载的场景添加到Build Setting中,添加后可通过Scene的名称或索引来加载与卸载场景;
第二步:使用UnityEngine.SceneManagement命名空间下的SceneManager类实现加载,推荐使用异步加载;
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);//核心是需要将加载模式设置成Additive
完整的代码:
1 using UnityEngine; 2 using UnityEngine.SceneManagement; 3 using System.Collections; 4 5 // 场景管理单例脚本,负责叠加加载/卸载场景 6 public class SceneLoader : MonoBehaviour 7 { 8 // 单例实例,方便其他脚本调用 9 public static SceneLoader Instance; 10 11 private void Awake() 12 { 13 // 确保单例唯一 14 if (Instance == null) 15 { 16 Instance = this; 17 DontDestroyOnLoad(gameObject); // 切换场景时不销毁该脚本所在对象 18 } 19 else 20 { 21 Destroy(gameObject); 22 } 23 } 24 25 // 异步叠加加载场景(通过场景名称) 26 public IEnumerator LoadSceneAdditive(string sceneName) 27 { 28 // 检查场景是否已加载,避免重复加载 29 if (SceneManager.GetSceneByName(sceneName).isLoaded) 30 { 31 Debug.LogWarning($"场景 {sceneName} 已加载,无需重复加载"); 32 yield break; 33 } 34 35 // 异步加载场景,指定Additive模式 36 AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive); 37 38 // 加载过程中可以显示加载进度(比如UI进度条) 39 while (!asyncLoad.isDone) 40 { 41 float progress = Mathf.Clamp01(asyncLoad.progress / 0.9f); // Unity的progress到0.9才代表加载完成 42 Debug.Log($"加载进度:{progress * 100:F1}%"); 43 yield return null; 44 } 45 46 Debug.Log($"场景 {sceneName} 叠加加载完成"); 47 48 // 可选:设置某个场景为Active Scene(影响部分API的默认行为,比如Instantiate的默认父场景) 49 SceneManager.SetActiveScene(SceneManager.GetSceneByName(sceneName)); 50 } 51 52 // 异步卸载场景 53 public IEnumerator UnloadScene(string sceneName) 54 { 55 // 检查场景是否存在 56 if (!SceneManager.GetSceneByName(sceneName).isLoaded) 57 { 58 Debug.LogWarning($"场景 {sceneName} 未加载,无需卸载"); 59 yield break; 60 } 61 62 AsyncOperation asyncUnload = SceneManager.UnloadSceneAsync(sceneName); 63 while (!asyncUnload.isDone) 64 { 65 yield return null; 66 } 67 68 // 清理未使用的资源(可选,释放内存) 69 Resources.UnloadUnusedAssets(); 70 Debug.Log($"场景 {sceneName} 卸载完成"); 71 } 72 73 // 快捷调用:加载多个场景(示例) 74 public void LoadAllGameScenes() 75 { 76 StartCoroutine(LoadSceneAdditive("Scene_MainUI")); // UI场景 77 StartCoroutine(LoadSceneAdditive("Scene_Terrain")); // 地形场景 78 StartCoroutine(LoadSceneAdditive("Scene_NPCs")); // NPC场景 79 } 80 }
在需要加载场景的位置调用LoadAllGameScenes()即可
注:Scene的异步加载可以在编辑模式下也可以在运行模式下,但是Scene的卸载只能在运行模式下
本文来自博客园,作者:伽椰子真可爱,转载请注明原文链接:https://www.cnblogs.com/jiayezi/p/19505025

浙公网安备 33010602011771号