Itération rapide de la conception dans Breachers à l'aide d'AssetPostprocessor et de Blender

Triangle Factory est une société de jeux belge en pleine expansion qui utilise Unity pour créer des titres VR multijoueurs de haute qualité comme Hyper Dash et leur dernier jeu, Breachers. Triangle Factory s'appuie sur des outils tels que Cinemachine, Unity Profiler, Game Server Hosting, MatchMaker, Voice Chat (Vivox) et Friends pour créer une expérience immersive pour les joueurs.
Dans ce blog, Jel Sadones, lead level design/tech art, et Pieter Vantorre, lead developer, nous présentent leur pipeline Blender-to-Unity et nous expliquent comment ils ont donné vie à Breachers, leur titre de FPS tactique VR.
Unity est notre moteur et notre environnement de développement de prédilection depuis plus d'une décennie, et nous sommes passés par de nombreux flux de travail au fil des ans pour la modélisation et la conception de l'environnement. Cela inclut l'utilisation d'outils de modélisation internes au moteur comme ProBuilder (que nous utilisons toujours et que nous adorons pour le prototypage rapide) et l'assemblage de scènes à partir de préfabriqués créés dans d'autres logiciels de modélisation. Pour nos projets actuels, nous avons opté pour un workflow où nous modélisons et organisons nos niveaux dans Blender, et nous nous appuyons sur l'AssetPostprocessor d'Unity pour les intégrer dans notre projet Unity.
Dans cet article, nous allons vous expliquer comment nous avons abouti à ce flux de travail et comment il permet le type d'itération de conception rapide dont nous avons besoin pour nos jeux.
En 2021, nous avons sorti notre premier grand titre VR, Hyper Dash, un jeu de tir en arène 5v5 au rythme effréné. Lorsque nous avons commencé le développement du jeu en 2019, nous avions un flux de travail de base de Blender à Unity qui semble probablement familier à beaucoup : Nous avons simplement modélisé la géométrie dans Blender, exporté nos actifs sous forme de fichiers FBX et les avons intégrés manuellement dans Unity. L'intégration manuelle s'est faite en plusieurs étapes :
- Mise en place d'objets dynamiques dans la scène tels que les ramasseurs d'armes, les portes de spawn, les points de capture
- Placer des collisionneurs pour empêcher les joueurs de marcher ou de se téléporter dans certaines zones.
- Mise en place de guides invisibles pour permettre aux bots de se comporter correctement
- Etc.

Ce processus peut s'avérer efficace pour les petits projets, mais il devient rapidement fastidieux lorsque le projet prend de l'ampleur et évolue. Lorsque nous avons commencé à planifier le développement de notre prochain titre, nous savions que nous allions avoir besoin d'un flux de travail considérablement amélioré.
Breachers est un jeu de tir compétitif avec des niveaux complexes, des mécanismes de jeu plus subtils, des systèmes plus techniques en jeu et un niveau plus élevé de polissage graphique ciblant la dernière génération de matériel VR autonome. En termes de complexité, il va plusieurs fois plus loin que l'Hyper Dash, et nous en avons rapidement ressenti les effets sur notre flux de travail.

Dans la phase de prototypage, nous nous sommes encore largement appuyés sur les Prefabs pour les objets dynamiques, comme les barricades de fenêtres par exemple. Il s'agit d'objets que nous plaçons à l'intérieur des cadres de fenêtres pour bloquer la ligne de vue entre l'intérieur et l'extérieur afin d'empêcher les équipes de se voir pendant la phase d'échauffement du match.
En testant notre prototype, nous déplacions constamment les fenêtres pour améliorer le gameplay, ce qui impliquait de modifier la géométrie dans Blender et de la réexporter vers Unity, puis de déplacer manuellement les objets de la barricade pour qu'ils correspondent à nos changements. De nombreuses heures ont été passées à voler autour de la vue Scène d'Unity, à vérifier et à corriger manuellement ce genre de choses. Pourtant, nous avons eu plus d'un playtest où nous nous sommes aperçus pendant le jeu que quelque chose avait été négligé.


De toute évidence, ce flux de travail ne nous permettait pas d'itérer rapidement sur la conception de nos cartes au fur et à mesure que nous faisions des tests, à la fois en interne et dans le cadre de notre alpha ouverte, où nous avions prévu de mettre une carte à disposition gratuitement pour recueillir les commentaires de la communauté. Nous nous réjouissions de tous ces retours d'information, mais pas du tout de l'effort manuel nécessaire pour les appliquer à nos cartes.
Un autre inconvénient potentiel d'un flux de travail de conception basé sur le préfabriqué est la performance. Nous ciblons principalement les casques VR mobiles et autonomes pour nos jeux. Nous voulons pousser les images aussi loin que possible, et nous devons donc tirer la moindre goutte de performance de notre flux de travail.
L'assemblage de niveaux à partir de préfabriqués peut s'avérer moins efficace que la création d'un maillage étanche dans un programme de modélisation. Si vous emboîtez deux pièces murales modulaires, vous aurez toujours une boucle géométrique non fusionnée entre elles. Avec les Prefabs, il est également facile de placer beaucoup de géométrie dans votre scène qui n'est pas visible (parce qu'elle est sur le dessous d'un objet, ou placée contre un mur) mais qui prend quand même de l'espace précieux dans la lightmap. Sur l'ensemble d'un niveau, ces petites inefficacités peuvent se traduire par un gaspillage de performances et une diminution de l'aspect visuel.

