Consejos para trabajar de forma más eficaz con la base de datos de activos

Asset Import Pipeline v2 es el nuevo pipeline de activos predeterminado en Unity, que reemplaza al Asset Import Pipeline v1 con una base de datos de activos reescrita para permitir un cambio rápido de plataforma. Sienta las bases para importaciones de activos escalables con un sólido seguimiento de dependencias. Continúe leyendo para explorar cómo funciona la base de datos de activos y descubrir algunos consejos que le permitirán ahorrar tiempo.
Desde el lanzamiento de Unity 2019.3, el nuevo canal de importación de activos ha sido el canal predeterminado para nuevos proyectos. En combinación con muchas otras mejoras, esto sienta las bases de un canal de importación de assets más confiable, eficiente y escalable. Esta reescritura cambió la forma en que funciona la carpeta Biblioteca para admitir nuevos flujos de trabajo.
Echemos un vistazo a una serie de situaciones que puede encontrar y cómo gestionarlas de manera eficiente. Aprenderá a detectar y abordar algunos de los cuellos de botella que le cuestan tiempo y rendimiento del proyecto.
Los consejos que encontrará aquí se aplican a Unity 2019.3 y versiones posteriores. Recuerde, si su proyecto está en producción más allá de la fase de prototipos, para lograr la máxima estabilidad le recomendamos utilizar la última versión de soporte a largo plazo (LTS) de Unity, Unity 2019 LTS.
Primero, hablemos de algunas de las cosas que suceden cuando creas un nuevo proyecto o abres un proyecto en el que tu biblioteca de activos aún no está presente.
Si observa el archivo Editor.log , notará muchas líneas que se parecen a:
- Empezar a importar…
- Importación terminada…
De esta manera el Canal de Importación de Activos deja un rastro de sus operaciones para que puedan ser inspeccionadas en un momento posterior.
Puede utilizar esta información para determinar un determinado tipo de cuello de botella, concretamente los tiempos de importación de activos.
Al observar la salida de cada línea, puede extraer los siguientes datos:
- Ruta de activos
- Duración de la importación
- Extensión de archivo
Al analizar esos datos, podemos luego categorizarlos por extensión. Una vez que sepa qué importador importó qué activo, puede agregar esos datos en un gráfico circular que le muestre qué tipos de activos tardan más en importarse. Por ejemplo:

Estos datos pueden brindarle una imagen más clara de dónde están los cuellos de botella de su proyecto.
En este ejemplo particular, las texturas, los modelos y los prefabricados son los que consumen más tiempo, lo que proporciona un punto de partida para investigar qué activos podrían optimizarse.
Descargue este proyecto de muestra SimpleEditorLogParser y úselo como base para su propio analizador.
Poder ver qué categoría de activos tarda más en importarse puede ayudarle a planificar dónde dirigir sus esfuerzos de optimización. Si la importación de texturas es la categoría que toma más tiempo, examine las texturas que tardan más en importarse y considere eliminar las texturas que no deberían terminar en la compilación final.
Esto no solo acelerará los tiempos de importación, sino que también mejorará el rendimiento de su canal de integración continua si está realizando compilaciones nocturnas limpias o algo similar.
Poder abrir tus proyectos rápidamente es importante. Los minutos que lleva reiniciar el Editor o abrir varios proyectos a lo largo del día pueden suponer una pérdida de tiempo valiosa.
A medida que un proyecto se vuelve más complejo y utiliza más funciones, su apertura lleva más tiempo. Esto puede deberse a una gran cantidad de factores y, antes de Unity 2019.3, no había forma de poner en funcionamiento el generador de perfiles mientras se iniciaba el editor.
Entre los varios argumentos de línea de comando que puede proporcionar al abrir Unity, el argumento de línea de comando -profiler-enable le permite crear un perfil del Editor durante el lanzamiento.
Este comando le indica al Editor que comience a grabar datos de creación de perfiles para el primer fotograma de la aplicación, que es todo el código que se ejecuta hasta que el Editor sea visible. El uso de este argumento puede ayudarle a ver qué sucede durante el inicio y qué lleva tiempo. Puede ver si se trata de un sistema en Unity, un paquete de Asset Store o un código específico de su proyecto. Esto puede ayudarle a saber qué hacer a continuación.

