第四章:AssetBundle 核心机制与文件结构
1. 定义与功能
AssetBundle 是 Unity 提供的一种归档文件 (Archive File) 格式。它作为容器,用于存储平台特定(Platform-Specific)的非代码资源(如模型、纹理、预制体、音频片段或场景)。
在运行时,AssetBundle 主要承担以下三个核心技术职能:
- 动态内容分发:支持将资源从安装包(Build)中分离,实现按需下载(DLC)或减小首包体积。
- 运行时内存映射:通过特定的压缩格式,支持以低内存开销的方式将资源映射到虚拟内存中。
- 平台兼容性处理:在构建阶段(Build Time)将资源编译为特定图形 API(如 OpenGL ES, Metal, Vulkan)所需的格式。
2. 内部文件结构
AssetBundle 本质上是一个包含文件头和多个内部文件的二进制容器。根据 Unity 底层规范,其内部主要由以下两类文件组成:

2.1 序列化文件 (Serialized Files)
这是 AssetBundle 的核心组成部分,存储了 Unity 对象的序列化数据。
- 内容:包含 GameObject 层级结构、Component 属性数据、以及对象间的引用关系。
- 生成规则 :
- Asset AssetBundles(普通资源包):通常包含一个序列化文件。
- Scene AssetBundles(场景包):通常包含两个序列化文件。一个存储场景层级(Hierarchy),另一个存储场景引用的对象。
2.2 资源文件 (Resource Files)
这是用于存储大块二进制数据的文件段。
- 内容:纹理(Texture)的像素数据、音频(AudioClip)的 PCM 数据等。
- 技术意义:Unity 将这些大数据块从序列化文件中分离,旨在优化加载性能。这种分离结构允许引擎在后台线程中高效地从磁盘读取二进制块,支持多线程加载。
3. 压缩格式与加载行为
AssetBundle 支持三种压缩模式,不同的压缩算法直接决定了运行时的 I/O 行为和内存占用。
3.1 LZMA (Stream-Based Compression)
- 算法特性:基于流的压缩算法。整个 AssetBundle 被视为一个连续的压缩流。
- 加载行为 :不支持随机读取。在使用 AssetBundle.LoadFromFile 加载时,引擎必须先将整个包解压并重写到内存或磁盘缓存中。
- 适用场景:仅适用于网络传输(下载阶段),因为其压缩率最高。下载后建议通过 AssetBundle.RecompressAssetBundleAsync转换为 LZ4 格式。
3.2 LZ4 (Chunk-Based Compression)
- 算法特性:基于块的压缩算法。文件被分割为固定大小的块(Chunks),每个块独立压缩。
- 加载行为 :支持随机读取 (Random Access) 。
- 当使用 AssetBundle.LoadFromFile 时,引擎仅读取文件头(Header)。
- 当实际加载内部资源(如 LoadAsset)时,引擎根据偏移量直接读取并解压对应的 Chunk。
- 优势:实现"零拷贝"加载,内存占用极低,无须解压整个包。
- 适用场景:所有运行时加载的本地 AssetBundle。
3.3 Uncompressed (无压缩)
- 特性:无压缩开销,文件体积最大。
- 加载行为:直接进行磁盘 I/O 读取,CPU 开销最低。
4. 脚本支持与限制
AssetBundle 不包含 C# 代码或程序集(Assemblies)。
4.1 序列化匹配机制
AssetBundle 中存储的是 ScriptableObject 或 MonoBehaviour 的序列化实例数据 。
在加载 AssetBundle 时,Unity 通过以下三个标识在当前应用程序域中查找对应的类:
- Assembly Name (程序集名称)
- Namespace (命名空间)
- Class Name (类名)
当你把一个挂着 Monster.cs 的 Prefab 打包时,AB 包里存的是:"这个物体挂了一个叫 Monster 的脚本,命名空间是 Game.Logic,它的 hp 字段值是 100"。
4.2 限制
由于 AssetBundle 不包含代码,因此无法通过 AssetBundle 分发新的 C# 类或修改现有类的逻辑。如果 AssetBundle 中的序列化数据引用了主程序中不存在的类,加载时会抛出 Script Missing 警告。
5. 类型树 (TypeTree) 与兼容性
5.1 TypeTree 的作用
TypeTree 是一种描述序列化数据结构的元数据(Metadata)。它定义了对象中每个字段的数据类型和布局。
- 功能 :当 Unity 引擎版本发生变化导致序列化格式改变时,引擎利用 TypeTree 进行安全二进制读取 (Safe Binary Read),尝试将旧版数据映射到新版对象上。
5.2 构建选项:DisableWriteTypeTree
在 BuildAssetBundleOptions 中可以启用 DisableWriteTypeTree 选项。
- 效果:从 AssetBundle 中剥离 TypeTree 数据。
- 优点:减小包体体积,提升加载速度,降低运行时内存占用。
- 约束 :构建 AssetBundle 的 Unity 版本必须与运行时的 Unity 版本严格一致。如果版本不匹配且缺少 TypeTree,会导致序列化布局错位,引发崩溃或数据错误。
总结
本章从底层技术视角解析了 AssetBundle 的核心机制:
- 文件结构 :由 Serialized Files (逻辑数据)和 Resource Files(二进制数据)组成,支持多线程高效加载。
- 压缩策略 :LZ4 格式通过块压缩实现了随机读取和低内存占用,是运行时加载的标准选择。
- 代码分离:AssetBundle 仅包含数据,代码逻辑必须存在于主程序集中。
- TypeTree:在保证引擎版本一致的前提下,禁用 TypeTree 是优化包体和内存的有效手段。
我们首先对AssetBundle 有一个初步的认识,后续更加深入的理解AssetBundle。