Le dernier problème des Prefabs que nous souhaitons mentionner est qu'il peut être facile de casser les choses en appliquant des changements apparemment innocents au modèle source dans Blender, comme renommer un objet. Au fur et à mesure de l'évolution d'un jeu ou d'un niveau, vous souhaitez souvent réorganiser vos ressources et leur donner des noms améliorés ou plus cohérents. Mais renommer un objet dans Blender et le réexporter peut facilement (et sans avertissement) briser les surcharges et les ajouts faits à l'objet dans Unity, ce qui entraîne des régressions.
Dans cet exemple simplifié, nous avons une grille d'aération Prefab et nous voulons que de la fumée en sorte. Après avoir importé le maillage dans Unity, notre artiste a ajouté le système de particules de fumée en tant qu'objet enfant et a ajouté un composant de type surface au Prefab pour le marquer comme étant un objet métallique.
Ici, vous pouvez voir ce qui se passe si nous renommons notre mesh dans Blender :
Lors de la réimportation du maillage avec le nom mis à jour, Unity ne peut plus trouver l'ancien maillage par son nom, et supprime donc l'objet du modèle Prefab. Les enfants de cet objet supprimé sont déplacés à la racine de la préfabrication et les scripts existants sont supprimés, ce qui entraîne à nouveau un travail de nettoyage manuel que nous préférons éviter.
Alors que la phase de prototypage de Breachers s'achevait et que nous nous préparions à passer en mode de production complète au début de l'année 2022, nos équipes artistiques et de développement se sont réunies pour étudier ce que nous pouvions faire pour remédier à ces problèmes. Nous avons défini des objectifs clairs pour notre pipeline d'actifs idéal, un pipeline qui prendrait en charge l'itération rapide et flexible requise pour Breachers :
- Toute la création et la modification de la géométrie du niveau doit se faire dans Blender.
- WYSIWYG : Ce qu'un designer crée dans Blender doit correspondre le plus possible au résultat dans Unity.
- Lorsque quelque chose est mis à jour dans Blender, l'importation des changements dans Unity devrait se faire automatiquement et ne pas nécessiter d'effort manuel.

Comme mentionné ci-dessus, notre objectif principal était d'avoir une visualisation précise du jeu dans Blender - reflétant non seulement correctement l'aspect du résultat final dans Unity, mais aussi la façon dont les mécanismes de jeu sont mis en place. Le gameplay de Breachers ne dépend pas seulement de l'agencement d'un niveau, mais aussi d'objets dynamiques (comme les murs franchissables) et d'éléments invisibles (comme les volumes sonores et les collisionneurs). Nous voulons que toutes ces informations soient visibles dès la phase de conception et qu'elles soient reportées avec précision dans Unity.
![Figure 5 : Breachers image provided by Triangle Factory [Partie de notre niveau Skyscraper dans Blender (géométrie statique du niveau et accessoires uniquement)].](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Ffuvbjjlp%2Fproduction%2F3d1ec8eaf99391b246965c8a7ac1fafd1b6f121c-3810x2058.png&w=3840&q=75)



Les propriétés personnalisées sont essentielles à notre flux de travail, et nous les attribuons aux objets dans Blender. Ceux-ci sont ensuite repris dans Unity par le format FBX, de sorte que nous pouvons les lire et exécuter une logique personnalisée lorsque nos actifs sont importés dans Unity.

Cela nous donne une grande flexibilité et une grande stabilité. Ces propriétés restent connectées aux objets tout au long du pipeline, ce qui nous permet de réorganiser et de renommer les objets dans nos niveaux autant que nous le souhaitons sans craindre que les choses ne se cassent ou ne se désynchronisent.
Unity dispose d'une classe puissante appelée AssetPostprocessor, qui permet de modifier les actifs pendant leur importation. C'est ce que nous utilisons au moment de l'importation pour analyser ces propriétés personnalisées et agir en conséquence.
Liens préfabriqués
Nous avons une propriété personnalisée nommée PrefabLink, qui indique à Unity que l'objet importé de Blender doit être remplacé par un Prefab déjà présent dans le projet Unity, tout en préservant la transformation du modèle importé. Cela nous permet de placer ces objets dynamiques dans Blender tout en conservant les avantages des Prefabs une fois qu'ils sont importés dans Unity. Les barricades de fenêtres dans la scène de Blender ci-dessus en sont un bon exemple.

