¿Qué estás buscando?

Consejos y problemas de los paquetes de activos de Unity

ATTILIO CAROTENUTO / UNITYTechnical Lead
Apr 16, 2024|8 minutos
Consejos y problemas de los paquetes de activos de Unity
Para tu comodidad, tradujimos esta página mediante traducción automática. No podemos garantizar la precisión ni la confiabilidad del contenido traducido. Si tienes alguna duda sobre la precisión del contenido traducido, consulta la versión oficial en inglés de la página web.

Los paquetes de activos son archivos que contienen activos para tu juego. Se utilizan para dividir tu juego en bloques lógicos, lo que te permite entregar y actualizar contenido a pedido y, al mismo tiempo, hacer que tu juego sea más pequeño. También se utilizan comúnmente para entregar parches y DLC para tu juego. Los paquetes de activos pueden contener todo tipo de activos, como prefabricados, materiales, texturas, clips de audio, escenas y más, pero no pueden incluir scripts.

Anteriormente, era necesario crear paquetes de activos manualmente, marcar cada activo según corresponda y luego rastrear y resolver las dependencias usted mismo en tiempo de ejecución. Hoy en día, todo esto lo gestiona el sistema Addressables , que creará paquetes de activos para usted en función de los grupos de activos que defina, además de cargar y gestionar dependencias de forma transparente.

Si bien hay muchas guías sobre cómo funcionan los paquetes de activos, me gustaría cubrir algunos aspectos menos conocidos del sistema, con un enfoque en el rendimiento del juego, el uso del tiempo de ejecución de la memoria y la compatibilidad general.

Carga y descarga de activos

Cada vez que intenta utilizar un activo contenido dentro de un paquete, Unity se asegura de que el paquete correspondiente se cargue en la memoria y luego, a su vez, carga el activo en la memoria.

Si bien es posible cargar parcialmente activos específicos dentro de un paquete de activos, no se permite lo contrario. Esto significa que una vez que se carga un activo dentro de un paquete de activos, solo se puede descargar si ya no se necesita todo el grupo de activos.

Como resultado, si la estructura de tu paquete no es ideal, a menudo verás un uso creciente de la memoria en tiempo de ejecución a medida que avanza el juego, lo que genera un deterioro del rendimiento y posibles fallas. Por este motivo, es mejor evitar paquetes con una gran cantidad de recursos, ya que terminarán ocupando mucha memoria de ejecución y se convertirán en un cuello de botella para el juego. En lugar de ello, intente agrupar los activos en función de la frecuencia con la que se cargarán y utilizarán juntos.

Compatibilidad de versiones del motor

Los paquetes de activos generalmente son compatibles con versiones posteriores, por lo que los paquetes creados con versiones anteriores de Unity en la mayoría de los casos funcionarán en juegos creados en versiones más nuevas de Unity (suponiendo que no elimine la información de TypeTree, como se explica más adelante). Lo opuesto no es cierto, por lo que es poco probable que los paquetes creados en una versión de Unity más nueva que la utilizada para la creación del juego se carguen correctamente.

A medida que aumenta la diferencia de versión entre el paquete y el motor utilizado para la creación del juego, la compatibilidad se vuelve menos probable. También hay casos en los que el paquete aún puede cargarse, pero los objetos contenidos en el paquete no pueden cargarse correctamente en la nueva versión de Unity, probablemente debido a un cambio en la forma en que se serializan los objetos, lo que crea problemas. En ese caso, necesitarás reconstruir tus paquetes para mantener la compatibilidad.

También existe un costo de rendimiento al cargar paquetes desde una versión diferente de Unity, como se explica en la sección TypeTree a continuación.

Por estos motivos, se recomienda realizar pruebas exhaustivas cada vez que actualice la versión Unity de su juego con los paquetes de activos existentes y también actualizarlos siempre que sea posible.

Compatibilidad entre plataformas

