Iteración de diseño rápido en Breachers usando AssetPostprocessor y Blender

JEL SADONES / UNITY TECHNOLOGIESLead Level Design/Tech Art, Triangle Factory
Apr 18, 2023|17 minutos
Iteración de diseño rápido en Breachers usando AssetPostprocessor y Blender
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.
Triangle Factory es una empresa de juegos belga de rápido crecimiento que utiliza Unity para crear títulos de VR multijugador de alta calidad como Hyper Dash y su último juego, Infractores. Triangle Factory aprovecha herramientas como Cinemachine, Unity Profiler, Game Server Hosting, Matchmaker, Voice Chat (Vivox)y Friends para crear una experiencia inmersiva para los jugadores.



En este blog, Jel Sadones, diseñador de niveles y arte técnico principal, y el desarrollador principal Pieter Vantorre nos cuentan su proceso de desarrollo de Blender a Unity y cómo dieron vida a su título FPS táctico de VR , Breachers .

Unity ha sido nuestro motor y entorno de desarrollo preferidos durante más de una década, y hemos pasado por muchos flujos de trabajo a lo largo de los años para el modelado y diseño del entorno. Eso incluye el uso de herramientas de modelado en el motor como ProBuilder (que todavía usamos y amamos para la creación rápida de prototipos) y el ensamblaje de escenas a partir de prefabricados creados en otros paquetes de modelado. Sin embargo, para nuestros proyectos actuales, hemos optado por un flujo de trabajo en el que modelamos y organizamos nuestros niveles en Blender, y confiamos en AssetPostprocessor de Unity para integrarlos en nuestro proyecto de Unity .

En este artículo, compartiremos contigo cómo logramos este flujo de trabajo y cómo respalda el tipo de iteración de diseño rápida que necesitamos para nuestros juegos.

Encontrar el flujo de trabajo adecuado

En 2021, lanzamos nuestro primer gran título de VR , Hyper Dash, un juego de disparos de arena 5v5 de ritmo rápido. Cuando comenzamos a desarrollar el juego en 2019, teníamos un flujo de trabajo básico de Blender a Unity que probablemente a muchos les resulte familiar: Simplemente modelamos geometría en Blender, exportamos nuestros activos como archivos FBX y los integramos manualmente en Unity. La integración manual implicó varios pasos:

  • Configurar objetos dinámicos en la escena, como puntos de recogida de armas, puertas de aparición y puntos de captura.
  • Colocar colisionadores para evitar que los jugadores caminen o se teletransporten en ciertas áreas.
  • Configurar guías invisibles para permitir que los bots se comporten correctamente
  • Etc.
Hiper Dash (2021)

Este proceso puede funcionar bien para proyectos más pequeños, pero rápidamente se vuelve engorroso a medida que el proyecto crece y evoluciona. Cuando empezamos a planificar el desarrollo de nuestro próximo título, sabíamos que íbamos a necesitar un flujo de trabajo drásticamente mejorado.

Utilizando el prototipo para identificar puntos críticos

Breachers es un shooter competitivo con diseños de niveles complejos, mecánicas de juego más sutiles, sistemas más técnicos en juego y un mayor nivel de pulido gráfico dirigido a la última generación de hardware de VR independiente. En términos de complejidad, va varios pasos más allá que Hyper Dash, y rápidamente sentimos los efectos de esto en nuestro flujo de trabajo.

Infractores: Descenso en rápel desde un rascacielos en 4K

En la fase de creación de prototipos, todavía dependíamos en gran medida de los prefabricados para objetos dinámicos, como barricadas de ventanas, por ejemplo. Son objetos que colocamos dentro de los marcos de las ventanas para bloquear la línea de visión entre los interiores y el exterior para evitar que los equipos se vean durante la fase de calentamiento del juego.

Mientras probábamos nuestro prototipo, nos movíamos constantemente por las ventanas para mejorar la jugabilidad, lo que implicaba cambiar la geometría en Blender y reexportar a Unity y luego mover manualmente los objetos de barricada para que coincidieran con nuestros cambios. Se pasaron muchas horas volando por la vista de escena de Unity, verificando y arreglando manualmente este tipo de cosas. Aun así, tuvimos más de una prueba de juego en la que solo durante el juego notamos que se había pasado por alto algo.

