Unity3D 的 asset bundle 的格式并没有公开。但为了做更好的差异更新,我们还是希望了解其打包格式。这样可以制作专门的差异比较合并工具,会比直接做二进制差异比较效果好的多。因为可以把 asset bundle 内的数据拆分为独立单元,只对变更的单元做差异比较即可。

网上能查到的资料并不是官方给出的,最为流行的是一个叫做 disunity 的开源工具。它是用 java 编写的,只有源代码,而没有给出格式说明(而后者比代码重要的多)。通过阅读 disunity 的代码,我整理出如下记录:

asset bundle 分为压缩模式和非压缩模式。压缩模式仅仅是用开源的 lzma 库 对整个非压缩包做了一次整体压缩。压缩数据的头有 13 个字节,前 5 个字节是 lzma 解压缩的 API 需要穿入的 props ,接下来的 4 字节是解压缩后的数据库长度。最后 4 字节不用理会它。

把压缩数据解开后,就和非压缩模式没有差别,下面只讨论非压缩格式:

assert 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;
};