Unity支持三种资源包的压缩方式:LZMA,LZ4和不压缩。
LZMA格式
资源包默认编译是压缩格式的。标准压缩格式使用的是单一的LZMA算法的序列化的数据文件流,使用前需要获取完整的数据再解压缩。
LZMA压缩包下载容量最小,但会导致解压变慢和加载时间更长。
LZ4格式
Unity还支持LZ4压缩,它会导致较大的压缩文件,但是这种方式不要求完整的数据包就可以解压缩。LZ4算法是“基于块”的,因此当对象从一个LZ4压缩包加载时,仅用于该对象的相应块会被解压。这发生在瞬间,并意味着使用前无需解压完整的资源包。LZ4格式是在Unity 5.3引入,以前的版本不可用。
不压缩格式
第三个压缩选项是不压缩。未压缩的资源包很大,但一旦下载后则访问最快。
压缩包的缓存
WWW.LoadFromCacheOrDownload 函数下载并缓存资源包到磁盘上,这极大的加快了加载速度。从Unity 5.3开始,缓存数据也可以使用LZ4算法压缩。相比未压缩的包它能节省40%~60%的空间。在下载过程中会同时进行压缩,因此最终用户几乎不会察觉。当数据从网络到达,Unity将解压并以LZ4格式重新压缩它。在下载数据流同时重新压缩,这意味着一旦数据足够就马上进行缓存压缩,并一直持续增长到下载完成。在此之后,数据在需要时会从高速缓存的包中即时解压并读取。
缓存压缩默认是启用的,由属性Caching.compressionEnabled 控制。它同时影响缓存到磁盘和存储在内存中的资源包。
AssetBundle加载API概述
此表提供了使用不同的压缩类型和不同的加载方法时内存和性能开销的比较。
|
无压缩 |
块压缩(LZ4) |
流压缩(LZMA) |
WWW * |
内存:未压缩的包的大小+(当WWW未释放时,未压缩的包的大小)。性能:没有额外的开销。 |
内存:LZ4HC压缩的包的大小+(当WWW未释放时,LZ4HC压缩的包的大小)。性能:没有额外的开销。 |
内存:LZ4压缩的包的大小+(当WWW未释放时,LZMA压缩的包的大小)。性能:LZMA解压+ 在下载过程中LZ4压缩。 |
LoadFromCacheOrDownload |
内存:没有额外的开销。性能:从磁盘读取。 |
内存:没有额外的开销。性能:从磁盘读取。 |
内存:没有额外的开销。性能:从磁盘读取。 |
LoadFromMemory(异步) |
内存:未压缩的包的大小。性能:没有额外的开销。 |
内存:LZ4HC压缩的包的大小。性能:没有额外的开销。 |
内存:LZ4压缩的包的大小。性能:LZMA压缩+ LZ4压缩。 |
LoadFromFile(异步) |
内存:没有额外的开销。性能:从磁盘读取。 |
内存:没有额外的开销。性能:从磁盘读取。 |
内存:LZ4压缩的包的大小。性能:从磁盘读取+ LZMA压缩+ LZ4压缩。 |
WebRequest的(也支持缓存) |
内存:未压缩的包的大小。性能:没有额外开销[+是否从磁盘读取缓存]。 |
内存:LZ4HC压缩的包的大小。性能:没有额外的开销[+是否从磁盘读取缓存]。 |
内存:LZ4压缩的包的大小。性能:下载过程中LZMA压缩+ LZ4压缩[+是否从磁盘读取缓存]。 |
*当使用WWW下载资源包,WebRequest还需要一个从socket读取数据的8x64KB的累加器缓存。
因此,使用在游戏中使用低级加载API时遵循以下原则:
1. 为游戏部署资源包时使用StreamingAssets:使用BuildAssetBundleOptions);使用基于块的压缩方式来构建包和资源包;使用LoadFromFileAsync来加载它。这使您的内存数据压缩和加载速度几乎等于读取缓存。
2. 下载用作DLC的资源包:使用默认的编译选项(LZMA压缩)和LoadFromCacheOrDownload / WebRequest来下载和缓存它。这样你可以有最好的压缩比,并得到资源包。LoadFromFile加载性能进一步提升。
3. 加密包:使用BuildAssetBundleOptions;使用基于块的压缩方式,并使用LoadFromMemoryAsync加载(通常这是唯一方案)。
4. 自定义压缩:使用BuildAssetBundleOptions;使用非压缩方式来构建资源包。用自定义的算法解压之后使用LoadFromFileAsync加载包。
你应该使用异步函数,因为他们不阻塞主线程,并且能让加载更高效和操作队列化。绝对避免在同时使用同步和异步函数,这可能会在主线程上产生"打嗝"。
兼容性
资源包容器格式发生了变化,来支持新的压缩类型,并且为进一步改进提供基础。Unity5还支持由Unity 4创建的包,但是更早期版本(2.X,3.X)不支持。
---------------------------------------------------- 以下是原文 ----------------------------------------------------
Asset Bundle Compression
Unity supports three compression options for Asset Bundles: LZMA, LZ4, and Uncompressed.
LZMA Format
By default, when Asset Bundles are built, they are stored in a compressed format. The standard compressed format is a single LZMA stream of serialized data files, and needs to be decompressed in its entirety before use.
LZMA-Compressed bundles give the smallest possible download size, but has relatively slow decompression resulting in higher apparent load times.
LZ4 Format
Unity also supports LZ4 compression, which results in larger compressed file sizes, but does not require the entire bundle to be decompressed before use. LZ4 is a “chunk-based” algorithm, and therefore when objects are loaded from an LZ4-compressed bundle, only the corresponding chunks for that object are decompressed. This occurs on-the-fly, meaning there are no wait times for the entire bundle to be decompressed before use. The LZ4 Format was introduced in Unity 5.3 and was unavailable in prior versions.
Uncompressed Format
The third compression option is no compression at all. Uncompressed bundles are large, but are the fastest to access once downloaded.
Caching of Compressed Bundles
The WWW.LoadFromCacheOrDownload function downloads and caches asset bundles to disk and thus greatly speeds up loading afterwards. From Unity 5.3 onwards, cached data can also be compressed with the LZ4 algorithm. This saves 40%–60% of space compared to uncompressed bundles. Recompression happens during download and thus is almost unnoticeable by the end users. As data arrives from the socket, Unity will decompress it and recompress it in LZ4 format. This recompression occurs during the download streaming, which means the cache compression begins as soon as enough of the data is downloaded, and continues incrementally until the download is complete. After that, data is read from the cached bundle by decompressing chunks on-the-fly when needed.
Cache compression is enabled by default and is controlled by the Caching.compressionEnabled
property. It affects bundles cached to disk and stored in memory.AssetBundle load API overview
This table provides a comparison of memory and performance overheads when using different compression types and different loading methods.
|
Uncompressed |
Chunk Compressed (LZ4) |
Stream Compressed (LZMA) |
WWW * |
Memory: uncompressed bundle size + (while WWW is not disposed, uncompressed bundle size). Performance: no extra processing. |
Memory: LZ4HC compressed bundle size + (while WWW is not disposed, LZ4HC compressed bundle size). Performance: no extra processing. |
Memory: LZ4 compressed bundle size + (while WWW is not disposed, LZMA compressed bundle size). Performance: LZMA decompression + LZ4 compression during download. |
LoadFromCacheOrDownload |
Mem: no extra memory is used. Perf: reading from disk. |
Mem: no extra memory is used. Perf: reading from disk. |
Mem: no extra memory is used. Perf: reading from disk. |
LoadFromMemory (Async) |
Mem: uncompressed bundle size. Perf: no extra processing. |
Mem: LZ4HC compressed bundle size. Perf: no extra processing. |
Mem: LZ4 compressed bundle size. Perf: LZMA decompression + LZ4 compression. |
LoadFromFile(Async) |
Mem: no extra memory is used. Perf: reading from disk. |
Mem: no extra memory is used. Perf: reading from disk. |
Mem: LZ4 compressed bundle size. Perf: reading from disk + LZMA decompression + LZ4 compression. |
WebRequest (also supports caching) |
Mem: uncompressed bundle size. Perf: no extra processing [+reading from disk if cached]. |
Mem: LZ4HC compressed bundle size. Perf: no extra processing [+reading from disk if cached]. |
Mem: LZ4 compressed bundle size. Perf: LZMA decompression + LZ4 compression during download [+reading from disk if cached]. |
* When downloading a bundle using WWW, WebRequest there is also an 8x64KB accumulator buffer which stores data from a socket.
Thus, use the following guidelines when using low-level loading API in your games:
1. Deploying asset bundles with your game as StreamingAssets - use BuildAssetBundleOptions.ChunkBasedCompression when building bundles and AssetBundle.LoadFromFileAsync to load it. This gives you data compression and the fastest possible loading performance with a memory overhead equal to read buffers.
2. Downloading asset bundles as DLCs - use default build options (LZMA compression) and LoadFromCacheOrDownload/WebRequest to download and cache it. Here you’ll have the best possible compression ratio and AssetBundle.LoadFromFile loading performance for further loads.
3. Encrypted bundles - choose BuildAssetBundleOptions.ChunkBasedCompression and use LoadFromMemoryAsync for loading (this is pretty much the only scenario where LoadFromMemory[Async] should be used).
4. Custom compression - use BuildAssetBundleOptions.UncompressedAssetBundle to build and AssetBundle.LoadFromFileAsync to load a bundle after it was decompressed by your custom compression algorithm.
You should generally always choose asynchronous functions - they don’t stall the main thread and they allow loading operations to be queued more efficiently. And absolutely avoid calling synchronous and asynchronous functions at the same time - this might introduce hiccups on the main thread.
Compatibility
The Asset Bundle container format was changed in order to support new compression type, and to provide basis for further improvements. Unity 5 still supports bundles created in Unity 4, however bundles created in earlier version (2.x, 3.x) are not supported.