Walka
Walka nie jest systemem odrębnym, a raczej abstrakcyjnym – jest to złożona interakcja kilku różnych systemów współpracujących ze sobą, a złożoność jej realizacji w dużym stopniu zależy od złożoności projektu.
W naszej grze zakres projektu jest bardzo prosty. Gracz ma do dyspozycji jeden sposób ataku – skakanie na głowę przeciwnika. Przeciwnicy mają dwa różne sposoby zaatakowania gracza – walkę wręcz lub kontakt, w zależności od typu przeciwnika.
Podstawy ataku gracza i ataku wręcz przeciwnika są niemal identyczne. W zależności od sposobu ataku wręcz, na siatce szkieletowej postaci mamy umieszczone jedno lub więcej pól trafienia, a także jedno lub więcej pól obrażeń, aby przybliżyć obszar, który chcemy poddać testom trafień.
W przypadku ataku poprzez kontakt z przeciwnikiem używamy obiektu kolizyjnego w kształcie kapsuły przeciwnika, aby sprawdzić, czy gracz wszedł z nim w kontakt, i wykonujemy te same akcje trafienia, co w przypadku walki wręcz. Możesz zobaczyć implementację tego, co dzieje się, gdy postać zostaje trafiona, w naszej klasie bazowej postaci, znajdującej się tutaj: Parrot\Source\Parrot\Public\Character\ParrotCharacterBase.h. Logika funkcyjna została zawarta tutaj oraz w podklasach ParrotPlayerCharacter.h i ParrotEnemyCharacterBase.h.
Postać gracza
Konfiguracja gracza jest wyjątkowa pod względem sposobu działania podczas ataku na przeciwnika. Gdy gracz nakłada się na obszar obrażeń przeciwnika, przeciwnik przekazuje tę informację graczowi, pytając, czy atak był prawidłowy. W tym przypadku sprawdza się, czy gracz znajduje się nad górną krawędzią pola obrażeń, aby upewnić się, że gracz ląduje na nim, a nie uderza z boku lub od dołu. Jeśli atak jest prawidłowy, przeciwnik sygnalizuje graczowi, aby wykonał skok. Jeśli gracz nadal trzyma przycisk skoku w momencie zetknięcia się z polem obrażeń, skoczy wyżej. Zwolnienie przycisku przed zetknięciem się z polem obrażeń spowoduje niższy skok.
Przeciwnik
Konfiguracja przeciwnika jest nieco bardziej skomplikowana z kilku powodów. Chcemy, aby ataki wręcz wyglądały realistycznie, więc pola obrażeń przeciwników umieszczono na krawędziach ich broni. Konfigurację pól trafienia, pól obrażeń i obiektu kolizyjnego w kształcie kapsuły można zobaczyć w oknie wizualizacji blueprintu postaci przeciwnika, takiego jak ten znajdujący się tutaj: Blueprints (Blueprinty) > Enemy (Przeciwnik) > Skeleton (Szkielet) > BP_EnemyCharacter_Skeleton.
W tym przykładzie widać pole trafienia na głowie, pole obrażeń na broni oraz obiekt kolizyjny w kształcie kapsuły. Każdy z tych wyzwalaczy kieruje zdarzenia nakładające się na funkcje nadrzędne w klasie bazowej postaci.
Ponadto animacje ataku wysyłają zdarzenia powiadamiające, które włączają pole trafienia na broni tylko podczas tej części animacji, w której następuje zamach bronią. Dzięki temu wygląda to tak, jakby gracz został faktycznie trafiony bronią, a nie tylko zetknął się z przeciwnikiem i otrzymał obrażenia w dowolnym momencie. Te powiadomienia animacji są wstawiane w animacji ataku w określonych momentach, aby włączyć, a następnie wyłączyć obszar obrażeń. Animację można zobaczyć w Blueprints (Blueprinty) > Enemy/EnemyBase > BP_AnimNotify_EnemyAttackBegin oraz Blueprints (Blueprinty) > Enemy (Przeciwnik) > EnemyBase > BP_AnimNotify_EnemyAttackEnd wraz z ustawieniami w animacji ataku konkretnego przeciwnika, np. Assets (Zasoby) > Quaternius > PirateKit > Characters (Postacie) > Headless_Skeleton > Animations (Animacje) > Characters_Skeleton_Headless_Anim_CharacterArmature_Sword.
Przeciwnik jest postacią, która sprawdza, czy doszło do nakładania się obiektów i wyzwala zdarzenia – oznacza to, że przeciwnik wyzwala zarówno własną funkcję HitCharacter(), jak i funkcję HitCharacter() gracza, gdy wykryje odpowiednie nakładanie się postaci.
Kod odpowiedzialny za działania w przypadku nakładania się pól trafienia i obrażeń można znaleźć tutaj: Parrot\Source\Parrot\Public\Character\ParrotEnemyCharacterBase.h w funkcjach HitBeginOverlap() i HurtBeginOverlap().
Walka z bossem
W walce z bossem dostępna jest dodatkowa funkcjonalność, która uruchamia sekwencję „wściekłości”, gdy boss zostanie trafiony przez gracza. Kod blueprintu wyzwalający reakcję bossa można wyświetlić tutaj: Blueprints (Blueprinty) > Enemy (Przeciwnik) > BossShark > BP_EnemyCharacter_BossShark.
Sekwencja „wściekłości” to prosta sekwencja czasowa, która odtwarza sygnalizowaną animację „potrząsania głową”, a następnie zwiększa prędkość chodzenia bossa i włącza komponent Niagara zielonego płomienia dla efektu wizualnego (VFX). Podczas tej sekwencji pole obrażeń jest nieaktywne, dzięki czemu boss staje się niepokonany.