Comment Rubber Duck Games a développé un combat de boss dans Evil Wizard

RUBBER DUCK GAMES Anonymous
Aug 17, 2023|15 Min
Comment Rubber Duck Games a développé un combat de boss dans Evil Wizard
Cette page a été traduite automatiquement pour faciliter votre expérience. Nous ne pouvons pas garantir l'exactitude ou la fiabilité du contenu traduit. Si vous avez des doutes quant à la qualité de cette traduction, reportez-vous à la version anglaise de la page web.
Rubber Duck Games, l'un des lauréats du prix Best in Play de la GDC 2023, explique comment il a créé un combat de boss captivant. Dans ce blog, les membres de l'équipe Banki et Sergio Wajswol vous guident tout au long du processus, de la conception et du prototypage à l'animation, en passant par les tests, l'équilibrage et la finalisation des effets visuels et de l'audio pour Evil Wizard.

Bonjour, chers lecteurs ! Je suis Banki, concepteur de jeux et producteur chez Rubber Duck Games. Notre jeu d'action plein d'humour Evil Wizard est sorti sur Steam et Xbox, et je voulais vous montrer les coulisses du développement d'un combat de boss.

Evil Wizard est un jeu d'inspiration Metroidvania qui vous met dans la peau d'un "boss final" vaincu dans sa quête de vengeance contre le héros maudit.

Cette quête de vengeance emmène les joueurs dans de charmants environnements en pixel-art remplis à ras bord de hordes d'ennemis qu'ils doivent vaincre pour récupérer ce qui leur appartient. Alors que le personnage principal était autrefois un puissant sorcier, une bataille perdue aux mains du héros l'a privé de ses pouvoirs, et il doit les récupérer alors qu'il s'efforce d'infiltrer le château et de déclencher une vengeance dévastatrice.

Le premier héros à vaincre dans le jeu est Hailga, la puissante sorcière de glace. C'est elle qui nous servira d'exemple de patron pour cette plongée en profondeur.

Conception de Hailga

Commençons par le début. La conception d'un boss (et de tous les ennemis) pour Evil Wizard a été un peu délicate. Même si les joueurs se battent contre les gentils, nous savions qu'ils devaient avoir l'air suffisamment menaçants pour être reconnus comme des ennemis.

Pour les boss, nous avons cherché l'inspiration et les références parmi les héros de jeux connus. Pour Hailga, nous nous sommes beaucoup inspirés de Jaina de Warcraft, qui présente de nombreuses similitudes.

La première étape a consisté à préparer une feuille de calcul (que nous avons utilisée pour chaque boss du jeu) dans laquelle nous avons détaillé les principales caractéristiques du personnage, ses mécanismes et quelques références.

Exemple de feuille de calcul pour Evil Wizard's Hailga (Rubber Duck Games)

Une fois les mécanismes conçus, nous pouvons passer à l'étape suivante : le prototypage.

Prototypage Hailga

Il est temps de présenter à l'équipe le projet du nouveau patron. Nous nous retrouvons donc en réunion et je parcours le document en expliquant certaines de mes décisions.

Dans certains cas, un mécanisme pourrait être trop difficile à développer, ou une animation trop compliquée à dessiner, etc. Nous essayons de faire les choses dans les temps, il y a donc des choses à prendre en compte pour faire le meilleur patron possible dans le temps dont nous disposons.

En ce qui concerne le prototypage, voici ce que notre programmeur en chef, Diego Ordóñez, avait à dire : "Hailga a été notre premier boss sur Evil Wizard et la première fois de ma vie que j'ai programmé un boss. Je savais qu'il s'agissait d'une tâche difficile, alors j'ai commencé par faire ce que tout programmeur fait : diviser les attaques en tâches simples et les réaliser séparément. Ce boss a des attaques qui étaient simples à réaliser en réutilisant des projectiles".

"Les attaques de balles et de missiles de glace sont très différentes pour les joueurs : l'une est simple à esquiver, tandis que l'autre représente un défi pendant le combat", poursuit-il. "La principale différence réside dans la manière dont le composant d'attaque génère les projectiles de glace et dans la quantité de projectiles qui font face au joueur. Avec de simples ajustements, nous avons pu réutiliser un système entier pour présenter deux attaques différentes. Tout cela fonctionnait très bien jusqu'à ce que je doive commencer à faire l'attaque du blizzard".

Idée de base

