Unity3D asset bundle 格式简析
Unity3D 的 Asset Bundle 格式并未公开,但为了实现更高效的差异更新,我们有必要了解其打包格式。掌握 Asset Bundle 的格式后,我们可以开发专门的差异比较合并工具,相较于直接进行二进制差异比较,这种方式效果更佳。原因在于,我们能够将 Asset Bundle 内的数据拆分为独立单元,仅对发生变更的单元进行差异比较。
目前网上能查到的相关资料并非官方提供,其中最流行的是一个名为 disunity 的开源工具。该工具使用 Java 编写,仅提供了源代码,却未给出格式说明(实际上,格式说明比代码更为重要)。通过仔细研读 disunity 的代码,我整理出以下记录。
Asset Bundle 的压缩模式与非压缩模式
Asset Bundle 分为压缩模式和非压缩模式。在压缩模式下,只是使用开源的 LZMA 库对整个非压缩包进行了一次整体压缩。压缩数据的头部有 13 个字节,具体信息如下:
- 前 5 个字节是 LZMA 解压缩的 API 需要传入的 props。
- 接下来的 4 个字节表示解压缩后的数据库长度。
- 最后 4 个字节可忽略。
将压缩数据解压缩后,其格式就与非压缩模式完全相同。因此,下面我们仅讨论非压缩格式。
非压缩模式下的文件头结构
非压缩模式下,Asset Bundle 的文件头是由以下数据结构序列化而来的:
struct AssetBundleFileHead {
struct LevelInfo {
unsigned int PackSize;
unsigned int UncompressedSize;
};
string FileID;
unsigned int Version;
string MainVersion;
string BuildVersion;
size_t MinimumStreamedBytes;
size_t HeaderSize;
size_t NumberOfLevelsToDownloadBeforeStreaming;
size_t LevelCount;
LevelInfo LevelList[];
size_t CompleteFileSize;
size_t FileInfoHeaderSize;
bool Compressed;
};
这个数据结构详细定义了 Asset Bundle 文件头的各个组成部分,对于理解 Asset Bundle 的格式至关重要。通过对这些字段的解析,我们可以更深入地了解 Asset Bundle 的内部结构,为后续开发差异比较合并工具提供坚实的基础。