Unity Addressables结合SceneManager.LoadSceneAsync编译失败求助
问题解决思路与修正代码
编译失败原因与核心问题
你代码中的编译错误大概率源于直接访问sceneHandle.Task.Result的不规范写法,且场景加载逻辑存在重复加载的错误——用Addressables加载场景后再调用SceneManager.LoadSceneAsync加载同一路径,会导致场景被重复加载,既浪费资源又可能引发异常。
修正后的完整代码
using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.SceneManagement; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.ResourceManagement.ResourceProviders; public class AddressableBundles : MonoBehaviour { private AsyncOperationHandle<SceneInstance> _sceneHandle; void Start() { Addressables.InitializeAsync().Completed += AddressablesManagerCompleted; } private void AddressablesManagerCompleted(AsyncOperationHandle<IResourceLocator> obj) { if (obj.Status == AsyncOperationStatus.Succeeded) { // 加载场景但不自动激活,适配加载屏逻辑 _sceneHandle = Addressables.LoadSceneAsync("Assets/02_Scenes/NEW_ZONING/asset_pack_1/Episode01_v2.unity", LoadSceneMode.Additive, false); _sceneHandle.Completed += OnSceneLoaded; } else { Debug.LogError("Addressables初始化失败: " + obj.OperationException); } } private void OnSceneLoaded(AsyncOperationHandle<SceneInstance> obj) { if (obj.Status == AsyncOperationStatus.Succeeded) { Scene loadedScene = obj.Result.Scene; // 手动激活场景,替代Addressables自动激活逻辑 SceneManager.SetActiveScene(loadedScene); Debug.Log("场景已加载并激活: " + loadedScene.name); } else { Debug.LogError("场景加载失败: " + obj.OperationException); } } private void OnDestroy() { // 销毁对象时卸载场景,防止内存泄漏 if (_sceneHandle.IsValid()) { Addressables.UnloadSceneAsync(_sceneHandle); } } }
关键修改点说明
- 移除静态变量:把
sceneHandle改为实例变量,避免静态变量带来的跨实例资源管理混乱。 - 规范结果访问:用回调参数
obj.Result替代sceneHandle.Task.Result,直接从已完成的操作句柄获取结果,更可靠且符合Addressables使用规范。 - 修正场景激活逻辑:不需要重复加载场景,Addressables加载完成后,通过
SceneManager.SetActiveScene手动激活场景,既适配加载屏需求,又保留Addressables的资源管理优势。 - 增加状态检查:在初始化和加载回调中判断操作状态,提前捕获失败异常,便于调试。
- 添加资源卸载:在
OnDestroy中卸载场景,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Ztorum
相关产品推荐
相关产品推荐