Pour le combat de Hailga, nous voulions apporter quelque chose de nouveau à la rencontre et nous avons pensé que le vent pourrait être intéressant. C'était très différent de tout ce que nous avions fait sur Evil Wizard, j'ai donc dû repartir de zéro. L'idée de base était de faire apparaître du vent dans une direction aléatoire afin de déplacer le joueur vers un mur rempli de pointes pouvant causer des dégâts. Le meilleur moyen de contrer cette attaque est de se mettre à l'abri, c'est pourquoi nous avons placé quelques stalactites sur le champ de bataille pour bloquer le vent. Si les joueurs se retrouvent derrière une stalactite de glace, le vent n'émettra plus de force sur eux.

Développer l'éolien

Nous avons commencé par créer un composant d'attaque chargé de gérer les différents systèmes que nous utilisons. Les systèmes utilisés sont les stalactites, l'émetteur de vent et le blizzard VFX. Je vais me concentrer sur les deux premiers, et les VFX seront traités par Sergio Wajswol plus loin dans ce billet.

Les stalactites sont créées en utilisant un collisionneur de cercle pour obtenir des points aléatoires à l'intérieur du cercle, puis en utilisant ces positions pour créer une stalactite avec un décalage sur l'axe Y. En appliquant une coroutine, nous faisons tomber les objets en abaissant l'axe Y - des choses simples. Une fois les stalactites produites, nous sommes passés au régulateur de vent. Ce composant fonctionne comme un grand ventilateur de forme rectangulaire qui tourne autour d'un cercle.

Prototype de manette de vent dans un combat de boss du sorcier maléfique. (Jeux Rubber Duck)

Comme nous devions faire souffler le vent dans des directions aléatoires, nous avons dû orienter l'émetteur vers le centre pour que tout ce qui se trouvait à l'intérieur de la zone soit affecté. Le contrôleur de vent est doté d'un émetteur de vent qui enregistre la rotation, la direction et la position du vent. Lorsque nous faisons tourner le composant, l'émetteur calcule ces valeurs et les applique au vent (qui n'est qu'une direction et une force). Il s'agit en fait d'un Vector3 et d'un float.

Blocage du vent

Le vent peut également être bloqué, comme mentionné, par un coupe-vent. Ce composant comporte un BoxCollider2D qui vérifie les collisions avec le joueur. Si le joueur s'approche d'un coupe-vent, le OnTriggerEnter2D activera le coupe-vent et, lorsque le joueur quitte le collisionneur, le OnTriggerExit2D le désactivera. Ceci est illustré par la ligne cyan entre le joueur et l'émetteur dans l'image ci-dessous. Tant que la ligne est verte, le joueur est protégé.

Prototype du coupe-vent dans un combat de boss du sorcier maléfique. (Jeux Rubber Duck)
Réception du vent

Enfin, nous devions faire en sorte que le joueur reçoive la force du vent et se déplace dans la direction du vent. Pour ce faire, nous disposons d'un composant WindReceiver. Il est chargé de vérifier l'intensité et la direction de l'impact du vent sur le joueur. Cette information est recueillie en effectuant un Raycast du joueur vers le récepteur de vent. Les informations sont ensuite utilisées pour savoir si l'émetteur de vent a un impact sur le récepteur, avec quelle force et dans quelle direction. Une fois que nous disposons de toutes les informations, nous appliquons la force du vent à l'aide de notre propre contrôleur de mouvement et nous déplaçons le joueur dans la direction souhaitée.

Le comportement de Hailga

Alors que Diego commençait à commettre les premières attaques, j'ai commencé à donner un comportement à Hailga.

Pour l'IA de Evil Wizard, nous avons utilisé un outil très utile appelé Behavior Designer. Je ne saurais trop le recommander. C'est parfait pour les concepteurs de jeux qui ne codent pas. Le programmeur peut travailler sur les mécanismes et le concepteur les intègre à l'arbre de comportement du personnage, ce qui lui permet de fonctionner comme il le souhaite sans avoir à coder. Vous pouvez en apprendre les bases ici.

Voici l'arbre de comportement de Hailga :

Arbre de comportement du personnage de Hailga dans Evil Wizard. (Jeux Rubber Duck)

C'est un gros arbre, mais ne vous inquiétez pas, c'est plus facile qu'il n'y paraît.

En fait, nous avons utilisé certaines tâches au début de l'arbre pour préparer la bataille. Par exemple, pour placer le boss dans sa première phase, jouer l'animation d'introduction et réinitialiser certaines variables.

