Kollisionstypen
Kollisionen in Unreal Engine sind ähnlich wie in Unity, haben aber einige Unterschiede, die hier behandelt werden. Wenn du die Layer-basierte Kollisionserkennung von Unity verwendet hast, sollten die Kollisionseinstellungen des Projekts ähnlich wie die Kollisionsmatrix aussehen. Du kannst darauf zugreifen, indem du zu Bearbeiten > Projekteinstellungen > Kollision gehst. Wenn du den Tab Voreinstellungen aufklappst, siehst du alle voreingestellten Profile mit einer Beschreibung ihrer Funktionen.
Du wirst feststellen, dass Unreal ein paar mehr Optionen hat, wenn es um die Auflösung von Kollisionen geht. Diese werden in der Unreal Engine Collision Overview ausführlich behandelt. Dieser Grad an Granularität bei der Kollisionserkennung ist sehr nützlich und kann die Leistung deines Spiels verbessern. Das ist wichtig zu verstehen:
Kanäle oder einzelne Kollider können auf Blockieren, Überlappung oder Ignorieren eingestellt werden.
Ein häufiger Fehler ist, dass das Kontrollkästchen „Überlappungsevents generieren“ bei den Kollidern nicht korrekt gesetzt ist, wenn du diese Events brauchst.
Statische Geometrie sollte blockieren und überlappen, aber nicht unbedingt Überlappungs- oder Trefferevents erzeugen, da dies für das Gameplay nicht erforderlich ist.
Überlappungsevents können auch dann erzeugt werden, wenn ein Objekt ein anderes blockiert – insbesondere bei hohen Geschwindigkeiten. In Unity kann dies ein Problem sein, wenn man die Verschiebung direkt modifiziert, anstatt eine Rigidbody-Komponente zu verwenden. Auf diese Weise werden Physik-Aspekte umgangen.
Wenn du in Unreal eine Funktion aufrufst, die die Transformation eines Actors aktualisiert, gibt es zwei boolesche Parameter, die festlegen, wie du den Actor bewegen möchtest:
Wenn Sweep auf true gesetzt wird, werden Überlappungen getriggert und der Actor kurz vor dem Ziel angehalten, wenn er blockiert ist. Teleport bestimmt, ob die Physik-Geschwindigkeit beibehalten wird oder nicht.
Kanäle können auch für Traces verwendet werden, die dem Physik-Cast von Unity entsprechen (d.h. Raycast, SphereCast etc.). Du kannst den Kanal während deines Aufrufs der Linien-Trace-Funktion genauso übergeben, wie du die Ebenenmaske in einem Raycast in Unity übergeben würdest.
Benutzerdefinierte Kollisionsformen in „Parrot“
„Parrot“ hat ein paar benutzerdefinierte Kollisionsobjektkanäle eingerichtet: Spieler, Kanonenkugel und Feind.
Durch das Hinzufügen dieser Objekttypen kann „Parrot“ genau steuern, wie diese Objektkanäle mit Trace-Kanälen interagieren, wenn Kollisionsspuren in der Welt auftreten. Es ist eine Standardreaktion dafür vorgegeben, was in der Regel geschehen soll – diese kann jedoch nach Wunsch angepasst werden. „Parrot“ verfügt auch über einige benutzerdefinierte Voreinstellungen für Trace-Kanäle: Player, OverlapAllPlayers, BlockAllPlayers, Cannonball und Enemy.
Diese Voreinstellungen sind besonders nützlich für Gameplay-Trigger. Zum Beispiel kann OverlapAllPlayers alle anderen Kollisionen ignorieren und nur auf Kollisionsevents mit Spieler-Kollisionsobjekttypen reagieren. Wenn du dir die Kollisionseinstellungen für verschiedene Meshes im Spiel ansiehst, wirst du sehen, dass diese Voreinstellungen häufig verwendet werden.
Die Kollisionseinstellungen können auf Wunsch auch für jedes einzelne Mesh angepasst werden.
Weltgrenzen
Bei der Erstellung deiner Level solltest du die Weltgrenzen beachten. Dies kann in Welteinstellungen > Welt eingestellt werden. Du kannst einen benutzerdefinierten Schadenstyp implementieren, wenn ein Actor mit diesen definierten Weltgrenzen interagiert. Grenzen in „Parrot“ verwenden eine Kombination aus der KillZ-Welt-Einstellung und Out of Bounds-Triggervolumen.
Trigger-Volumen
Unreal Engine hat eingebaute Trigger-Volumen-Actors (siehe Trigger-Volumen-Actors in Unreal Engine), die zum Triggern von Events verwendet werden können. Beispiele, in denen Entwickler diese in „Parrot“ verwenden, sind Trigger-Volumen für Out Of Bounds und Finish Line. Trigger-Volumen werden oft in Verbindung mit dem Level Blueprint verwendet (siehe Entwicklerdokument Level-Blueprints in „Parrot“), müssen es aber nicht. In „Parrot“ ist der Trigger für Out Of Bounds ein Box-Trigger mit einem einfachen Event Graph:
Wenn du dir die Kollisionseinstellungen des Actors im Details-Panel ansiehst, wirst du sehen, dass die Voreinstellung des Kollisionskanals hier die meiste Arbeit macht.
Power-Abholpunkt
Werfen wir einen Blick auf ein praktisches Beispiel für das Kollisionssystem mit der Umsetzung des Powerup-Abholpunkts in „Parrot“. Wenn du BP_AbholpunktBase unter Inhalt > Blueprints > Abholpunkte öffnest und dir den Viewport ansiehst, kannst du die Hierarchie sehen, die die Kollisionskomponente enthält.
Die Kollisionseinstellungen und die Out of Bounds haben eine Trigger-Voreinstellung, die Überlappungsevents mit Spielern erzeugt:
Im Event Graph siehst du das Event ActorBeginOverlap mit Other Actor als Parameter. Dieses Event funktioniert ähnlich wie OnCollisionEnter in Unity. Der Unterschied besteht darin, dass hier nicht eine Kollisionskomponente, sondern der Actor selbst übergeben wird.
„Parrot“ prüft, ob der Actor ein Spieler ist, der die Überlappung bewirkt. Dann wird das Event OnPickedUp aufgerufen. Dies ermöglicht es abgeleiteten Blueprint-Klassen, ihr eigenes Verhalten für OnPickedUp zu definieren, während die Basis-Klasse das Überlappungsevent des Actors selbst behandelt.
Die Entwickler verwenden den Basis-Blueprint, um alle Abholpunkte einen Sound spielen zu lassen und einige Partikeleffekte zu erzeugen. Die Variablen für den Abholpunkt-Sound und den Partikeleffekt sind instanzierbar, so dass sie in den Klassenvoreinstellungen der abgeleiteten Klassen festgelegt werden können. Klassenvoreinstellungen befinden sich im Blueprint-Editor oben neben der Schaltfläche „Kompilieren“:
Ein Beispiel für geänderte Klassenvoreinstellungen ist der Geschwindigkeitsabholpunkt, der ein Niagara-System mit grünen Partikeln verwendet (im Gegensatz zum Herzabholpunkt, der rosa Partikel verwendet). In ähnlicher Weise kann das Abholpunkt-Mesh selbst in abgeleiteten Blueprints festgelegt werden. Der letzte Schritt in der Überlappungslogik ist die Zerstörung des Abhol-Actors, da wir nicht wollen, dass er bestehen bleibt, nachdem ein Spieler ihn eingesammelt hat.
Mit nur wenigen Knoten kannst du eine robuste Logik erstellen, die sich mühelos auf abgeleitete Blueprints ausweiten lässt. Alle abgeleiteten Blueprints stammen aus einem Überlappungsevent, das an den Actor gebunden ist.
Spielercharakter springt von einem Feind ab
Ein weiteres gutes Beispiel ist der Absprung des Spielers von einem Feind. Der Kapselkollisionstyp des Feindes ist „Enemy“ und kollidiert mit Spielerobjekttypen. Auch bei Feinden mit Schwertern gibt es ein ähnliches Überlappungsevent. Diese werden gemeinhin als Hitboxes bezeichnet und sind der Ort, an dem ein Angriff wirksam ist.
Aber wie umgeht „Parrot“ dieses Problem, wenn ein Spieler von einem Feind abspringen will? Die Lösung besteht darin, die Köpfe der Feinde mit einer Hurtbox zu versehen. Wenn der Spieler diese Hurtbox überlappt, kann der Spielercharakter eine Reihe von Überprüfungen durchführen, um festzustellen, ob es sich um einen gültigen Sprung handelt, basierend auf der Position des Charakters, der Position der Hurtbox und der Ausdehnung der Box. Wenn die Prüfungen erfolgreich sind, kann der Spieler seinen Sprung ausführen und den Gegner treffen. Dabei wird die meiste Arbeit wieder einmal von den Kollisionskanälen erledigt, die nur die Überlappungen filtern, die für „Parrot“ von Bedeutung sind – ein Spieler-Kollisionsobjekt und ein Feind auf dem Hurtbox-Volumen.