Combat
Le combat est plus un système abstrait qu'un système isolé. C'est le fruit d'interactions complexes de plusieurs systèmes différents qui fonctionnent ensemble. Ainsi, plus la conception du combat est poussée, plus le développement l'est également.
Pour ce jeu, les combats sont très simples. Le joueur dispose d'un seul moyen d'attaquer : sauter sur un ennemi. Les ennemis ont deux façons différentes d'attaquer le joueur : frapper ou être au contact direct, selon le type d'ennemi.
Pour l'attaque du joueur et l'attaque de frappe de l'ennemi, les principes de base sont presque exactement les mêmes. On utilise une ou plusieurs boîtes de collision placées sur le maillage squelettique du personnage en fonction de la façon dont il peut attaquer en frappant. On utilise aussi une ou plusieurs boîtes de dégâts pour représenter approximativement la zone que nous voulons rendre sensible aux coups.
Pour l'attaque de contact de l'ennemi, nous utilisons le collisionneur de capsule de l'ennemi pour vérifier si le joueur est entré en contact direct avec lui et effectuer les mêmes actions de dégâts que lorsque l'ennemi frappe le joueur. Pour voir l'implémentation de ce qui se passe lorsqu'un personnage est touché, voici le chemin de notre classe de base de personnage : Parrot\Source\Parrot\Public\Character\ParrotCharacterBase.h. C'est ici que réside la logique fonctionnelle, mais elle se trouve aussi dans les sous-classes ParrotPlayerCharacter.h et ParrotEnemyCharacterBase.h.
Le personnage joueur
La configuration du joueur a un fonctionnement particulier pour attaquer l'ennemi. Lorsque le joueur chevauche la boîte de dégâts d'un ennemi, ce dernier transmet cette information au joueur pour lui demander si l'attaque était valable. Dans ce cas, il vérifie si le joueur se trouve au-dessus du haut de la boîte de dégâts pour s'assurer qu'il atterrit dessus, sans toucher les côtés ou le dessous. Si l'attaque est valide, l'ennemi fait effectuer un saut au joueur. Si le joueur maintient toujours le bouton de saut lorsqu'il entre en contact avec la boîte de dégâts, il sautera plus haut. En revanche, si le joueur relâche le bouton avant d'entrer en contact avec la boîte de dégâts, il sautera moins haut.
Le personnage ennemi
La configuration de l'ennemi est un peu plus compliquée pour plusieurs raisons. Nous voulons que les attaques de frappe paraissent réalistes, c'est pourquoi les boîtes de dégâts des ennemis sont placées sur le bord de leurs armes. La configuration des boîtes de collision, des boîtes de dégâts et des collisionneurs de capsule est visible dans le hublot du blueprint de personnage ennemi, comme celui que vous trouverez ici : Blueprints > Enemy > Skeleton > BP_EnemyCharacter_Skeleton.
Dans cet exemple, vous pouvez voir la boîte de dégâts sur la tête, la boîte de collision sur l'arme et le collisionneur de capsule. Chacun de ces déclencheurs transmet ses événements de chevauchement aux fonctions parentes de la classe de base du personnage.
En outre, les animations d'attaque envoient des événements de notification qui n'activent les boîtes de collision de l'arme que pendant la partie de l'animation où l'ennemi donne un coup avec son arme. De cette manière, on dirait que le joueur est réellement touché par l'arme, et pas seulement entré en contact avec un ennemi en subissant des dégâts à un moment aléatoire. Ces notifications d'animation sont insérées dans l'animation de l'attaque à des moments précis pour déclencher l'activation puis la désactivation de la boîte de dégâts. Vous pouvez voir la notification d'animation dans Blueprints > Enemy/EnemyBase > BP_AnimNotify_EnemyAttackBegin et Blueprints > Enemy > EnemyBase > BP_AnimNotify_EnemyAttackEnd avec la configuration de l'animation d'attaque d'un personnage ennemi spécifique, comme Assets > Quaternius > PirateKit > Characters > Headless_Skeleton > Animations > Characters_Skeleton_Headless_Anim_CharacterArmature_Sword.
Le personnage ennemi est celui qui vérifie les chevauchements et déclenche les événements. Cela signifie que l'ennemi déclenche ses propres fonctions HitCharacter(), mais aussi les fonctions HitCharacter() du joueur lorsque des chevauchements appropriés sont détectés.
Vous pouvez voir le code qui agit sur les chevauchements de la boîte de collision et de la boîte de dégâts ici : Parrot\Source\Parrot\Public\Character\ParrotEnemyCharacterBase.h dans les fonctions HitBeginOverlap() et HurtBeginOverlap().
Combat de boss
Pour notre combat de boss, il y a une fonctionnalité supplémentaire lorsque le boss est touché par le joueur afin de jouer une séquence de "rage". Vous pouvez consulter le code qui déclenche la réaction du boss ici : Blueprints > Enemy > BossShark > BP_EnemyCharacter_BossShark.
La séquence de "rage" est une simple séquence programmée : d'abord, le boss lance une animation dans laquelle ile secoue la tête, puis il se met à courir (en augmentant sa vitesse de marche) en activant un composant Niagara pour faire apparaître des effets visuels de flammes vertes. Cette séquence désactive également la boîte de dégâts pour que le boss soit invincible pendant un certain temps.