Vue statique de l'arbre de comportement du personnage de Hailga dans Evil Wizard. (Jeux Rubber Duck)

Ces tâches ne s'exécutent qu'au début du combat, nous avons donc ajouté un répétiteur qui aurait le comportement du boss, comme vous pouvez le voir dans l'image suivante.

Vue approfondie de l'arbre de comportement du personnage de Hailga dans Evil Wizard, montrant les comportements pour le combat du boss. (Jeux Rubber Duck)

La priorité du comportement du patron est toujours la santé. Grâce à elle, nous contrôlons si le boss doit passer à une autre phase ou même s'il doit mourir. Il faut donc d'abord se demander si le boss a plus de 75 % de santé. Si c'est le cas, nous exécutons les tâches de la phase 1, à savoir les pics de glace, les missiles de glace et l'invocation de slimes de neige (serviteurs du boss). Lorsque la santé du boss tombe en dessous de 75 %, l'arbre passe au sélecteur suivant en bas de l'image et exécute les tâches correspondant à la deuxième phase, et ainsi de suite jusqu'à ce que le boss atteigne sa phase finale et que le personnage meure à 0 santé.

Avant de passer à l'étape suivante, j'aimerais mentionner la fonction d'arbre de comportement externe, qui est un bon moyen d'organiser de grands arbres de comportement comme celui-ci.

Vous les avez déjà vus sur l'image précédente - les icônes avec trois cases sont des arbres de comportement externes.

Vue rapprochée d'un arbre de comportement externe en cours d'utilisation. (Jeux Rubber Duck)

Considérez les arbres de comportement externes comme une méthode dans votre code : vous appelez la méthode à plusieurs endroits dans toute la logique du jeu et elle exécute le même code à chaque endroit, mais vous n'avez ce code qu'à un seul endroit. Si vous devez changer quelque chose dans cette logique, vous modifiez le code de cette méthode et il sera modifié à chaque endroit où la méthode est appelée. Ici, cela fonctionne de la même manière. Vous disposez d'un arbre comportemental externe, qui contient le comportement permettant d'effectuer une action spécifique, par exemple "invoquer des limaces de neige".

Si j'entre dans notre arbre de comportement externe, je trouve ceci :

Arborescence du comportement externe pour "Summon snow slimes" dans Evil Wizard. (Jeux Rubber Duck)

C'est comme un mini arbre de comportement qui vérifie qu'un boss ne répète pas trop souvent la même attaque et qu'il n'y a pas trop de serviteurs sur le champ de bataille, puis qui invoque les serviteurs, joue les lignes de voix d'Hailga ou termine en mettant le boss au repos.

Si je veux changer le nombre de serviteurs qui peuvent être sur le champ de bataille à un moment donné, il me suffit de le modifier dans la tâche "Check Enemy Amount of Type" à l'intérieur de cet arbre comportemental externe, et cela fonctionnera pour chaque partie de l'arbre qui est utilisée pour invoquer des serviteurs.

Animer Hailga

Pour la création de Hailga, notre artiste principal, Ruben Gómez, est parti du principe de faire référence à des personnages existants en espérant que les joueurs les reconnaîtraient.

Dans ce cas, nous avons utilisé Jaina de Warcraft (comme mentionné) et Elsa de Frozen comme références de personnages.

Voici ce que Ruben a à dire :

"En gardant à l'esprit la prémisse, j'ai commencé par la conception de Hailga", a déclaré Ruben. "Nous avons pris certaines caractéristiques des vêtements et des coiffures de chaque référence, des éléments qui pourraient être facilement reconnaissables dans un sprite pixelisé très petit, et nous avons rempli le reste avec de l'imagination (pas d'IA, juste de l'imagination humaine, la même que celle que j'utilisais quand j'étais enfant)."

Premiers prototypes pour l'animation du personnage Hailga dans Evil Wizard. (Jeux Rubber Duck)

Pendant l'animation, nous avions besoin que les mouvements aillent vite sans perdre la fluidité entre les images, nous avons donc essayé de gagner du temps avec des itérations plus rapides pour l'action de chaque personnage. Nous partons toujours de la version finale, en recadrant, réarrangeant, mettant à l'échelle et faisant pivoter chaque partie du personnage pour chaque image de l'animation en utilisant l'interpolation la plus proche avec l'intention de réutiliser certains éléments et d'éviter l'anticrénelage.

Nous avons ensuite procédé à un test rapide des mouvements et ajusté de la même manière.