Figura 2: Imagen de Breachers proporcionada por Triangle Factory (Prototipo del nivel Hideout)
Figura 3.5: Imagen de Breachers proporcionada por Triangle Factory (la versión final de Hideout)

Obviamente, este flujo de trabajo no nos iba a dar la capacidad de iterar rápidamente en nuestros diseños de mapas a medida que hacíamos pruebas, tanto internamente como como parte de nuestra versión alfa abierta, donde planeamos hacer que un mapa estuviera disponible de forma gratuita para recibir comentarios de la comunidad. Estábamos esperando con ansias todos esos comentarios, pero no con ansias en absoluto el esfuerzo manual que implicaba aplicarlos a nuestros mapas.

Otra desventaja potencial de un flujo de trabajo de diseño basado en Prefab es el rendimiento. Para nuestros juegos nos dirigimos principalmente a cascos de VR móviles e independientes. Queremos llevar las imágenes al máximo, por lo que necesitamos exprimir hasta la última gota de rendimiento de nuestro flujo de trabajo.

El ensamblaje de niveles a partir de prefabricados puede ser menos eficiente que la creación de una malla hermética en un programa de modelado. Si unes dos piezas de pared modulares, siempre tendrás un bucle de geometría no fusionado entre ellas. Con Prefabs, también es fácil terminar colocando mucha geometría en tu escena que no es visible (porque está en la parte inferior de un objeto o colocada contra una pared) pero que aún así ocupa un valioso espacio en el mapa de luz. A lo largo de un nivel entero, esas pequeñas ineficiencias pueden provocar un desperdicio de rendimiento y una calidad visual reducida.

Figura 3: Imagen de Breachers proporcionada por Triangle Factory (ventanas rompibles en un nivel sandbox durante el prototipo)

El último problema con Prefabs que queremos mencionar es que puede ser fácil romper cosas al aplicar cambios aparentemente inocentes al modelo fuente en Blender, como cambiar el nombre de un objeto. A medida que un juego o nivel evoluciona, a menudo deseas reorganizar tus activos y darles nombres mejorados o más consistentes. Pero cambiar el nombre de un objeto en Blender y volver a exportarlo puede fácilmente (y sin previo aviso) romper las modificaciones y adiciones realizadas al objeto en Unity, lo que genera regresiones.

En este ejemplo simplificado, tenemos una rejilla de ventilación prefabricada y queremos que salga humo de ella. Después de importar la malla a Unity, nuestro artista agregó el sistema de partículas de humo como un objeto secundario y agregó un componente de tipo de superficie al Prefab para marcarlo como un objeto de metal.

Aquí puedes ver lo que sucede si cambiamos el nombre de nuestra malla en Blender:

Al volver a importar la malla con el nombre actualizado, Unity ya no puede encontrar la malla anterior por nombre, por lo que elimina el objeto del modelo Prefab. Los hijos de este objeto eliminado se mueven a la raíz del Prefab y se eliminan los scripts existentes, lo que nuevamente genera un trabajo de limpieza manual que preferiríamos evitar.

Establecer objetivos claros para la cadena de producción

Cuando la fase de creación de prototipos de Breachers llegó a su fin y nos preparábamos para entrar en modo de producción total a principios de 2022, nuestros equipos de arte y desarrollo se sentaron juntos e investigaron qué podíamos hacer para solucionar estos problemas. Definimos objetivos claros para nuestra cartera de activos ideal, una que respaldara la iteración rápida y flexible requerida para Breachers:

  • Toda la creación y modificación de la geometría de nivel debe realizarse en Blender.
  • LO QUE VES ES LO QUE OBTIENES: Lo que un diseñador crea en Blender debe coincidir lo más posible con el resultado en Unity .
  • Cuando se actualiza algo en Blender, la importación de los cambios a Unity debería realizarse automáticamente y no requerir ningún esfuerzo manual.
