Kampf
Der Kampf ist weniger ein diskretes System und mehr ein abstraktes – er ist die komplexe Interaktion mehrerer verschiedener Systeme, die zusammenarbeiten, und die Komplexität der Implementierung ist stark von der Komplexität des Designs abhängig.
In unserem Spiel ist der Design-Umfang sehr einfach. Der Spieler hat nur eine Angriffsmöglichkeit – auf einen Gegner zu springen. Feinde haben zwei verschiedene Möglichkeiten, den Spieler anzugreifen – Nahkampf und Kontakt, je nach Typ des Feindes.
Für den Angriff des Spielers und den gegnerischen Nahkampfangriff sind die Grundlagen fast genau dieselben. Wir haben eine oder mehrere Hitboxen auf dem Skelett-Mesh des Charakters platziert, basierend darauf, wie er im Nahkampf angreifen kann, zusammen mit einer oder mehreren Hurtboxen, um eine Annäherung an die Region zu erreichen, das wir als trefferprüfbar ansehen wollen.
Für den gegnerischen Angriff verwenden wir den Collider der gegnerischen Kapsel, um zu prüfen, ob der Spieler mit ihr in Kontakt gekommen ist, und führen dieselben Aktionen aus, die wir für den Nahkampf verwenden. Die Implementierung dessen, was passiert, wenn ein Charakter getroffen wird, findest du in unserer Charakter-Basis-Klasse: Parrot\Source\Parrot\Public\Character\ParrotCharacterBase.h. Die funktionale Logik ist hier und in den Subklassen ParrotPlayerCharacter.h und ParrotEnemyCharacterBase.h enthalten.
Der Spieler-Charakter
Die Konfiguration für den Spieler ist einzigartig in seiner Funktion beim Angreifen eines Feindes. Wenn sich der Spieler mit der Hurtbox eines Gegners überschneidet, gibt der Gegner diese Information an den Spieler weiter, um zu fragen, ob der Angriff gültig war. In diesem Fall wird geprüft, ob sich der Spieler über der Spitze der Hurtbox befindet, um zu gewährleisten, dass der Spieler oben landet und nicht von den Seiten oder unten getroffen wird. Wenn der Angriff gültig ist, fordert der Gegner den Spieler auf, einen Sprung auszuführen. Wenn der Spieler die Schaltfläche zum Springen noch gedrückt hält, wenn er mit der Hurtbox in Berührung kommt, springt er höher. Das Loslassen vor dem Kontakt mit der Hurtbox führt zu einem niedrigeren Sprung.
Der feindliche Charakter
Die Konfiguration für den Feind ist aus mehreren Gründen etwas komplizierter. Wir möchten, dass die Nahkampfangriffe realistisch wirken, daher sind die gegnerischen Hurtboxen an der Kante ihrer Waffen platziert. Die Hitbox(en), die Hurtbox(en) und der Kapsel-Collider sind im Viewport eines Blueprints für einen feindlichen Charakter zu sehen, wie z. B. der hier zu findende: Blueprints > Enemy > Skeleton > BP_EnemyCharacter_Skeleton.
In diesem Beispiel siehst du die Hurtbox am Kopf, die Hitbox an der Waffe und den Kapsel-Collider. Jeder dieser Trigger leitet seine Überlappungs-Events an Parent-Funktionen in der Charakter-Basisklasse weiter.
Darüber hinaus senden die Angriffsanimationen Benachrichtigungsevents, die die Waffen-Hitbox(en) nur während des Teils der Animation aktivieren, in dem die Waffe geschwungen wird. Auf diese Weise sieht es so aus und fühlt sich so an, als würde der Spieler tatsächlich von der Waffe getroffen werden und nicht nur mit einem Gegner in Kontakt kommen und zu einem beliebigen Zeitpunkt Schaden nehmen. Diese Animationmeldungen werden an bestimmten Punkten in die Angriffsanimation eingefügt, um die Hurtbox zu aktivieren und dann zu deaktivieren. Du kannst die Animationsmeldungen in Blueprints > Enemy/EnemyBase > BP_AnimNotify_EnemyAttackBegin und Blueprints > Enemy > EnemyBase > BP_AnimNotify_EnemyAttackEnd mit dem Setup in der Angriffsanimation eines bestimmten feindlichen Charakters sehen, z. B. Assets> Quaternius > PirateKit > Characters > Headless_Skeleton > Animations > Characters_Skeleton_Headless_Anim_CharacterArmature_Sword.
Der gegnerische Charakter ist derjenige, der auf Überlappungen prüft und Events triggert – das bedeutet, dass der Feind sowohl seine eigenen HitCharacter() als auch die HitCharacter()-Funktionen des Spielers triggert, wenn entsprechende Überlappungen entdeckt werden.
Du kannst den Code, der auf Hitbox- und Hurtbox-Überlappungen wirkt, hier sehen: Parrot\Source\Parrot\Public\Character\ParrotEnemyCharacterBase.h in den Funktionen HitBeginOverlap() und HurtBeginOverlap().
Bosskampf
Für unseren Bosskampf gibt es eine zusätzliche Funktion, wenn der Boss vom Spieler getroffen wird, um eine „Wut“-Sequenz abzuspielen. Du kannst den Blueprint-Code, der eine Boss-Reaktion auslöst, hier einsehen: Blueprints > Enemy > BossShark > BP_EnemyCharacter_BossShark.
Die „Wut“-Sequenz ist eine einfache zeitgesteuerte Sequenz, die eine „Kopfschüttel“-Animation abspielt, bevor sie die Laufgeschwindigkeit des Bosses erhöht und eine Niagara-Komponente mit grünen Flammen für VFX aktiviert. Während dieser Sequenz wird auch die Hurtbox deaktiviert, was den Boss vorübergehend unbesiegbar macht.