Exemple de test de mouvement pour les animations Hailga dans Evil Wizard. (Jeux Rubber Duck)

Une fois le projet d'animation terminé, nous avons affiné chaque élément, comblé les espaces vides et ajouté des détails.

Vous pouvez voir la version finale de chaque cadre dans l'image suivante.

Dernier regard sur les animations Hailga pour Evil WIzard, montrant les améliorations par rapport au projet initial. (Jeux Rubber Duck)
Essais et équilibrage

Pendant que les animations étaient en cours, j'ai testé et équilibré le combat du boss. Pour cela, nous avons créé une scène appelée "Zone de combat", que nous avons utilisée pour tester les boss, les ennemis, les sorts, etc. En fait, il s'agit d'une petite zone qui dispose de tous les outils et de toutes les fonctionnalités dont nous avons besoin pour tester le jeu sans le toucher.

Voici à quoi ressemblait le premier boss de Hailga lorsque nous avons testé le personnage dans la scène de la zone de combat :

Premier aperçu des animations du boss Hailga dans une scène test pour Evil Wizard. (Jeux Rubber Duck)
Premier aperçu des animations du boss Hailga dans une scène test pour Evil Wizard. (Jeux Rubber Duck)

Enfin, lorsque nous avons été satisfaits de son comportement, de sa fonctionnalité et de sa difficulté, nous avons intégré Hailga à sa place dans le jeu.

Vue du placement final des animations du boss Hailga dans Evil Wizard. (Jeux Rubber Duck)
Le temps des effets spéciaux

Lorsque nous avons terminé le comportement et les animations de Hailga, nous avons commencé à intégrer les animations du patron en utilisant l'outil AnimatorImporterqui est un excellent outil pour intégrer les animations en pixel art faites dans Aseprite. Avec lui, en quelques étapes seulement, tout est fait.

Il est maintenant temps de donner de la saveur au patron, et c'est là que notre artiste VFX, Teky, est entré en jeu. Prends-le, Teky :

Hé ! Sergio Wajswol (a.k.a. Teky), programmeur et artiste VFX pour Evil Wizard.

Les effets visuels de Hailga ont constitué un véritable défi, non seulement parce qu'il s'agissait du premier boss de l'équipe, mais aussi parce que c'était l'une de mes premières tâches sur le jeu. Il y a plusieurs séquences VFX employées pendant le combat de boss - au moins une par attaque - mais je vais centrer mon attention sur quelques-unes seulement.

L'un des moments les plus forts de la bataille est la dernière transition de phase au cours de laquelle Hailga s'énerve et lance un rayon de glace vers le sorcier maléfique, laissant le champ de bataille gelé.

Aperçu de l'effet du rayon de glace dans le combat du boss Hailga du sorcier maléfique. (Jeux Rubber Duck)

Je pense qu'il s'agit là d'un effet très intéressant à décortiquer et à montrer les éléments qui ont permis à la magie d'opérer. Pour ce faire, nous avons divisé la transition en deux éléments VFX : la poutre de glace et la congélation du sol.

Pour la première pièce, mon travail commençait dès que Diego avait fini de programmer l'attaque et s'accompagnait généralement d'un joli espace réservé (dans ce cas, un rectangle allongé) - et d'un souhait de bonne chance de sa part. À partir de là, je me suis lancée en utilisant les outils que je savais déjà avoir dans ma boîte à outils. Mais comme c'était le début du développement, je n'en avais pas assez. Dans le passé, j'avais utilisé le composant Line Renderer d ' Unity pour obtenir le rendu d'une ligne entre deux points contrôlés par script. J'ai donc commencé par cela, puis je l'ai combiné avec un shader de base pour ajouter de la couleur aux bords et au centre de la ligne.

Le composant Unity Line Renderer en action dans une scène d'Evil Wizard. (Jeux Rubber Duck)

Ce n'est pas tout à fait le cas, comme vous pouvez le voir ci-dessus. Une chose que j'ai rapidement comprise dans le domaine des effets visuels, c'est que (contrairement à la philosophie classique), "le tout est la somme des parties". Je veux dire par là qu'il faut plusieurs systèmes pour obtenir l'effet désiré, et pas seulement un shader ou une particule.

