Este artículo te enseñará cómo funciona la Gestión de Activos Digitales en cualquiera de tus Proyectos de Unity. Con las extraordinarias funciones de Unity 3D para el desarrollo de juegos, te guiaremos para que optimices la velocidad de carga de tu aplicación Unity. Aprenderás a reducir el tamaño final de tu build.

Para ello, primero nos sumergiremos profundamente en cómo Unity gestiona los activos internamente, lo que incluye temas como:

  • ¿Cuáles son las diferencias entre Activos y Objetos Unity?
  • ¿Cómo puedo, como desarrollador, crear mis propios Objetos de Unity?
  • ¿Cómo hace Unity para serializar mis Objetos dentro de los Activos?
  • ¿Cómo gestiona Unity el ciclo de vida de un recurso en la memoria durante el tiempo de ejecución?
  • Mejores prácticas para utilizar las Carpetas de Recursos de Unity.
                                                       
                                         Video Webinar: Gestión de Activos de Unity

Creando Tu Propio UnityEngine.Object: MonoBehaviour, ScriptableObjects y MonoScript

Unity proporciona dos Objetos base que permiten, mediante la herencia, crear tus propios Objetos personalizados que Unity serializará.

El primero es el MonoBehaviour. Un objeto MonoBehaviour puede ser serializado dentro de una Escena o Prefabricado. Se pueden adjuntar a los GameObjects como componentes.

Segundo, está el ScriptableObject. A diferencia de MonoBehaviour, el ScriptableObject no puede ser serializado dentro de un activo de Escena o Prefabricado. A menudo se utilizan como tipos de almacenamiento de datos. 

MonoScript es una referencia al guión que utiliza tu objeto personalizado. Es decir, tus objetos personalizados (MonoBehaviour y ScriptableObjects) contienen una referencia a un MonoScript. Un MonoScript incluye la información necesaria para que puedas localizar el script que define el Objeto. La información básica necesaria para localizar un script incluye el nombre del ensamblaje, el espacio de nombres y el nombre de la clase.

Unity logo

Ensamblajes de Unity

Cada script en C# de tu proyecto se compila con Assembly-CSharp.dll. Excepto los de las carpetas de plugins que están compilados mediante Assembly-CSharp-firstpass.dll. En Unity 2017.3, se añadió la posibilidad de definir tus propios ensamblajes con archivos de referencia de definición de ensamblajes. Todos los ensamblajes se cargan en el inicio de la aplicación.

Este objeto MonoScript es la razón por la que un AssetBundle (o una Escena o un prefabricado) no contiene en realidad código ejecutable en ninguno de los componentes de MonoBehaviour en el AssetBundle, Escena o prefabricado. Esto permite que diferentes MonoBehaviours se refieran a clases específicas compartidas, incluso si los MonoBehaviours están en diferentes AssetBundles.

Serializando Objetos de Unity: Archivo GUID y Local ID

Todos tus objetos pueden tener referencias a uno o más objetos diferentes. Esto se llama Referencias Inter-Objetos. El archivo GUID y el local ID son herramientas utilizadas por Unity para serializar las referencias, como Reference Serialization. 

Es un sistema de identificación robusto, diseñado para abstraer la ubicación de la ruta de los activos, independientemente de la plataforma para la que estamos construyendo nuestro proyecto.

GUID significa Identificador Único Global. Tiene un valor entero de 16 bytes (128 bits), garantizado como único. El archivo GUID identifica un archivo de Activos particular que ha almacenado en el disco. Es un puntero a la ubicación específica del Activo. Unity almacena este identificador en el archivo .meta asociado al Activo.

Local ID ayuda de forma única a identificar un objeto dentro de un archivo de Activos. Después de todo, un archivo de activos puede contener más de un objeto, a menudo del mismo tipo.

Instance ID

Ya que las comparaciones del GUID son lentas en tiempo de ejecución. Unity mantiene un caché de enteros únicos de sesión para identificar una instancia de un recurso, llamado Instance ID.

Esta caché se inicializa al inicio de la aplicación. Mantiene un mapeo entre el ID de una instancia, el archivo GUID, el local ID y la instancia del recurso en memoria (si existe). El caché se inicializa con todos los objetos que son inmediatamente necesarios para la aplicación, que son los objetos a los que se hace referencia en las escenas incorporadas y los objetos de las carpetas de recursos.

Importadores de Activos No Nativos

Los tipos de activos no nativos deben ser importados a Unity. Esto se hace a través de un importador de Activos. Aunque estos importadores suelen ser llamados automáticamente, también están expuestos a los scripts a través de la API AssetImporter. Por ejemplo, la API TextureImporter proporciona acceso a la configuración utilizada cuando se importan activos de texturas individuales, como los archivos PNG.

