Construyendo Asset Bundles
Estructura Interna de Asset Bundle

Compresión de Asset Bundles

Unity soporta tres opciones de compresión para Asset Bundles: LZMA, LZ4 y sin comprimir.

Formato LZMA

Por defecto, cuando los Asset Bundles son construidos, estos son almacenados en un formato comprimido. El formato estándar de compresión es un stream LZMA de solo archivos de datos serializados, y necesitan ser des-comprimidos en su totalidad antes de ser usados.

Los bundles comprimidos con LZMA dan el tamaño de descarga más pequeño posible, pero tiene una des-compresión relativamente lenta resultando en tiempos de carga mayores.

Formato LZ4

Unity también soporta la compresión LZ4, la cual resulta en tamaños de archivo comprimidos mayores, pero no requiere que el bundle en su totalidad sea descomprimido antes de su uso. LZ4 es un algoritmo que se basa en “porciones (chunks)”, y por lo tanto cuando los objetos son cargados desde un bundle comprimido mediante LZ4, solamente las porciones (chunks) correspondientes para ese objeto son descomprimidos. Esto ocurre en la marcha (on the fly), significando que no hay tiempos de espera para que el bundle entero sea descomprimido antes de su uso. El formato LZ4 fue introducido en Unity 5.3 y no estaba disponible en versiones anteriores.

Formato sin comprimir

La tercera opción de compresión es sin comprimir en absoluto. Los bundles sin comprimir son grandes en tamaño, pero son los más rápidos para acceder una vez hayan sido descargados.

El almacenamiento en Caché de Bundles Comprimidos

La función WWW.LoadFromCacheOrDownload descarga y almacena en caché los asset bundles en disco por lo tanto acelera en gran medida la carga después. Desde Unity 5.3 para adelante, los datos en caché también pueden ser comprimidos con el algoritmo LZ4. Esto ahorra entre 40%–60% de espacio comparado a los bundles sin comprimir. La re-compresión sucede durante la descarga y por lo tanto casi no se nota por los usuarios finales. A medida que los datos llegan del socket, Unity lo va a descomprimir y re-comprimirlo en un formato LZ4. Esta re-compresión ocurre durante la descarga del streaming, lo cual significa que la compresión en caché empieza tan pronto la mayoría de datos hayan sido descargados, y continua de manera incremental hasta que la descarga se haya completado. Después de esto, los datos son leídos desde el bundle en caché al descomprimirlo por porciones en la marcha (on the fly) cuando sea necesario.

La compresión en caché es habilitada por defecto y es controlada por la propiedad Caching.compressionEnabled. Esta afecta los bundles almacenados en caché en disco y en memoria.

Visión general del API de la carga (load) de AssetBundles

Esta tabla proporciona una comparación de sobrecarga de memoria y rendimiento cuando se utilice diferentes tipos de compresión y diferentes métodos para cargar.

Sin comprimir Compresión por porciones (chunks-LZ4) Compresión por stream (LZMA)
WWW * Memoria: tamaño del bundle sin comprimir + (mientras que WWW no sea colocado, el tamaño del bundle es sin comprimir). Rendimiento: no hay un procesamiento extra. Memoria: tamaño del bundle comprimido por LZ4HC + (mientras WWW no sea colocado, el tamaño del bundle es uno comprimido por LZ4HC). Rendimiento: no hay un procesamiento extra. Memoria: tamaño del bundle comprimido por LZ4 + (mientras WWW no sea colocado, el tamaño del bundle es comprimido por LZMA). Rendimiento: descompresión LZMA + compresión LZ4 durante la descarga.
LoadFromCacheOrDownload Mem: No se utiliza memoria adicional. Rendimiento: lee desde disco. Mem: No se utiliza memoria adicional. Rendimiento: lee desde disco. Mem: No se utiliza memoria adicional. Rendimiento: lee desde disco.
LoadFromMemory (Async) Mem: Tamaño del bundle sin comprimir. Rendimiento: no se necesita un procesamiento adicional. Mem: Tamaño del bundle comprimido por LZ4HC. Rendimiento: No se necesita un procesamiento adicional. Mem: Tamaño del bundle comprimido por LZ4. Rendimiento: Descompresión LZMA + compresión LZ4.
LoadFromFile(Async) Mem: No se utiliza memoria adicional. Rendimiento: lee desde disco. Mem: No se utiliza memoria adicional. Rendimiento: lee desde disco. Mem: Tamaño del bundle comprimido por LZ4. Rendimiento: lee del disco + descompresión LZMA + compresión LZ4.
WebRequest (también soporta el almacenamiento en caché) Mem: Tamaño del bundle sin comprimir. Rendimiento: No hay un procesamiento adicional [+ lee del disco si está en caché]. Mem: Tamaño del bundle comprimido por LZ4HC. Rendimiento: No hay un procesamiento adicional [+ lee del disco si está en caché]. Mem: Tamaño del bundle comprimido por LZ4. Rendimiento: Descompresión LZMA + compresión LZ4 durante la descarga [+ lee del disco si está en caché].

* Cuando descargue un bundle utilizando WWW, WebRequest, también hay un buffer acumulador 8x64KB que almacena datos desde un socket.

Por lo tanto, utilice los siguientes lineamientos utilizando un API para cargar de bajo nivel en sus juegos:

  1. Despliegue de asset bundles con su juego como StreamingAssets - utilice BuildAssetBundleOptions.ChunkBasedCompression cuando construya bundles y AssetBundle.LoadFromFileAsync para cargarlos. Esto le da una compresión de datos y la manera más rápida para el rendimiento de cargar con una sobre carga de memoria igual a leer buffers.
  2. Descargando asset bundles como DLCs (contenido para descargar) - utilice las opciones por defecto (compresión LZMA) y LoadFromCacheOrDownload/WebRequest para descargarlo y almacenarlo en caché. Aquí usted tendrá la mejor posible tasa de compresión y AssetBundle.LoadFromFile para un rendimiento optimo de cargar para futuras cargas.
  3. Bundles encriptados -escoja BuildAssetBundleOptions.ChunkBasedCompression y utilice LoadFromMemoryAsync para cargar (este probablemente sea el único escenario dónde LoadFromMemory[Async] debería ser utilizado).
  4. Compresión personalizada - utilice BuildAssetBundleOptions.UncompressedAssetBundle para construir y AssetBundle.LoadFromFileAsync para cargar un bundle después de que haya sido descomprimido por su algoritmo de compresión personalizado.

En general, usted debería siempre escoger funciones asincrónicas - estas no estacan el thread (hilo) principal y permiten que las operaciones de cargan sean pasadas en cola (queued) de manera más eficiente. Y absolutamente evite llamar funciones asincrónicas y sincrónicas al mismo tiempo - esto podría introducir contratiempos al thread principal.

Compatibilidad

El formato contenedor del Asset Bundle fue cambiado con el fin de soportar nuevos tipos de compresión, y para proporcionar una base para mejoras futuras. Unity 5 todavía soporta bundles creados en Unity 4, sin embargo los bundles creados en versiones previas (2.x, 3.x) no son soportados.

Construyendo Asset Bundles
Estructura Interna de Asset Bundle