第二章 了解AssetBundle的生命周期

当我们构建好一个AssetBundle之后,当然是要加载它,Unity 提供了三种加载 AssetBundle的API,分别是 :

  1. AssetBundle.LoadFromMemory 通过 byte[] 数组加载,无论用什么方法只要拿到资源的 byte[] 数据就可以加载,比较灵活,BundleMaster 在使用异或加密的时候用这种方式。
  2. AssetBundle.LoadFromFile 通过路径加载,好处是可以直接加载 StreamingAssets 下的资源,并且不会像 LoadFromMemory 那样占用额外的堆内存(LZMA压缩的情况下不生效),BundleMaster 默认使用此模式。
  3. AssetBundle.LoadFromStream 通过文件流加载,限制较多,但可以自己设定 Unity 加载数据时使用的读取缓冲区大小从而提升加载性能,能优化一点点性能,不过一般不用。

当加载完成后,我们就获得了一个 AssetBundle 对象,我们可以从这个对象里获取我们想要的资源,如果这个资源是 GameObject,则可以将加载出来的资源实例化,就得到了游戏中具体的物体,如果需要多个物体也可以实例化多次。

如果想要卸载某个资源,需要先将所有实例化出来的物体清除,然后对 AssetBundle 对象调用 Unload,但是 Unload 有一个参数 bool unloadAllLoadedObjects:

  • 当 unloadAllLoadedObjects 为 true 的时候,卸载会将这个 AssetBundle 加载出的所有资源都给卸载掉,BundleMaster 使用的就是这个。
  • 当 unloadAllLoadedObjects 为 false的时候,卸载 AssetBundle 只会卸载原始数据和加载出来没有引用的资源,而拥有引用的资源并不会卸载,如果想要卸载掉这类资需要将引用取消并且手动调用 Resources.UnloadUnusedAssets。

如果使用 Unload(false) 的方式,可以在资源被从 AssetBundle 中加载出来的时候就将 AssetBundle 卸载,可以节省一点点内存的使用,但是如果一个 AssetBundle 当中拥有很多资源,再加载这个 AssetBundle 中其它资源的时候就又需要将 AssetBundle 重新加载出来,浪费掉的性能与省下的那一点点内存相比得不偿失,更何况 AssetBundle 都是经过高度压缩的,本来占用内存就不大,所以综合来看还是使用 Unload(true) 的机制比较好。

可能有朋友对上面的过程中诸如 AssetBundle 和 AssetBundle加载出的资源有所疑问,欢迎看下一章,会着重分析这里。

91焦先生

2022/07/19