默认情况下,Unity 通过 LZMA 压缩来创建 AssetBundle,然后通过 LZ4 压缩将其缓存。本部分描述以上的两种压缩格式。
Unity 的 AssetBundle 构建管线通过 LZMA 压缩来创建 AssetBundle。此压缩格式是表示整个 AssetBundle 的数据流,这意味着如果您需要从这些存档中读取某个资源,就必须将整个流解压缩。这是从内容分发网络 (CDN) 下载的 AssetBundle 的首选格式,因为文件大小小于使用 LZ4 压缩的文件。
另一方面,LZ4 压缩是一种基于块的压缩算法。如果 Unity 需要从 LZ4 存档中访问资源,只需解压缩并读取包含所请求资源的字节的块。这是 Unity 在其两种 AssetBundle 缓存中使用的压缩方法。在构建 AssetBundle 以强制进行 LZ4(HC) 压缩时,应使用 BuildAssetBundleOptions.ChunkBasedCompression 值。
使用 BuildAssetBundleOptions.UncompressedAssetBundle 时由 Unity 构建的未压缩 AssetBundle 无需解压缩,但是会占用更多磁盘空间。未压缩的 AssetBundles 是 16 字节对齐的。
为了使用 WWW 或 UnityWebRequest (UWR) 来优化 LZMA AssetBundle 的提取、再压缩和版本控制,Unity 有两种缓存:
内存缓存以 UncompressedRuntime 格式将 AssetBundle 存储在 RAM 中。
磁盘缓存将提取的 AssetBundle 以下文描述的压缩格式存储在可写介质中。
将 AssetBundle 加载到内存缓存中会耗用大量的内存。除非您特别希望频繁且快速地访问 AssetBundle 的内容,否则内存缓存的性价比可能不高。因此,应改用磁盘缓存。
如果向 UWR API 提供版本参数,Unity 会将 AssetBundle 数据存储在磁盘缓存中。如果没有提供版本参数,Unity 将使用内存缓存。版本参数可以是版本号或哈希。如果 Caching.compressionEnabled 设置为 true,则对于所有后续下载,Unity 会在将 AssetBundle 写入磁盘时应用 LZ4 压缩。它不会压缩缓存中的现有未压缩数据。如果 Caching.compressionEnabled 设置为 false,Unity 在将 AssetBundle 写入磁盘时不会应用压缩。
最初加载缓存的 LZMA AssetBundle 所花费的时间更长,因为 Unity 必须将存档重新压缩为目标格式。随后的加载将使用缓存版本。
AssetBundle.LoadFromFile 或 AssetBundle.LoadFromFileAsync 始终对 LZMA AssetBundle 使用内存缓存,因此您应该使用 UWR API。如果无法使用 UWR API,您可以使用 AssetBundle.RecompressAssetBundleAsync 将 LZMA AssetBundle 重写到磁盘中。
内部测试表明,使用磁盘缓存而不是内存缓存在 RAM 使用率方面至少存在一个数量级的差异。因此,必须在内存影响、增加的磁盘空间要求以及应用程序的资源实例化时间之间进行权衡。