El resultado del proceso de importación es uno o más UnityEngine.Objects. Estos son visibles en el Editor de Unity como múltiples sub-activos dentro del activo padre, como múltiples sprites anidados bajo una textura Asset que ha sido importada como un atlas de sprites. Cada uno de estos objetos compartirá un archivo GUID ya que sus datos de origen se almacenan en el mismo archivo Asset. Se distinguirán dentro del Asset de la textura importada por un ID local.

El proceso de importación convierte los Activos de origen en formatos adecuados para la plataforma de destino seleccionada en el Editor de la Unidad. El proceso de importación puede incluir una serie de operaciones de peso pesado, como la compresión de la textura. Como este proceso suele ser muy lento, los Activos importados se almacenan en la carpeta Library, eliminando la necesidad de volver a importar los Activos en el siguiente lanzamiento del Editor.

Específicamente, los resultados del proceso de importación se almacenan en una carpeta con el nombre de los dos primeros dígitos del GUID del archivo del activo. Esta carpeta se almacena dentro de la carpeta Library/metadata/. Los objetos individuales del Activo se serializan en un único archivo binario que tiene un nombre idéntico al del archivo del Activo GUID.

Este proceso se aplica a los all Activos, no sólo a los activos no nativos. Los activos nativos no requieren largos procesos de conversión o reserialización.

Ciclo de Vida de los Recursos en Memoria

Para gestionar la huella de memoria de una aplicación en tiempo de ejecución, es importante entender cómo Unity gestiona la carga y descarga automática de Objetos.

Los Objetos se cargan automáticamente cuando un ID de Instancia asignado a un Objeto es derivado, y el Objeto referenciado no está ya cargado, por supuesto es necesario que la fuente de datos del Objeto pueda ser localizada con el par de Archivo GUID + Local ID.

Hay tres formas principales de descargar los objetos de la memoria:

  • Cuando se produce una limpieza de activos, ésta se activa automáticamente cuando se carga una nueva escena de forma no adicional. O cuando Resources.UnloadUnusedAssets se invoca manualmente dentro de un script de C#. Este proceso sólo liberará los Objetos de Unidad no referenciados.
  • Si has cargado explícitamente un objeto de una carpeta de Recursos, puede descargarse invocando el método Resources.UnloadAsset.
  • Los objetos procedentes de AssetBundles se descargan automática e inmediatamente al invocar la API AssetBundle.Unload(true) API.

Carpeta de Recursos: Mejores Prácticas

Los activos que se almacenan dentro de cualquier carpeta llamada Resources, dentro de la carpeta Assets de tu proyecto, serán empaquetados dentro del Unity Player cuando hagas un build, de manera similar a los activos con objetos que son referenciados dentro de tus escenas incorporadas añadidas en Build Settings.

Estos Objetos pueden ser cargados con el API de recursos proporcionado por Unity.

Con eso dicho, es mejor evitar el uso de este sistema. Aquí hay un par de puntos a tener en cuenta al usar las carpetas de recursos:

  • El uso de recursos hace más difícil microgestionar la huella de la memoria en tiempo de ejecución.
  • El uso adecuado de estas carpetas aumentará drásticamente el tiempo de inicio de la aplicación y los tamaños de construcción.
  • Disminuye la capacidad de los Proyectos de suministrar contenido personalizado a plataformas específicas y elimina la posibilidad de incrementar las actualizaciones de contenido como DLCs

¿Cuándo se puede usar la carpeta de Recursos?

  • Para el prototipado rápido, donde la optimización no es el principal objetivo.
  • Para los activos no intensivos en memoria que se necesitarán a lo largo de la vida de una aplicación durante el tiempo de ejecución.

Conclusiones finales

En la próxima parte de este Webinar, discutiremos en profundidad el funcionamiento interno de los Paquetes de Activos y Direcciones de Unity.

Poniendo en Marcha el Proyecto

Ahora que ya has aprendido mucho en este artículo, es hora de que empieces tu propio proyecto de desarrollo de juegos con Unity.

Siéntete libre de hacer preguntas y contacta con Estudios Starloop para obtener una consulta gratuita.

Además, mira este artículo sobre los 7 beneficios de la subcontratación del desarrollo de juegos.

Starloop Studios is proud to be part of the Magic Media group, an international group specialising in entertainment and gaming industry services. Our wide range of offerings includes VFX, blockchain gaming, game art services, and more. Reach out today to avail of our expertise and A-Z services for your projects.