Unity AssetBundle详细概念
Unity 的Asset与Object
Unity 中的 Asset 对应的 meta 文件中存有一个 File GUID,此外还有若干 Local id,File Id 与 Local id 会被 presidentManager 组合映射到一个 Instance Id,该 id 会作为某个资源的索引依据,和实际运行时的 Unity Object 关联起来。
AssetBundle
AssetBundle 是一种包含平台特定、非代码(这里指的是 Unity 下的 Script,事实上Lua脚本之类的代码也会经常以文本资产的形式打包成AssetBundle)且 Unity 可以在运行时加载资产的归档文件。此外还可以选择特定算法压缩。常用于 Unity 客户端的资源热更新、加载。
AssetBundle文件组成
AssetBundle 由两部分组成 头部 与 数据段。
头部包含 标识符、压缩类型、清单。清单是用对象名作为键值的查找表。存有对象在数据段中的位置,平台上查找表的数据结构为平衡二叉搜索树,IOS上的存储为红黑树。
数据段包含Assetbundle中Asset序列化的生成原生数据,如果有压缩类型的化:
- 不压缩,就是Asset的原生数据
- LZMA,所有Asset原生数据源排列之后将所有数据一起压缩。
- LZ4,Asset原生数据各自压缩之后依次排列,先压缩单个Asset然后排列
AssetBundle加载
AssetBundle.LoadFromMemory : 从托管内存里直接拷贝压缩数据到新的内存。如果是LZMA,会整体解压,如果是LZ4,则会逐个解压。以这个过程内存峰值会超过 AssetBundle 大小的两倍。一份来自托管内存的 API 参数,一份拷贝解压至非托管内存的副本, 如果是 Asset 实际被加载时,该 Asset 将会有三份拷贝。了上述两部分,还有一个来自实际使用该 Asset 的系统(比如GPU)持有的部分。
AssetBundle.LoadFromFile: 如果是 LZMA 则会先将数据解压到内存中,而对于未压缩或者LZ4,将会从文件中加载 AssetBundle 的首部,之后会按需加载各个在Asset 的数据,则不会有额外的内存开销。但是编辑器下还是会将 AssetBundle 连带数据段一起加载。
从AssetBundle加载Asset
-
LoadAsset : 加载单个Asset
-
LoadAllAsset: 加载一个Bundle中的所有Asset
-
LoadAssetWithSubAssets: 递归加载嵌套Object的组合Asset
获取AssetBundle依赖
- 编辑器模式下: AssetDataBase API可以记载AssetbundleManifest获取依赖关系。
AssetBundle分发
- UnityWebRequest
- C# HTTpWebRequest