Editor 上不报错,打成 ab 包在移动端报错
1. 应用背景:
我出现此问题的背景环境是:
我使用一个自定义的列表组件来管理列表 item 的循环复用;
然后 item 做成一个预制体,跟列表界面预制体放在同一目录下;
列表组件中通过一个
public GameObject itemPref;
的属性索引 item 预制体,实例化的时候使用Instantiate(itemPref)
的方式实现;
这样的流程在 Unity 编辑器上执行完全没问题,然后打 android 包的时候,我将预制资源都打成了 AB 包,每个 .prefab
预制都打成一个 .assetbundle
,然后,在手机上运行的时候出现了如下报错:
The file 'none' is corrupted. Remove it and launch unity again [position out of bounds!]
大致意思,就是实例化 item 失败了。
2. 问题分析:
直接查看列表界面预制体打成 .assetbundle
对应的 ..assetbundle.manifest
文件,在文件末尾,可以看到该预制所需要引用到的资源列表:
...
Assets:
- Assets/res/Prefabs/ui/rank/PnlRank.prefab
Dependencies:
- C:/XXX/Assets/../resource/assets/res/common/materials.assetbundle
- C:/XXX/Assets/../resource/assets/res/ui/atlas/common.assetbundle
- C:/XXX/Assets/../resource/assets/res/ui/atlas/rank.assetbundle
- C:/XXX/Assets/../resource/assets/res/ui/atlas/roles.assetbundle
- C:/XXX/Assets/../resource/assets/res/ui/fonts/default.assetbundle
可以看到通过 C# 脚本引用的预制资源并不会被记录在此文件中,所以实例化的时候自然也找不到对应的资源,从而导致实例化失败。
3. 解决方案:
既然 AB 机制下,不同预制不能通过 C# 来索引,可以考虑一下两个方案:
- 方案一:通过代码和资源路径索引资源,然后再实例化;
- 方案二:不将 item 单独做成预制体,而是直接放在列表 UI 的预制体中,设置为
active = false
(隐藏),然后再拖拽到 C# 脚本的索引属性上。