Unity从AssetBundle加载XRReferenceImageLibrary后纹理为空问题
解决方案
核心原因
你遇到的XRReferenceImageLibrary纹理为空的问题,本质是两个常见问题导致的:1、AssetBundle加载完成后卸载时机过早,纹理资源未完成绑定就被释放;2、原生XRReferenceImageLibrary为只读结构,运行时从AssetBundle加载后不会自动关联依赖的纹理资源。
具体修复步骤
- 第一步:打包AssetBundle前检查两个配置
- 所有参考图关联的纹理的导入设置中,开启
Read/Write Enabled选项 - 打包时确保
XRReferenceImageLibrary和它关联的所有纹理都被打入同一个AssetBundle,或者依赖的纹理所在的AssetBundle会被提前加载
- 所有参考图关联的纹理的导入设置中,开启
- 第二步:修改加载逻辑,改用运行时可变参考图库完成纹理绑定,修正后代码如下:
using System.Collections.Generic; using UnityEngine; using UnityEngine.XR.ARFoundation; using UnityEngine.XR.ARSubsystems; private static void Initialize(AssetBundle myLoadedAssetBundle) { if (myLoadedAssetBundle == null) return; var manager = FindObjectOfType<ARTrackedImageManager>(); if (manager == null) return; var allAssets = myLoadedAssetBundle.LoadAllAssets(); Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>(); XRReferenceImageLibrary sourceLibrary = null; // 分别缓存加载到的纹理和参考图库资源 foreach (var asset in allAssets) { if (asset is Texture2D tex) { textureCache[tex.name] = tex; } else if (asset is XRReferenceImageLibrary lib) { sourceLibrary = lib; } } if (sourceLibrary == null) return; // 创建运行时可变参考图库,支持动态添加纹理 var runtimeLib = manager.CreateRuntimeLibrary(sourceLibrary) as MutableRuntimeReferenceImageLibrary; if (runtimeLib == null) return; // 手动绑定每一张参考图的纹理 foreach (var referenceImage in sourceLibrary) { if (textureCache.TryGetValue(referenceImage.name, out var targetTex)) { runtimeLib.AddReferenceImage(targetTex, referenceImage.name, referenceImage.size.x); } } manager.referenceLibrary = runtimeLib; // 确认所有资源绑定完成后再卸载AssetBundle,若后续还需使用该Bundle内资源可延迟卸载 myLoadedAssetBundle.Unload(false); }
额外注意事项
如果你的AR Foundation版本低于3.1,没有提供MutableRuntimeReferenceImageLibrary接口,可在打包AssetBundle时显式调用BuildPipeline.PushAssetDependencies()方法强制打包所有依赖资源,加载时不要在图库赋值完成后立即卸载AssetBundle,延迟1~2帧再执行卸载操作即可。
内容的提问来源于stack exchange,提问作者sparkcola_zet
相关产品推荐
相关产品推荐