Types de surface
La définition des surfaces est extrêmement importante dans Breachers. Marcher sur un escalier en Metal ne sonne pas de la même manière que marcher sur un sol en béton. La pénétration des balles dans le bois est très différente de celle dans l'acier. Et chaque type de surface a ses propres effets d'impact. Passer en revue chaque accessoire dans Unity et lui attribuer le bon type de surface prendrait énormément de temps, c'est pourquoi nous nous attaquons également à cette tâche au stade de la conception dans Blender en définissant des propriétés personnalisées sur nos collisionneurs de géométrie.
Drapeaux statiques
Les drapeaux statiques d'Unity constituent un autre paramètre important pour l'optimisation. Un réglage correct de ces paramètres peut avoir un impact important sur des éléments tels que l'atténuation de la visibilité, le light baking et le batching. En utilisant les propriétés personnalisées dans Blender, nous pouvons les définir sur n'importe quelle partie du niveau, y compris les accessoires réutilisables, et faire en sorte que cette information soit reprise dans Unity pour tous nos niveaux.
Collisionneurs
Enfin, nous aimerions vous expliquer comment nous avons mis en place les collisionneurs. Unity dispose d'un système simple mais efficace qui détecte automatiquement les variantes de niveau de détail pour les modèles lorsque le nom d'une ressource de modèle est précédé de _LOD0, _LOD1, etc. Nous nous en sommes inspirés et avons créé un système similaire pour les collisionneurs : En ayant simplement une géométrie avec _BoxCollider ou _NoCollision dans le nom, nous remplaçons les meshes de Blender par des colliders dans Unity.


En guise d'exemple concret, voici un extrait de notre LevelSetupPostprocessor qui lit les propriétés personnalisées et attribue les drapeaux statiques appropriés à chaque objet importé :
Pour que tout cela fonctionne bien, nous avons également dû travailler du côté de Blender.
Les propriétés personnalisées sont un peu cachées dans l'interface utilisateur de Blender et obligeraient les artistes à saisir manuellement les propriétés personnalisées à chaque fois, ce qui n'est pas une excellente expérience pour l'utilisateur. S'appuyer sur la saisie manuelle de texte serait également très propice aux erreurs, ce qui annulerait une grande partie de l'avantage de configurer les choses dans Blender en premier lieu. Passer d'un flux de travail basé sur les Prefabs à Blender nous a également fait regretter certains des avantages des Prefabs, comme le fait de disposer d'une belle bibliothèque d'objets à parcourir et à choisir. Heureusement, Blender, comme Unity, est très flexible et facilement extensible.
La réponse au problème de l'organisation des préfabriqués est venue dans Blender 3.2 avec les Asset Libraries. Ce système fonctionne un peu comme le système Prefab dans Unity : Il vous permet de créer des actifs dans un fichier séparé, puis de les importer dans votre scène Blender, tandis que les modifications apportées au fichier d'actifs se répercutent automatiquement dans la scène Blender. De plus, il s'assure que les propriétés personnalisées ou les colliders sont correctement appliqués à chaque instance de cet asset dans Blender.


Pour Blender, nous avons écrit un module complémentaire interne pour aider à configurer les propriétés personnalisées dans une interface utilisateur plus claire. Cela simplifie la définition de propriétés personnalisées en sélectionnant simplement les objets Blender concernés et en appuyant sur un bouton, au lieu de saisir chaque propriété manuellement.
Le module complémentaire Bundle Exporter est un module complémentaire open source que nous utilisons pour exporter tous nos fichiers FBX en un seul clic. Nous l'avons modifié pour qu'il fonctionne également avec des propriétés personnalisées et nous avons mis à jour l'interface utilisateur pour accélérer les exportations afin de répondre à nos besoins spécifiques.

La mise en place de notre workflow de conception de niveaux pour Breachers a nécessité un important investissement en temps au départ, mais nous pensons que c'était le bon choix pour le projet. En outre, c'était plutôt amusant !
Au fur et à mesure que nous construisions le jeu, depuis les premiers blocs jusqu'aux mois précédant la sortie finale, en passant par les tests alpha, l'itération sur nos niveaux s'est faite rapidement et sans douleur. Nous avons pu éliminer les frais généraux et la charge de travail pour nos concepteurs et nos artistes, tout en leur transférant des responsabilités pour lesquelles ils auraient auparavant eu besoin d'un développeur.
Nous avons été impressionnés par la capacité d'Unity et de Blender à s'intégrer aussi facilement l'un à l'autre, et nous sommes convaincus que cette intégration a été essentielle pour faire de Breachers un jeu dont nous sommes satisfaits et que nous sommes fiers de partager avec le monde entier.
Merci de votre lecture et bon jeu !

Le site Breachers de Triangle Factory est désormais disponible. Consultez d'autres blogs de développeurs de Made with Unity ici.