Figura 4: Imagen de Breachers proporcionada por Triangle Factory
Haciendo que Blender ame Unity

Como se mencionó anteriormente, nuestro objetivo principal era tener una visualización precisa del juego en Blender , no solo reflejando adecuadamente cómo se verá el resultado final en Unity , sino también cómo está configurada la mecánica del juego. La jugabilidad en Breachers no solo depende del diseño del nivel, sino también de objetos dinámicos (como paredes rompibles) y elementos invisibles (como volúmenes de sonido y colisionadores). Queremos tener toda esta información visible en la etapa de diseño y trasladada con precisión a Unity.

Figura 5: Imagen de Breachers proporcionada por Triangle Factory [Parte de nuestro nivel Rascacielos en Blender (solo geometría y accesorios de nivel estático)]
Figura 6: Imagen de Breachers proporcionada por Triangle Factory (la misma escena con objetos dinámicos agregados)
Figura 7: Imagen de Breachers proporcionada por Triangle Factory (la misma escena importada a Unity, antes del horneado ligero)
Figura 8: Imagen de Breachers proporcionada por Triangle Factory (La escena final en Unity)
Propiedades personalizadas y AssetPostprocessor de Unity

Las propiedades personalizadas son fundamentales para nuestro flujo de trabajo y las asignamos a objetos en Blender. Estos luego se transfieren a Unity mediante el formato FBX, de modo que podemos leerlos y ejecutar lógica personalizada cuando nuestros activos se importan a Unity.

Figura 9: Imagen de Breachers proporcionada por Triangle Factory (un ejemplo de propiedades personalizadas asignadas a un objeto en Blender)

Esto nos da una gran cantidad de flexibilidad, así como estabilidad. Estas propiedades permanecen conectadas a los objetos a lo largo de la cadena de producción, por lo que podemos reorganizar y cambiar el nombre de las cosas en nuestros niveles tanto como queramos sin preocuparnos de que las cosas se rompan o se desincronizan.

Unity tiene una clase poderosa llamada AssetPostprocessor, que permite modificar los activos mientras se importan. Esto es lo que usamos en el momento de la importación para analizar esas propiedades personalizadas y actuar sobre ellas.

Casos de uso

Enlaces prefabricados

Tenemos una propiedad personalizada llamada PrefabLink, que le dice a Unity que el objeto importado de Blender debe ser reemplazado por un Prefab que ya está en el proyecto de Unity , mientras se preserva la transformación del modelo importado. Esto nos permite colocar estos objetos dinámicos en Blender conservando las ventajas de los Prefabs una vez que se importan a Unity. Las barricadas de las ventanas en la escena de Blender anterior son un buen ejemplo de esto.

Figura 10: Imagen de Breachers proporcionada por Triangle Factory

Tipos de superficies

La definición de la superficie es extremadamente importante en Breachers. Caminar sobre una escalera de metal suena diferente a caminar sobre un piso de concreto. La penetración de una bala a través de la madera es muy diferente a la de una bala a través del acero. Y cada tipo de superficie tiene sus propios efectos de impacto. Revisar cada propiedad en Unity y etiquetarla como el tipo de superficie correcto llevaría muchísimo tiempo, por lo que también abordamos esto en la etapa de diseño en Blender configurando propiedades personalizadas en nuestros colisionadores de geometría.

Banderas estáticas

Otra configuración importante para la optimización son los indicadores estáticos de Unity. Configurarlos correctamente puede tener un profundo impacto en aspectos como la reducción de la visibilidad, el horneado ligero y la preparación por lotes. Al usar propiedades personalizadas en Blender, podemos configurarlas en cualquier parte del nivel, incluidas las propiedades reutilizables, y hacer que esa información se transfiera a Unity en todos nuestros niveles.

Colisionadores

Por último, nos gustaría compartir cómo configuramos los colisionadores. Unity tiene un sistema simple pero efectivo que detecta automáticamente variantes de nivel de detalle de los modelos cuando se agrega como posfijo _LOD0, _LOD1, etc. al nombre de un activo de modelo. Nos inspiramos en esto y creamos un sistema similar para colisionadores: Simplemente teniendo geometría con _BoxCollider o _NoCollision en el nombre, reemplazamos las mallas de Blender con colisionadores en Unity.