En esta captura, puedes ver que abrir este proyecto en particular demora unos 50 s.
A primera vista, parece que se necesitan 43 segundos para cargar AssetDatabase. Tras una inspección más detallada, queda claro que se gastan 14 s en llamadas a OnPostProcessAllAssets. Más abajo, el código que se ejecuta durante RegisterScriptsAndTryLoadingExistingUserAssemblies suma 10 s, y 5,7 s de ese tiempo se destinan a cargar el dominio, que se ralentiza aún más por las llamadas a los scripts que tienen el atributo [InitializeOnLoad] .
Estos datos de inicio pueden ayudarle a rastrear cuellos de botella en el rendimiento y ver si el código está en su proyecto o en Unity .
La carpeta Biblioteca ahora puede contener múltiples resultados de importación para el mismo activo, por lo que los proyectos que usan el nuevo canal de importación de activos ya no tienen un GUID (identificador único global) “simple” para la asignación de carpetas en la carpeta Biblioteca.
Los archivos de la carpeta Biblioteca se basan en el hash de su contenido más una serie de dependencias estáticas y dinámicas. Esto permite que Unity tenga características como cambio rápido de plataforma, eliminación de duplicados de activos y omisión de una importación si el hash de un activo ya está presente en la carpeta Biblioteca.
Esto significa que ya no es trivial encontrar resultados de importación en la carpeta Biblioteca. A continuación se muestra un ejemplo que le muestra dónde puede encontrar el resultado de la importación de “Assets/Prefabs/MyPrefab.prefab”:
public class LibraryPathsForAsset
{
[MenuItem("AssetDatabase/OutputLibraryPathsForAsset")]
public static void OutputLibraryPathsForAsset()
{
var assetPath = "Assets/Prefabs/MyPrefab.prefab";
StringBuilder assetPathInfo = new StringBuilder();
var guidString = AssetDatabase.AssetPathToGUID(assetPath);
//The ArtifactKey is needed here as there are plans to
//allow importing for different platforms without switching
//platform, thus ArtifactKeys will be parametrized in the future
var artifactKey = new ArtifactKey(new GUID(guidString));
var artifactID = AssetDatabaseExperimental.LookupArtifact(artifactKey);
//Its possible for an Asset to have multiple import results,
//if, for example, Sub-assets are present, so we need to iterate
//over all the artifacts paths
AssetDatabaseExperimental.GetArtifactPaths(artifactID, out var paths);
assetPathInfo.Append($"Files associated with {assetPath}");
assetPathInfo.AppendLine();
foreach (var curVirtualPath in paths)
{
//The virtual path redirects somewhere, so we get the
//actual path on disk (or on the in memory database, accordingly)
var curPath = Path.GetFullPath(curVirtualPath);
assetPathInfo.Append("\t" + curPath);
assetPathInfo.AppendLine();
}
Debug.Log("Path info for asset:\n"+assetPathInfo.ToString());
}
}
A continuación se muestran dos conceptos básicos para diferentes versiones de Unity:
Los ejemplos son diferentes porque a medida que la implementación del canal de importación de activos ha madurado, varias API se han movido del espacio de nombres experimental al propio espacio de nombres de AssetDatabase.
A menudo, es posible que desees encontrar un activo particular en tu proyecto y hacer algo con el resultado. Es posible que incluso quieras hacer esto varias veces mientras ejecutas el código del editor.
Al llamar a AssetDatabase.FindAssets se recorrerá todo el proyecto para que coincida con la consulta que le ha proporcionado. A medida que los proyectos se hacen más grandes, esto puede convertirse en un cuello de botella en el rendimiento, ya que el tiempo necesario para buscar entre proyectos de diferentes tamaños crece linealmente.

Como era de esperar, cuanto más activos tenga un proyecto, mayor será el tiempo necesario para buscarlos. Afortunadamente, el tiempo necesario para encontrar cada activo se mantiene relativamente estable a lo largo del tiempo.