Los paquetes de activos generalmente no ofrecen soporte multiplataforma. Mientras esté en el Editor, podrá cargar paquetes desde otra plataforma de destino; sin embargo, en el dispositivo esto fallará.

Esto sigue siendo válido para los paquetes que contienen activos que no son necesariamente específicos de la plataforma.

La razón de esta limitación es que los datos podrían optimizarse o comprimirse de maneras que solo funcionan para la plataforma de destino. Además, los paquetes pueden contener datos específicos de la plataforma que no deben compartirse entre diferentes plataformas, por lo que esto evita que se filtre contenido que no está destinado a otra plataforma.

Cargando caché

El caché de carga es un grupo compartido de páginas donde Unity almacena datos a los que accedió recientemente para sus paquetes de activos. Esto es global, por lo que se comparte entre todos los paquetes de activos dentro del juego.

Esto se introdujo hace relativamente poco, creo que en Unity 2021.3, y luego se trasladó a 2019.4. Antes de esto, Unity dependía de cachés separados para cada paquete de activos, lo que generaba un uso de memoria en tiempo de ejecución significativamente mayor (que se explica a continuación en “Búferes de archivos serializados”).

De forma predeterminada, esto se establece en 1 MB, pero se puede cambiar configurando AssetBundle.memoryBudgetKB.

El tamaño de caché predeterminado debería ser suficiente en la mayoría de los casos, aunque hay algunos escenarios en los que cambiarlo podría traer beneficios a tu juego. Por ejemplo, si tienes paquetes con muchos objetos pequeños contenidos en su interior, aumentar el tamaño de la memoria caché puede generar más accesos a la memoria caché, lo que mejora el rendimiento de tu juego.

Datos internos adicionales

Junto con los recursos del juego, los paquetes de recursos incluyen una gran cantidad de información adicional y encabezados que Unity utiliza para saber qué recursos cargar y cómo, además de un caché dedicado (según la versión de Unity que estés usando).

Tabla de contenido

Un mapa de los activos en un paquete. Es lo que le permite buscar y cargar cada activo individual en el paquete por nombre. Su tamaño en la memoria normalmente no es una preocupación, a menos que tenga paquetes de activos excepcionalmente grandes que contengan miles de objetos.

Tabla de precarga

La tabla de precarga enumera las dependencias de cada activo incluido en su paquete. Unity lo utiliza para cargar y construir activos correctamente.

Esto puede llegar a ser bastante grande si los activos contenidos en su paquete tienen muchas dependencias explícitas e implícitas, así como dependencias en cascada provenientes de otros paquetes. Por esta razón (y muchas otras), es una buena idea diseñar sus paquetes para minimizar la cadena de dependencia.

Árboles de tipos

Los TypeTrees definen el diseño serializado de los objetos contenidos en los Asset Bundles.

Su tamaño depende de cuántos tipos diferentes de objetos contiene el paquete. Por este motivo, es buena idea evitar paquetes grandes en los que se mezclan objetos de muchos tipos diferentes.

Los TypeTrees son necesarios para mantener la compatibilidad al actualizar la versión Unity de la compilación de tu juego mientras aún intentas cargar paquetes de activos creados en versiones anteriores del motor. Por ejemplo, si el formato o la estructura del objeto han cambiado, le permiten realizar una lectura binaria segura para que Unity pueda intentar cargarlo de todos modos. Esto tiene un costo de rendimiento, por lo que en general se recomienda actualizar los paquetes siempre que sea posible cuando se actualiza el motor.

Se puede desactivar opcionalmente configurando el indicador BuildAssetBundleOptions.DisableWriteTypeTree al crear sus paquetes. Esto hará que tus paquetes y la sobrecarga de memoria relacionada sean más pequeños, pero también significa que necesitarás reconstruir todos tus paquetes cada vez que actualices la versión del motor de la compilación de tu juego. Esto es especialmente doloroso si dependes de paquetes creados a partir de tus reproductores para obtener contenido generado por el usuario, por lo que, a menos que tengas una razón muy sólida para hacerlo, se recomienda mantener TypeTrees habilitado.