Ensuite, j'avais besoin que l'effet ressemble davantage à une poutre (et qu'il soit moins solide), j'ai donc joué avec le Shader Graph pour y parvenir. Je vais essayer de l'expliquer brièvement.

Pour réaliser ce que je voulais, le shader avait besoin de trois parties principales. Tout d'abord, j'ai utilisé une texture précédemment dessinée qui n'était qu'un dégradé horizontal en miroir (vous pouvez la voir dans l'image suivante en tant que MainTex). En utilisant le nœud "Pow", je peux facilement contrôler la largeur du faisceau (la texture se multiplie et, puisqu'il s'agit d'un gradient, rétrécit le faisceau).

Vue de l'éditeur Unity des parties du Shader Graph utilisées pour l'effet de rayon de glace dans Evil Wizard. (Jeux Rubber Duck)

Ensuite, j'ai utilisé Simple Noise animé avec le nœud Tiling And Offset pour deux raisons :

Dissoudre la poutre dans certaines parties (toujours contrôlées par une variable publique)

Modifier les UV du faisceau, ce qui lui donne un aspect déformé.

Vue de l'éditeur Unity des parties du Shader Graph utilisées pour l'effet de rayon de glace dans Evil Wizard. (Jeux Rubber Duck)

En continuant, j'ai multiplié le faisceau résultant par une couleur HDR afin de contrôler la lueur émise. Enfin, j'ai pris les bords de la poutre en utilisant le nœud de pas et je les ai multipliés pour obtenir une couleur différente, laissant le centre de la poutre ressortir.

Une fois que j'ai terminé, j'ai eu quelque chose comme ça pour jouer avec différentes couleurs et variables.

Vue de l'éditeur Unity des ajustements apportés à l'effet de faisceau de glace dans Evil Wizard. (Jeux Rubber Duck)

C'est à ce moment-là que j'ai commencé à sentir que j'avançais, mais j'ai remarqué qu'il me manquait quelque chose : le faisceau était lancé depuis le milieu de nulle part.

Avec l'aide de particules, j'ai donc créé une sphère de glace pour qu'elle serve de point de lancement du faisceau :

Vue de l'éditeur Unity de la sphère de glace créée pour être le point de lancement de l'effet de faisceau de glace dans Evil Wizard. (Jeux Rubber Duck)

Enfin, nous avions besoin de particules le long du faisceau pour l'intégrer au reste de la zone.

Vue de l'éditeur Unity de la création de particules intégrées le long de l'effet de faisceau de glace dans Evil Wizard. (Jeux Rubber Duck)

La deuxième partie est plus courte, mais plus délicate. Pour compléter l'effet principal, nous devions être en mesure de passer d'une texture à l'autre - un sol non gelé et un sol gelé - mais à un angle radial suivant la trajectoire et la vitesse du faisceau.

Pour adapter la vitesse, nous avons utilisé un script régulier pour contrôler la vitesse de la poutre par rapport à une variable de 0 à 1, c'est-à-dire le degré de gel du sol en fonction de la rotation actuelle de la poutre. Pour le lissage des textures, nous avions besoin d'un shader court. Regardez comment nous avons divisé le shader en deux parties pour obtenir un gradient radial et un lerping réel.

Vue de l'éditeur Unity du shader de texture lerping pour Evil Wizard. (Jeux Rubber Duck)

Voici la formule appliquée pour calculer le gradient radial, en tenant compte de la position de l'UV et en allant exactement de 0 à 1. Le mouvement du faisceau est ainsi synchronisé avec la valeur gelée.

Mise à jour de la vue de l'éditeur Unity du shader de texture lerping pour Evil Wizard avec une formule de gradient radial appliquée. (Jeux Rubber Duck)

Voici ce qu'il en est sur place :

Vue de l'effet du shader de texture lerping en action dans une scène d'Evil Wizard. (Jeux Rubber Duck)

Pour compléter la scène, nous avons tout ajouté ensemble et obtenu un effet cool, servant à la fois de transition vers la phase finale et de l'une des attaques de ce boss.

Conclusion

Une fois le tout terminé, Haakon Davidsen, le compositeur du jeu, a ajouté la touche finale : une musique époustouflante qui permet aux joueurs de ressentir la "chaleur" de la bataille. Vous pouvez l'écouter ici. Et, bien sûr, une doubleuse - Breanna MacDowall - a fait un travail remarquable en donnant une voix à Hailga.

Nous espérons que vous avez apprécié ce blog !

Découvrez le combat de boss d'Hailga par vous-même en découvrant Evil Wizard sur Steam ou Xbox - et restez à l'affût de sa sortie sur d'autres plateformes. Pour en savoir plus sur les histoires de Made with Unity en direct des développeurs , cliquez ici.