Como puede ver, si su proyecto tiene cientos de miles de activos, la búsqueda de activos puede provocar una desaceleración notable en el desarrollo. Con 200.000 activos, ya hay un retraso de 200 ms para una consulta de búsqueda simple.
El uso del método de fuerza bruta produce este patrón de uso común:
string[] assets = AssetDatabase.FindAssets ("t:texture2D");
if(assets.Length > 0)
{
string path = AssetDatabase.GUIDToAssetPath (guids[0]);
if (!string.IsNullOrEmpty (path))
{
Texture tex = AssetDatabase.LoadAssetAtPath<Texture>(path);
//Do something with this texture
}
}Básicamente, este código recorre todo el proyecto para encontrar una textura y luego hacer algo con ella.
AssetDatabase proporciona una forma de buscar la ruta de un activo por GUID. Puedes pensarlo como buscar algo en un diccionario por clave en lugar de iterar una matriz para encontrar una coincidencia.
La ventaja de utilizar este enfoque en lugar de la fuerza bruta es que AssetDatabase no necesita buscar en todo el proyecto para encontrar el activo. Puede simplemente usar el GUID como índice de base de datos y seguir esa ruta para cargar el activo en la memoria.
Puede encontrar el GUID en el archivo .meta correspondiente de un activo, por ejemplo:
fileFormatVersion: 2
guía: 9fc0d4010bbf28b4594072e72b8655ab
DefaultImporter:
objetos externos: {}
userData:
assetBundleName:
assetBundleVariant:
En este caso, el GUID de este activo es 9fc0d4010bbf28b4594072e72b8655ab.
Teniendo esa información puedes hacer lo siguiente:
var path = AssetDatabase.GUIDToAssetPath("9fc0d4010bbf28b4594072e72b8655ab");
var asset = AssetDatabase.LoadAssetAtPath<Texture>(path);
Ahora su activo está listo para ser utilizado.
Como nota al margen, si estás interesado en acelerar la búsqueda dentro del Editor, también debes tener en cuenta las siguientes herramientas:
Paquete de búsqueda rápida que le permite buscar en múltiples áreas de Unity.
TypeCache para buscar scripts derivados de un tipo que usted conoce.
Normalmente, el GUID de un activo es constante.
Sin embargo, en ciertas situaciones, un activo y su archivo .meta se duplican, lo que provoca un conflicto que AssetDatabase resuelve de las siguientes maneras:
Si duplica una carpeta dentro de un proyecto en otro lugar del mismo proyecto
Importar un paquete de Asset Store varias veces o copiar una carpeta de otro proyecto varias veces a su proyecto
Cuando se ejecuta AssetDatabase.Refresh, muchos sistemas deben trabajar juntos para presentar su proyecto en un estado válido. En mi charla en Unite Copenhagen, detallo los distintos pasos que ocurren cuando se llama a Refresh.
Las devoluciones de llamadas particulares ejecutadas durante una actualización interactúan con el código. Esto puede afectar el tiempo que tarda en completarse la operación de actualización.
Cuanto más código se ejecute durante una recarga de dominio, más lenta será su experiencia con el editor. Para mantener el flujo mientras se itera el código, piense cuidadosamente cuándo se debe ejecutar el código y si se puede posponer para más adelante en el proyecto.
Durante una recarga de dominio, su código se ejecutará si contiene alguno de los siguientes métodos:
1. Despierto
2. Activado
3. Al validar
Lo ideal sería que el código en esos métodos fuera muy rápido o que se pudiera posponer su ejecución para otro momento (no durante una actualización, por ejemplo). Esto se debe a que se supone que estas devoluciones de llamadas ayudan a restaurar ciertos estados, pero como no hay restricciones sobre lo que se puede hacer dentro de estas llamadas, cualquier código que no se escale (es decir, cualquier cosa que atraviese todo el proyecto) reduce la velocidad de iteración de los scripts mientras el editor está abierto.
Otro enfoque es utilizar EditorApplication.delayCall, donde su código se ejecuta en el próximo tic del Editor después de que AssetDatabase haya tenido la oportunidad de detectar e importar todos los cambios en el disco.
Siga este hilo en los foros de Unity para mantenerse actualizado con las novedades sobre las mejoras en esta área.
Espero que estos consejos te resulten útiles. Cuéntenos qué otras cosas le gustaría saber sobre el proceso de importación de activos o cuáles son sus problemas. Estamos trabajando activamente para mejorar el proceso de importación de activos y queremos que su iteración sea lo más instantánea posible, para que pueda ser más productivo al trabajar con el Editor y cambiar activos o scripts.