Un caso en el que TypeTrees normalmente se puede desactivar de forma segura es para los paquetes incluidos directamente en la compilación del juego. En este caso, actualizar el motor requeriría de todos modos crear una nueva compilación del juego y nuevos paquetes de activos, por lo que su aspecto de retrocompatibilidad no es relevante.

Cada paquete tiene su propio TypeTrees, por lo que tener varios paquetes pequeños que contengan el mismo tipo de objetos aumentará ligeramente el tamaño total en el disco. Por otro lado, cuando se cargan, los TypeTrees se almacenan en un caché global en la memoria, por lo que no incurrirá en un mayor costo de memoria en tiempo de ejecución si varios paquetes de activos almacenan el mismo tipo de objetos.

Buffers de archivos serializados

Nota: Desde Unity 2019.4, esto ha sido reemplazado por un caché de carga compartido global, como se describe arriba.

Cuando se carga un paquete de activos, Unity asigna buffers internos para almacenar sus archivos serializados en la memoria.

Los paquetes de activos regulares contienen un archivo serializado, mientras que los paquetes de activos de escenas de transmisión contienen hasta dos archivos por cada escena contenida en ese paquete. El tamaño de estos buffers depende de la plataforma. En Switch, PlayStation y Windows RT será de 128 KB, mientras que todas las demás plataformas tienen búferes de 14 KB.

Por este motivo, es mejor evitar tener una gran cantidad de paquetes de activos muy pequeños, ya que la memoria ocupada por estos buffers puede llegar a ser significativa en comparación con los activos que realmente proporcionan.

Comprobaciones de integridad del CRC

Se utiliza una CRC (verificación de redundancia cíclica) para realizar una validación de suma de comprobación de sus paquetes de activos, lo que garantiza que el contenido entregado a su juego sea exactamente el que espera. Los CRC se calculan en función del contenido sin comprimir del paquete.

En las consolas, los paquetes de activos normalmente se incluyen como parte de la instalación del título en el almacenamiento local o se descargan como DLC, lo que hace que las comprobaciones de CRC sean innecesarias. En otras plataformas, como PC o dispositivos móviles, es importante realizar comprobaciones de CRC en los paquetes descargados desde una CDN. Esto es para garantizar que el archivo no se dañe ni se trunque, lo que podría provocar fallas potenciales, y también para evitar posibles alteraciones.

Las comprobaciones de CRC son bastante costosas en términos de uso de CPU, especialmente en consolas y dispositivos móviles. Por estos motivos, normalmente es un buen compromiso deshabilitar las comprobaciones de CRC en los paquetes locales y en los paquetes almacenados en caché, y habilitarlas solo en los paquetes remotos no almacenados en caché.

Reducción de gastos generales en la búsqueda de activos

De forma predeterminada, Unity ofrece tres formas de buscar activos dentro de los paquetes:

  • Ruta relativa del proyecto (Activos/Prefabricados/Personajes/Hero.prefab)
  • Nombre del archivo del activo (Hero)
  • Nombre de archivo de activo con extensión (Hero.prefab)

Si bien esto es conveniente, tiene un costo. Para soportar los dos últimos métodos, Unity necesita crear tablas de búsqueda, que pueden consumir una cantidad significativa de memoria para paquetes grandes.

Además, cargar activos utilizando un método diferente a la Ruta relativa del proyecto implicará un costo de rendimiento, nuevamente debido a la búsqueda en la tabla requerida.

Por estas razones, se recomienda evitar el uso de dichos métodos. Incluso puedes desactivarlos cuando se crean los paquetes de activos, lo que mejorará el rendimiento de carga de los paquetes de activos y el uso de memoria en tiempo de ejecución.

Para hacer esto, puedes configurar estas dos banderas al crear tus paquetes:

Para obtener más información sobre la gestión de activos, compartir comentarios o interactuar con la comunidad y el personal de Unity , consulte el foro de Gestión de activos.