Cet article provient de l’équipe d’Assassin’s Creed. Vous pouvez trouver le blogue original ici.
Bienvenue dans cet article du blog des développeurs ! Aujourd’hui, nous tenions à vous parler du processus de création de la compétence Renvoi de projectile.
Avant toute chose, jetons un coup d’œil au produit fini !
Pour le développement de chaque nouvelle fonctionnalité, tout commence par la conception. Dans le cas de Renvoi de projectile, l’intention était la suivante : attraper en vol une flèche qui vous est destinée et la réexpédier à l’envoyeur par le biais d’une parade. L’étape suivante consistait à créer une animation prototype.
Après avoir créé cette animation, nous l’avons intégrée au moteur de jeu pour en tirer un prototype. Nous disposions déjà d’un système capable d’afficher des animations à partir d’un ensemble d’entrées et de conditions. Grâce à ce système, nous avons pu « écouter » l’entrée liée à la parade et vérifier la survenue d’une condition que nous avions appelée « de visée/tir sur ». Cette dernière visait à déterminer si l’action du renvoi devait être déclenchée ou non. Pour le prototype, nous avons décidé de laisser de côté la saisie du projectile en plein vol et le produit final consistait simplement à renvoyer la flèche à l’adversaire sur lequel le joueur était verrouillé.
Ceci nous a permis d’intégrer le tout au jeu en quelques heures !
Comme vous pouvez le constater, c’est encore trop rudimentaire pour avoir sa place dans le jeu final, mais cela a validé le concept et indiqué quels étaient les éléments dont nous avions besoin. Nous voulions aussi pouvoir appliquer la compétence à d’autres types de projectiles, avec pour exceptions les projectiles lourds ou volumineux comme les barriques et les cadavres.
Une fois le prototype réalisé, il nous fallait déterminer comment la détection permettrait d’activer la compétence. Dans la mesure où la condition « tir sur » mesurait uniquement si le PNJ était en train de tirer, le joueur pouvait activer la compétence avant que la flèche soit tirée, ou, s’il était trop éloigné, le PNJ pouvait quitter son état de tir avant que la flèche approche le joueur. Il nous fallait par conséquent un moyen plus fiable de détecter si le joueur était sur le point d’être atteint par un projectile. Heureusement, nous tenons une liste de tous les projectiles, ce qui nous permet de vérifier des choses telles que la durée de vol avant impact et le caractère menaçant de la trajectoire pour le joueur.
Avec cette nouvelle condition, l’étape suivante était de renvoyer le projectile. Dans la version prototype, le renvoi fonctionnait correctement, mais dirigeait le projectile vers le PNJ sur lequel le joueur était verrouillé, ce qui ne pouvait faire l’affaire dans le jeu final. Par chance, comme nous conservons l’identité du tireur dans les données du projectile (pour des raisons de calcul des dégâts), nous pouvions exploiter cette information pour définir la cible et régler la question du retour à l’envoyeur.
L’une des dernières étapes du développement initial fut la saisie du projectile. L’apparence dans le jeu étant à ce stade correcte, nous avons décidé de tout simplement faire disparaître la flèche en approche pour en faire apparaître une autre dans la main du joueur à l’instant approprié. Enfin, nous avons orienté l’animation dans la direction du tireur et le tour était joué. Il était désormais possible « d’attraper » des projectiles et de les réexpédier à l’envoyeur !
Il restait à peaufiner un peu le tout.
Le joueur pouvant appuyer sur la commande de parade lorsque le projectile est sur le point de l’atteindre ou, au contraire, alors qu’il est encore très éloigné, la saisie en vol pouvait être trop tardive ou trop précoce. Il nous fallait trouver un moyen de synchroniser l’animation de saisie à l’emplacement correct du projectile. Pour ce faire, nous avons « joué » sur la durée de l’animation en accélérant ou ralentissant sa diffusion.
Nous avons dû calculer un ratio temporel de diffusion de l’animation, égal à 1 pour la vitesse normale, à 0,5 pour une vitesse réduite de moitié, etc. Nous l’avons fait dans la machine d’état de l’animation, qui est l’endroit où nous gérons quelle animation est diffusée.
La case rose (coin inférieur gauche) est la distance entre la flèche et le personnage du joueur. Cette information est transmise au moteur d’animation par le code.
Lorsque tout fonctionne, on ajoute une caméra afin de présenter l’action.
Si vous vous souvenez, nous souhaitions appliquer cette compétence à de nombreux types de projectiles. Pour l’instant, l’affaire était réglée pour un projectile sur dix, mais heureusement, la plupart des éléments demeuraient identiques.
Si le code de détection restait le même, l’animation, elle, variait selon le projectile (par exemple, elle est différente pour une flèche et un bouclier). Il nous fallait également implémenter la saisie du projectile. Nous pouvions certes réutiliser certains éléments tirés de la technologie du ramassage d’arme, mais il fallait ajouter au code du projectile une indication de type « quand tu es attaché à quelque chose, tu cesses de te déplacer » afin que le projectile s’arrête dès qu’il est saisi par le personnage. Nous avons ensuite ajouté une méthode de différenciation des types de projectiles afin d’avoir une animation appropriée pour chacun.
Si cela n’était pas très difficile pour les autres armes que les flèches, nous souhaitions également pouvoir renvoyer autre chose que des armes ! La technologie développée pour ramasser des armes ne pouvait pas s’appliquer aux pierres ou aux bombes lancées par les ennemis. Nous disposions cependant d’une méthode de rattachement d’un objet à un « os », ce qui nous permettait de lier le projectile à un « os d’arme », nous garantissant des résultats similaires, même si les choses sont très différentes en coulisses.
En raison d’une faute de frappe lors du codage, on a obtenu un rattachement à la personne qui envoyait le projectile au lieu du projectile lui-même ! Oups…
Une crise de fou rire et quelques clics plus tard, tout était corrigé. À ce stade, il ne restait que quelques réglages à apporter, notamment sur la synchronisation finale.
Nous avons rencontré quelques soucis intéressants lors du développement de cette fonctionnalité. Par exemple, un rapport en interne parlait d’un situation où « lorsqu’il y a des flèches à proximité, le personnage du joueur entame une séance de yoga après appui sur la commande de parade ». Oh-oh…
Les rapports de bogues sont généralement accompagnés d’une vidéo. Avant toute chose, nous prenons le temps de la regarder.
Il est tout de suite apparu qu’il s’agissait d’un problème de ratio temporel de l’animation, mais nous en ignorions la cause. Nous pouvions consacrer pas mal de temps à tenter de l’identifier ou mettre en place une mesure de sécurité évitant sa survenue. Nous avons choisi la deuxième possibilité et ajouté à nos calculs une formule indiquant que « le projectile ne doit pas se trouver à plus de 9 mètres ». De ce fait, l’animation voit sa vitesse réduite de près de la moitié.
L’un des animateurs a aussi envoyé à l’équipe une vidéo intitulée « Bye ! »
Elle était très drôle, mais ne correspondait pas au réalisme que nous désirions dans le jeu. Il existait un correctif rapide : modifier l’impact physique de l’attaque. Nous avons donc transformé la valeur « loufoque » en « crédible ».
Un problème ne cessait de réapparaître, celui de l’affichage de l’animation, mais sans renvoi effectif de projectile. Si l’identification et la correction de tous les soucis ont réclamé pas mal de temps, il en est un qui mérite que l’on s’attarde sur lui : le personnage du joueur se défaisant de son arc alors qu’il tente d’attraper une flèche. Pour être francs, c’est un cas auquel nous n’avions jamais songé !
Nous l’avons résolu en procédant à deux vérifications : la première, si le personnage possède un arc et la seconde, s’il n’en a pas.
Ce problème n’est pas lié à Renvoi de projectile proprement dit, mais le PNJ porte-étendard se débarrassait de son drapeau alors qu’il ne devait pas.
On ne s’en lasse pas.
Nous espérons que la lecture de cet article vous aura enseigné deux choses :
- Il n’est pas facile de produire un jeu : il faut garder à l’esprit d’innombrables facteurs, et même une tâche qui paraît simple et minime au premier abord peut réclamer beaucoup de temps.
- Mais c’est sacrément fun : il n’est pas toujours facile de régler les problèmes et on se sent parfois tout petit en découvrant que la solution géniale que l’on vient de trouver ne donne pas les résultats escomptés. Les bogues sont pénibles, mais ils font partie du développement d’un jeu. Leur élimination peut se révéler fun, et le résultat en vaut la peine !
Merci de votre lecture!