Figura 11: Imagen de Breachers proporcionada por Triangle Factory (Observe los nombres _BoxCollider y _NoCollision en Blender)
Figura 12: Imagen de Breachers proporcionada por Triangle Factory (el objeto marcado como _BoxCollider se traduce a un BoxCollider real en Unity)
Ejemplo de código

Como ejemplo concreto, aquí hay un fragmento de nuestro LevelSetupPostprocessor que lee propiedades personalizadas y asigna los indicadores estáticos correctos en cada objeto importado:

Cómo personalizar Blender para que funcione mejor con Unity

Para que todo esto funcione sin problemas, también tuvimos que realizar algún trabajo en el lado de Blender .

Las propiedades personalizadas están un poco ocultas en la interfaz de usuario de Blender y requerirían que los artistas escriban manualmente las propiedades personalizadas cada vez, lo que no es una excelente experiencia de usuario. Confiar en la entrada de texto manual también sería muy propenso a errores, anulando gran parte de la ventaja de configurar las cosas en Blender en primer lugar. Pasar de un flujo de trabajo basado en Prefabs a Blender también nos hizo perder algunas de las ventajas de los Prefabs, como tener una linda biblioteca de objetos para explorar y elegir. Afortunadamente, Blender, como Unity, es muy flexible y fácilmente extensible.

Biblioteca de recursos de Blender

La respuesta al problema de la organización de Prefab llegó en Blender 3.2 con Asset Libraries. Este sistema actúa un poco como el sistema Prefab en Unity: Le permite crear activos en un archivo separado y luego importarlos a su escena de Blender , mientras que los cambios en el archivo de activos se reflejan automáticamente en la escena de Blender . Además, garantiza que todas las propiedades personalizadas o colisionadores se apliquen correctamente a cada instancia de este activo en Blender.

Figura 13: Imagen de Breachers proporcionada por Triangle Factory (parte de nuestra biblioteca de accesorios en Blender)
Figura 14: Imagen de Breachers proporcionada por Triangle Factory (todos los tipos de objetos dinámicos que utilizan la propiedad personalizada PrefabLink)
Complementos personalizados de Blender

Para Blender, escribimos un complemento interno para ayudar a configurar las propiedades personalizadas en una interfaz de usuario más clara. Esto simplifica la configuración de propiedades personalizadas con solo seleccionar los objetos Blender relevantes y presionar un botón, en lugar de escribir cada propiedad manualmente.

El complemento Bundle Exporter es un complemento de código abierto que usamos para exportar todos nuestros archivos FBX con un solo clic. Lo modificamos para que también funcione con propiedades personalizadas y actualizamos la interfaz de usuario para tener exportaciones más rápidas para nuestras necesidades específicas.

Figura 15: Imagen de Breachers proporcionada por Triangle Factory
Conclusión

Configurar nuestro flujo de trabajo de diseño de niveles para Breachers requirió una gran inversión de tiempo inicialmente, pero creemos que fue la elección correcta para el proyecto. Además, ¡fue bastante divertido!

A medida que construimos el juego desde los bloques iniciales hasta las pruebas alfa y los meses previos al lanzamiento final, la iteración en nuestros niveles ha sido rápida y sin problemas. Hemos podido eliminar gastos generales y trabajo innecesario para nuestros diseñadores y artistas, y al mismo tiempo transferirles responsabilidades para las que antes habrían necesitado un desarrollador.

Nos ha impresionado tanto Unity como Blender por su capacidad para integrarse entre sí con tanta fluidez, y creemos firmemente que esta integración fue fundamental para hacer de Breachers un juego con el que estamos contentos y orgullosos de compartir con el mundo.

¡Gracias por leer y disfruta del juego!

Imagen en 4K del FPS de VR Breachers de Triangle Factory

Los infractores de Triangle Factory Ya está disponible. Consulta más blogs de desarrolladores de Made with Unity aquí.