Katzenhaken verleihen dem Spiel Spaß und interessante Mechanik. Sie können sie verwenden, um sich durch Level zu bewegen, in Arenen zu kämpfen und Gegenstände zu erhalten. Trotz der scheinbaren Einfachheit kann die Physik des Seilmanagements und die Schaffung eines realistischen Verhaltens eine Herausforderung sein!
Im ersten Teil dieses Tutorials implementieren wir unser eigenes zweidimensionales Hook-Cat-System und lernen Folgendes:
- Erstellen Sie ein Zielsystem.
- Verwenden Sie den Linienrenderer und das Distanzgelenk, um das Seil zu erstellen.
- Wir werden dem Seil beibringen, sich um Spielobjekte zu wickeln.
- Berechnen Sie den Schwenkwinkel am Seil und erhöhen Sie die Stärke in dieser Richtung.
Hinweis : Dieses Lernprogramm richtet sich an fortgeschrittene und erfahrene Benutzer und behandelt keine Themen wie das Hinzufügen von Komponenten, das Erstellen neuer GameObject-Skripts und die C # -Syntax. Wenn Sie Ihre Unity-Kenntnisse verbessern müssen, lesen Sie unsere Tutorials Erste Schritte mit Unity und Einführung in Unity Scripting . Da DistanceJoint2D in diesem Lernprogramm verwendet wird, sollten Sie auch die Physikverbindungen in Unity 2D durchsehen und erst dann zu diesem Lernprogramm zurückkehren.
An die Arbeit gehen
Laden Sie den
Entwurf für dieses Tutorial herunter und öffnen Sie ihn im Unity-Editor. Für den Betrieb ist Unity 2017.1 oder höher erforderlich.
Öffnen Sie die Spielszene aus dem Ordner "
Szenen " und sehen Sie, wo wir anfangen werden:
Im Moment haben wir einen einfachen Spielercharakter (Schnecke) und Steine, die in der Luft hängen.
Wichtige Komponenten von GameObject
Player sind bisher Capsule Collider und Rigidbody, die es ihm ermöglichen, mit physischen Objekten auf der Ebene zu interagieren. Außerdem ist dem Charakter ein einfaches Bewegungsskript (
PlayerMovement ) beigefügt, mit dem er auf dem Boden gleiten und einfache Sprünge ausführen kann.
Drücken Sie die
Play- Taste, um das Spiel zu starten, und versuchen Sie, den Charakter zu steuern.
A und
D bewegen es nach links / rechts, und wenn Sie die
Leertaste drücken
, springt es. Versuche nicht zu rutschen und von der Klippe zu fallen, sonst wirst du sterben!
Wir haben bereits die Grundlagen des Managements, aber das größte Problem ist jetzt das Fehlen von Katzenhaken.
Haken und Seile erstellen
Das Cat-Hook-System scheint zunächst recht einfach zu sein, aber für seine qualitativ hochwertige Implementierung müssen viele Aspekte berücksichtigt werden. Hier sind einige der Anforderungen für die zweidimensionale Cat-Hook-Mechanik:
- Line Renderer zur Anzeige des Seils. Wenn sich das Seil um Objekte wickelt, können wir dem Linienrenderer weitere Segmente hinzufügen und die Eckpunkte an den Punkten platzieren, die den Seilbrüchen entsprechen.
- DistanceJoint2D. Es kann verwendet werden, um den aktuellen Ankerpunkt des Katzenhakens so zu befestigen, dass unsere Schnecke schwingen kann. Außerdem können wir den Abstand einstellen, mit dem das Seil verlängert und verkleinert werden kann.
- Untergeordnetes GameObject mit RigidBody2D, das abhängig von der aktuellen Position des Ankerpunkts des Hakens verschoben werden kann. Im Wesentlichen ist dies der Aufhänge- / Ankerpunkt des Seils.
- Raycast zum Werfen eines Hakens und zum Befestigen an Objekten.
Wählen Sie das
Player- Objekt in der Hierarchie aus und fügen Sie ein neues untergeordnetes
GameObject mit dem Namen
RopeHingeAnchor hinzu . Dieses GameObject wird verwendet, um den Aufhängungs- / Ankerpunkt des Katzenhakens zu positionieren.
Fügen
Sie dem RopeHingeAnchor SpriteRenderer- und
RigidBody2D- Komponenten
hinzu .
Legen Sie für SpriteRenderer die
Sprite- Eigenschaft so fest, dass der
UISprite- Wert verwendet wird, und ändern Sie die
Reihenfolge in Layer auf
2 . Deaktivieren Sie die Komponente, indem Sie das
Kontrollkästchen neben ihrem Namen
deaktivieren .
Setzen Sie für die
RigidBody2D- Komponente die Body Type-Eigenschaft auf
Kinematic . Dieser Punkt wird nicht von der physischen Engine, sondern vom Code verschoben.
Wählen Sie die
Seilebene aus und setzen Sie die X- und Y-Skalierungswerte der Transformationskomponente auf
4 .
Wählen Sie
Player erneut aus und hängen Sie die neue
DistanceJoint2D- Komponente an.
Ziehen Sie den
RopeHingeAnchor aus der Hierarchie auf die Eigenschaft
Connected Rigid Body der
DistanceJoint2D- Komponente und
deaktivieren Sie
Auto Configure Distance .
Erstellen Sie ein neues C #
-Skript mit dem Namen
RopeSystem im Projektordner "
Skripte " und öffnen Sie es im Code-Editor.
Entfernen Sie die
Update
Methode.
RopeSystem
oben im Skript in der
RopeSystem
Klassendeklaration neue Variablen, die
Awake()
-Methode und die neue
Update
Methode hinzu:
Lassen Sie uns jedes Teil der Reihe nach analysieren:
- Wir verwenden diese Variablen, um die verschiedenen Komponenten zu verfolgen, mit denen das RopeSystem-Skript interagieren wird.
- Die
Awake
Methode beginnt zu Beginn des Spiels und deaktiviertopeJoint (die DistanceJoint2D-Komponente). Außerdem wird playerPosition
auf die aktuelle Position des Players gesetzt. - Dies ist der wichtigste Teil der Hauptschleife von
Update()
. Zuerst erhalten wir die Mauszeigerposition in der Welt mithilfe der ScreenToWorldPoint
Kameramethode. Dann berechnen wir die Blickrichtung, indem wir die Position des Spielers von der Position der Maus in der Welt abziehen. Anschließend erstellen wir damit aimAngle
, eine Darstellung des aimAngle
des Cursors. Der Wert speichert einen positiven Wert im if-Konstrukt. aimDirection
ist eine Wendung, die später nützlich sein wird. Der Z-Wert interessiert uns nur, da wir eine 2D-Kamera verwenden und dies das einzige entsprechende Betriebssystem ist. Wir übergeben aimAngle * Mathf.Rad2Deg
, das den Bogenmaßwinkel in einen Winkel in Grad umwandelt.- Die Position des Spielers wird mithilfe einer praktischen Variablen überwacht, mit der Sie nicht ständig auf
transform.Position
verweisen können. - Schließlich haben wir das
if..else
Konstrukt, mit dem wir bald feststellen werden, ob das Seil am Ankerpunkt befestigt ist.
Speichern Sie das Skript und kehren Sie zum Editor zurück.
Hängen Sie die
RopeSystem- Komponente an das Player-Objekt an und hängen Sie die verschiedenen Komponenten an die öffentlichen Felder, die wir im
RopeSystem- Skript erstellt haben. Ziehen Sie
Player ,
Crosshair und
RopeHingeAnchor in die entsprechenden Felder:
- Seilscharnieranker : RopeHingeAnchor
- Seilverbindung : Spieler
- Fadenkreuz : Fadenkreuz
- Fadenkreuz-Sprite : Fadenkreuz
- Spielerbewegung : Spieler
Jetzt führen wir nur all diese komplizierten Berechnungen durch, aber bisher gibt es keine Visualisierung, die sie in Aktion zeigen könnte. Aber keine Sorge, wir werden es bald tun.
Öffnen Sie das
RopeSystem- Skript und fügen Sie eine neue Methode hinzu:
private void SetCrosshairPosition(float aimAngle) { if (!crosshairSprite.enabled) { crosshairSprite.enabled = true; } var x = transform.position.x + 1f * Mathf.Cos(aimAngle); var y = transform.position.y + 1f * Mathf.Sin(aimAngle); var crossHairPosition = new Vector3(x, y, 0); crosshair.transform.position = crossHairPosition; }
Diese Methode positioniert das Visier basierend auf dem übertragenen
aimAngle
(dem Float-Wert, den wir in
Update()
berechnet haben) so, dass es sich mit einem Radius von 1 Einheit um den Spieler dreht. Wir fügen auch einen Sprite-Bereich hinzu, falls dies noch nicht geschehen ist.
In Update()
ändern wir das Konstrukt !ropeAttached
, um !ropeAttached
so zu überprüfen, dass es folgendermaßen aussieht:
if (!ropeAttached) { SetCrosshairPosition(aimAngle); } else { crosshairSprite.enabled = false; }
Speichern Sie das Skript und führen Sie das Spiel aus. Jetzt sollte unsere Schnecke in der Lage sein, mit einem Anblick zu zielen.
Die nächste Logik, die implementiert werden muss, ist ein Cat-Hook-Schuss. Wir haben die Zielrichtung bereits festgelegt, daher benötigen wir eine Methode, die sie als Parameter erhält.
Fügen Sie die folgenden Variablen unter den Variablen im
RopeSystem- Skript hinzu:
public LineRenderer ropeRenderer; public LayerMask ropeLayerMask; private float ropeMaxCastDistance = 20f; private List<Vector2> ropePositions = new List<Vector2>();
LineRenderer enthält einen Link zu einem Linienrenderer, der das Seil zeichnet.
Mit LayerMask können Sie die Physik-Layer anpassen, mit denen der Hook interagieren kann. Der Wert für
ropeMaxCastDistance
legt die maximale Entfernung fest, die Raycast "schießen" kann.
Schließlich wird die Positionsliste von Vector2 verwendet, um die Seilwickelpunkte zu verfolgen, auf die wir später noch eingehen werden.
Fügen Sie die folgenden neuen Methoden hinzu:
Der obige Code bewirkt Folgendes:
- HandleInput wird von der
Update()
Schleife aufgerufen und fragt einfach die Eingabe der linken und rechten Maustaste ab. - Wenn ein Linksklick registriert wird, wird die Seillinie eingeschaltet und ein 2D-Raycast von der Position des Spielers in Zielrichtung abgefeuert. Die maximale Entfernung wird so eingestellt, dass die Hakenkatze nicht in unendlicher Entfernung geschossen werden kann, und eine Maske wird angewendet, damit die Schichten der Physik ausgewählt werden können, mit denen Raycast kollidieren kann.
- Wenn ein Raycast-Treffer erkannt wird,
ropeAttached
true
, und eine Liste der Positionen der Eckpunkte des Seils wird überprüft, um sicherzustellen, dass dort kein Punkt vorhanden ist. - Wenn die Prüfung wahr zurückgibt, wird dem Butzen ein kleiner Kraftimpuls hinzugefügt, so dass er über dem Boden abprallt. Das
ropeJoint
(DistanceJoint2D) wird eingeschaltet, das auf den Abstand eingestellt ist, der dem Abstand zwischen dem Schneckenpunkt und dem Raycast-Trefferpunkt entspricht. Ein Ankerpunkt-Sprite ist ebenfalls enthalten. - Wenn Raycast nichts trifft, sind Line Renderer und RopeJoint deaktiviert und das Flag "
ropeAttached
ist falsch. - Wenn die rechte Maustaste gedrückt wird, wird die
ResetRope()
-Methode ResetRope()
, mit der alle mit dem Seil / Haken verbundenen Parameter deaktiviert und auf die Werte zurückgesetzt werden, die gelten sollten, wenn der Haken nicht verwendet wird.
HandleInput()
ganz unten in unserer
Update
Methode einen Aufruf der neuen
HandleInput()
-Methode hinzu und übergeben Sie den
aimDirection
Wert an
aimDirection
:
HandleInput(aimDirection);
Speichern Sie die Änderungen in
RopeSystem.cs und kehren Sie zum Editor zurück.
Ein Seil hinzufügen
Unsere Schnecke kann ohne Seil nicht durch die Luft fliegen, daher ist es an der Zeit, ihr etwas zu geben, das eine visuelle Darstellung des Seils darstellt und sich um Ecken "drehen" kann.
Der Linienrenderer ist dafür ideal, da er es uns ermöglicht, die Anzahl der Punkte und ihre Position im Raum der Welt zu übertragen.
Die Idee dabei ist, dass wir immer den ersten Scheitelpunkt des Seils (0) in der Position des Spielers speichern und alle anderen Scheitelpunkte dynamisch positioniert werden, wenn sich das Seil um etwas wickeln soll, einschließlich der aktuellen Position des Scharniers, das der nächste Punkt entlang des Seils ist vom Spieler.
Wählen Sie
Player und fügen Sie die
LineRenderer- Komponente hinzu. Stellen Sie die
Breite auf
0,075 ein . Erweitern Sie die
Materialliste und wählen
Sie als
Element 0 das
RopeMaterial- Material aus, das sich im
Materialordner des Projekts befindet. Wählen Sie schließlich für Line Renderer für
Texture Mode die
Option Pro Segment verteilen .
Ziehen Sie die Line Renderer-Komponente in das Feld
Rope Renderer der
Rope System- Komponente.
Klicken Sie auf die Dropdown-Liste der
Rope Layer Mask und wählen Sie als Ebenen aus, mit denen Raycast
Default, Rope und Pivot interagieren können. Aus diesem Grund kollidiert ein Raycast beim „Aufnehmen“ nur mit diesen Ebenen, nicht jedoch mit anderen Objekten, z. B. einem Player.
Wenn Sie das Spiel jetzt starten, werden Sie ein merkwürdiges Verhalten bemerken. Wenn wir auf einen Stein über dem Kopf der Schnecke zielen und mit einem Haken schießen, bekommen wir einen kleinen Sprung nach oben, wonach sich unser Freund eher zufällig verhält.
Wir haben den Abstand für das Distanzgelenk noch nicht festgelegt, außerdem sind die Eckpunkte des Linienrenderings nicht konfiguriert. Daher sehen wir das Seil nicht, und da sich das Distanzgelenk direkt über der Position der Schnecke befindet, drückt der aktuelle Wert des Distanzgelenkabstands es zu den Steinen darunter.
Aber keine Sorge, jetzt werden wir dieses Problem lösen.
Fügen Sie im Skript
RopeSystem.cs am Anfang der Klasse einen neuen Operator hinzu:
using System.Linq;
Auf diese Weise können wir LINQ-Abfragen verwenden, die es uns in unserem Fall einfach ermöglichen, das erste oder letzte Element der Liste der
ropePositions
bequem zu finden.
Hinweis : Language Integrated Query (LINQ) ist der Name einer Reihe von Technologien, die auf der Einbettung von Abfragefunktionen direkt in C # basieren. Hier können Sie mehr darüber lesen.
Fügen Sie unter den anderen Variablen eine neue private Bool-Variable namens
distanceSet
:
private bool distanceSet;
Wir werden diese Variable als Flag verwenden, damit das Skript erkennen kann, dass der Abstand des Seils (für den Punkt zwischen dem Spieler und dem aktuellen Referenzpunkt, an dem der Katzenhaken angebracht ist) korrekt eingestellt ist.
Fügen Sie nun eine neue Methode hinzu, mit der wir die Positionen der Seilscheitelpunkte für das Rendern der Linie und den Abstand der Distanzverbindung in der gespeicherten Liste der Positionen mit Seil (
ropePositions
)
ropePositions
:
private void UpdateRopePositions() {
Erläutern Sie den oben gezeigten Code:
- Beenden Sie die Methode, wenn das Seil nicht befestigt ist.
- Wir weisen den Wert der
ropePositions
der Seillinie der Anzahl der in ropePositions
gespeicherten ropePositions
, plus 1 weiteren (für die Position des Spielers). - Wir
ropePositions
Liste der ropePositions
und führen eine ropePositions
für jede Position (mit Ausnahme der letzten) durch. ropePositions
die Position des Scheitelpunkts des Linienrenderers dem Wert der Position Vector2 zu, die vom Schleifenindex in der Liste der Seilpositionen gespeichert wird. - Weisen Sie dem Ankerpunkt des Seils die zweite von der Endposition des Seils zu, in der sich der aktuelle Scharnier- / Ankerpunkt befinden sollte, oder machen Sie ihn zum Ankerpunkt, wenn wir nur eine Position des Seils haben. Also setzen wir das DistanzseilJoint gleich dem Abstand zwischen dem Spieler und der aktuellen Position des Seils, die wir in der Schleife
ropeJoint
. - Das if-Konstrukt behandelt den Fall, in dem die aktuelle Position des Seils in der Schleife vom Ende an zweiter Stelle steht. d.h. der Punkt, an dem das Seil mit dem Objekt verbunden ist, d.h. aktueller Scharnier- / Ankerpunkt.
- Dieser
else
Block behandelt das Zuweisen der Position des letzten Scheitelpunkts des Seils zum Wert der aktuellen Position des Spielers.
Denken Sie daran, den
UpdateRopePositions()
am Ende von
Update()
UpdateRopePositions()
hinzuzufügen:
UpdateRopePositions();
Speichern Sie die Änderungen am Skript und führen Sie das Spiel erneut aus. Machen Sie aus einem „kleinen Raum“ einen kleinen Sprung, indem Sie mit einem Haken auf einen Stein über dem Charakter zielen und schießen. Jetzt können Sie die Früchte Ihrer Arbeit genießen - die Schnecke schwankt ruhig über den Steinen.
Jetzt können Sie zum Szenenfenster gehen, Player auswählen, das Verschieben-Werkzeug (standardmäßig die
W- Taste) verwenden, um es zu verschieben, und beobachten, wie die beiden Eckpunkte des Renderings der Seillinie der Position des Hakens und der Position des Players zum Zeichnen des Seils folgen. Nachdem wir den Player losgelassen haben, berechnet DistanceJoint2D die Entfernung korrekt und der Butzen schwingt weiter am angeschlossenen Scharnier.
Umgang mit Wickelpunkten
Das Spielen mit einer schwingenden Schnecke ist bisher nicht nützlicher als ein wasserabweisendes Handtuch, daher müssen wir es definitiv ergänzen.
Die gute Nachricht ist, dass die neu hinzugefügte Methode zur Verarbeitung von Seilpositionen in Zukunft verwendet werden kann. Bisher verwenden wir nur zwei Seilpositionen. Einer ist mit der Position des Spielers verbunden und der zweite mit der aktuellen Position des Ankerpunkts des Hakens, wenn er auf ihn schießt.
Das einzige Problem ist, dass wir zwar nicht alle möglichen Positionen des Seils verfolgen, dies jedoch ein wenig Arbeit erfordert.
Um die Positionen auf den Steinen zu erkennen, um die sich das Seil wickeln soll, und dem Linienrenderer eine neue Scheitelpunktposition hinzuzufügen, benötigen wir ein System, das bestimmt, ob der Scheitelpunkt des Kolliders zwischen der geraden Linie zwischen der aktuellen Position der Schnecke und dem aktuellen Scharnier- / Ankerpunkt des Seils liegt.
Sieht so aus, als wäre dies wieder Arbeit für den guten alten Raycast!
Zuerst müssen wir eine Methode erstellen, die den nächstgelegenen Punkt im Collider basierend auf dem Trefferpunkt des Raycasts und den Kanten des Colliders findet.
Fügen
Sie dem Skript
RopeSystem.cs eine neue Methode
hinzu :
Wenn Sie mit LINQ-Abfragen nicht vertraut sind, scheint dieser Code eine Art komplizierte C # -Magie zu sein.
Wenn ja, dann haben Sie keine Angst. LINQ leistet viel Arbeit für uns:
- Diese Methode verwendet zwei Parameter - das RaycastHit2D- Objekt und das PolygonCollider2D-Objekt . Alle Steine auf dem Level haben PolygonCollider2D-Collider. Wenn wir also immer PolygonCollider2D-Formen verwenden, funktioniert dies einwandfrei.
- Hier beginnt die Magie der LINQ-Abfrage! Hier transformieren wir die Punktesammlung des polygonalen Colliders in das Vector2- Positionswörterbuch (der Wert jedes Elements des Wörterbuchs ist die Position selbst), und dem Schlüssel jedes Elements wird der Abstand von diesem Punkt zum Positionsspieler des Spielers zugewiesen (Gleitkommawert). Manchmal passiert hier etwas anderes: Die resultierende Position wird in den Weltraum konvertiert (standardmäßig werden die Positionen der Kolliderscheitelpunkte im lokalen Raum gespeichert, d. H. Lokal relativ zu dem Objekt, zu dem der Kollider gehört, und wir benötigen Positionen im Weltraum).
- Das Wörterbuch ist nach Schlüsseln sortiert. Mit anderen Worten, um die Entfernung, die der aktuellen Position des Spielers am nächsten liegt. Die nächstgelegene Entfernung wird zurückgegeben, dh jeder Punkt, der mit dieser Methode zurückgegeben wird, ist der Kolliderpunkt zwischen dem Spieler und dem aktuellen Punkt des Seilscharniers!
Kehren wir zum Skript
RopeSystem.cs zurück und fügen oben eine neue private
Feldvariable hinzu:
private Dictionary<Vector2, int> wrapPointsLookup = new Dictionary<Vector2, int>();
Wir werden es verwenden, um die Positionen zu verfolgen, um die sich das Seil wickeln kann.
Suchen Sie am Ende der
Update()
-Methode das
else
Konstrukt, das
crosshairSprite.enabled = false;
enthält
crosshairSprite.enabled = false;
und fügen Sie Folgendes hinzu:
Erklären Sie diesen Code:
- Wenn einige Positionen in der
ropePositions
gespeichert sind, dann ... - Wir schießen von der Position des Spielers in Richtung des Spielers, der die letzte Position des Seils aus der Liste betrachtet - den Ankerpunkt, an dem der Katzenhaken am Stein befestigt ist - mit einem Raycast-Abstand, der dem Abstand zwischen dem Spieler und der Position des Ankerpunkts des Seils entspricht.
- Wenn Raycast mit etwas kollidiert, wird der Collider dieses Objekts sicher in den Typ PolygonCollider2D umgewandelt . Während es sich um einen echten PolygonCollider2D handelt, wird die nächstgelegene Scheitelpunktposition dieses Colliders mit der Methode zurückgegeben, die wir zuvor als Vector2 geschrieben haben .
- Es wird von
wrapPointsLookup
überprüft, um sicherzustellen, dass dieselbe Position nicht erneut überprüft wird. Wenn es aktiviert ist, werfen wir das Seil weg, schneiden es ab und lassen den Spieler fallen. - Dann wird die Liste der
ropePositions
: Die Position wird hinzugefügt, um die sich das Seil wickeln soll. Das wrapPointsLookup
Wörterbuch wird ebenfalls aktualisiert. Schließlich wird das Flag distanceSet
zurückgesetzt, damit die UpdateRopePositions()
-Methode den Abstand des Seils mit der neuen Länge des Seils und der Segmente neu definieren kann.
ResetRope()
in
ResetRope()
die folgende Zeile hinzu, damit das
wrapPointsLookup
Wörterbuch jedes Mal gelöscht wird, wenn ein Spieler ein Seil
wrapPointsLookup
:
wrapPointsLookup.Clear();
Speichern und starten Sie das Spiel. Schießen Sie den Katzenhaken in den Stein über der Schnecke und bewegen Sie die Schnecke mit dem Verschieben-Werkzeug im Szenenfenster über mehrere Steinleisten.
So haben wir Seil gelehrt, um Gegenstände zu wickeln!
Schaukelfähigkeit hinzufügen
Die am Seil hängende Schnecke ist ziemlich statisch. Um dies zu beheben, können wir die Schwingfähigkeit hinzufügen.
Dazu müssen wir eine Position senkrecht zur Position des Vorwärtsschwingens (seitwärts) erhalten, unabhängig von dem Winkel, in den er schaut.
Öffnen Sie
PlayerMovement.cs und fügen Sie die folgenden zwei öffentlichen Variablen oben im Skript hinzu:
public Vector2 ropeHook; public float swingForce = 4f;
Der
ropeHook
Variablen wird jede Position zugewiesen, an der sich der
swingForce
gerade befindet, und
swingForce
ist der Wert, den wir zum Hinzufügen der Swing-Bewegung verwenden.
Ersetzen Sie die
FixedUpdate()
-Methode
FixedUpdate()
neue:
void FixedUpdate() { if (horizontalInput < 0f || horizontalInput > 0f) { animator.SetFloat("Speed", Mathf.Abs(horizontalInput)); playerSprite.flipX = horizontalInput < 0f; if (isSwinging) { animator.SetBool("IsSwinging", true);
Die wichtigsten Änderungen hierbei sind, dass die Flagge zuerst überprüft wird, isSwinging
sodass Aktionen nur ausgeführt werden, wenn die Schnecke am Seil hängt. Außerdem fügen wir eine Senkrechte zur Ecke der Schnecke hinzu, die ihren aktuellen Ankerpunkt oben am Seil anzeigt, jedoch senkrecht zur Richtung ihres Schwingens.- Wir erhalten den normalisierten Richtungsvektor vom Spieler zum Hakenbefestigungspunkt.
- Abhängig davon, ob die Schnecke nach links oder rechts schwankt, wird die senkrechte Richtung mit berechnet
playerToHookDirection
. Ein Debug-Draw-Aufruf wurde ebenfalls hinzugefügt, damit Sie ihn auf Wunsch im Editor anzeigen können.
Öffnen Sie RopeSystem.cs und fügen Sie oben im else-Block der if(!ropeAttached)
Methode Update()
Folgendes hinzu: playerMovement.isSwinging = true; playerMovement.ropeHook = ropePositions.Last();
Fügen Sie im if-Block desselben Designs if(!ropeAttached)
Folgendes hinzu: playerMovement.isSwinging = false;
Daher informieren wir das PlayerMovement-Skript, dass der Spieler schwingt, und bestimmen auch die letzte Position (mit Ausnahme der Position des Spielers) des Seils - mit anderen Worten den Ankerpunkt des Seils. Dies ist erforderlich, um den senkrechten Winkel zu berechnen, den wir gerade zum PlayerMovement-Skript hinzugefügt haben.So sieht es aus, wenn Sie in einem laufenden Spiel Gizmos einschalten und A oder D drücken, um nach links / rechts zu schwingen:Seilabstieg hinzufügen
Wir haben zwar nicht die Fähigkeit, das Seil auf und ab zu bewegen. Obwohl die Schnecke im wirklichen Leben nicht leicht am Seil entlang steigen und fallen konnte, ist dies ein Spiel, in dem alles passieren kann, oder? Fügen Sieoben im RopeSystem- Skript zwei neue Feldvariablen hinzu: public float climbSpeed = 3f; private bool isColliding;
climbSpeed
Legt die Geschwindigkeit fest, mit der sich der Butzen auf dem Seil auf und ab bewegen kann, und isColliding
wird als Flagge verwendet, um zu bestimmen, ob die Distanzverbindungseigenschaft des Distanzgelenkseils erhöht oder verringert werden kann.Fügen Sie diese neue Methode hinzu: private void HandleRopeLength() {
Dieser Block if..elseif
liest die Eingabe entlang der vertikalen Achse (auf / ab oder W / S auf der Tastatur) und ropeAttached iscColliding
vergrößert oder verkleinert unter Berücksichtigung der Flaggen den Abstand ropeJoint
, wodurch der Effekt einer Verlängerung oder Verkürzung des Seils entsteht.Wir verknüpfen diese Methode und fügen ihren Aufruf am Ende hinzu Update()
: HandleRopeLength();
Wir brauchen auch eine Möglichkeit, die Flagge zu setzen isColliding
.Fügen Sie am Ende des Skripts die folgenden zwei Methoden hinzu: void OnTriggerStay2D(Collider2D colliderStay) { isColliding = true; } private void OnTriggerExit2D(Collider2D colliderOnExit) { isColliding = false; }
Diese beiden Methoden sind native Methoden der Basisklasse von MonoBehaviour-Skripten.Wenn Collider derzeit ein anderes physisches Objekt im Spiel berührt, wird die Methode ständig OnTriggerStay2D
ausgelöst und der Flagge einen isColliding
Wert zugewiesen true
. Dies bedeutet, dass dem isColliding-Flag ein Wert zugewiesen wird, wenn die Schnecke den Stein berührt true
.Die Methode wird OnTriggerExit2D
ausgelöst, wenn ein Collider den Bereich eines anderen Colliders verlässt und das Flag auf false setzt.Beachten Sie: Die Methode OnTriggerStay2D
kann sehr rechenintensiv sein. Gehen Sie daher vorsichtig vor.Wohin als nächstes?
Starten Sie das Spiel erneut und drücken Sie diesmal die Pfeiltasten oder W / S, um das Seil auf und ab zu bewegen.Das fertige Projekt dieses Teils des Tutorials kann hier heruntergeladen werden .Wir haben einen langen Weg zurückgelegt - von der nicht schwingenden Schnecke bis zur akrobatischen muschelfreien Gastropodenmolluske!Sie haben gelernt, wie Sie ein Zielsystem erstellen, das einen Katzenhaken auf jedes Objekt mit einem Kollider schießt, sich daran festhält und gleichzeitig darauf schwingt und sich an einem dynamischen Seil um die Kanten von Objekten dreht! Ausgezeichnete Arbeit.Hier fehlt jedoch eine wichtige Funktion - das Seil kann sich bei Bedarf nicht „abwickeln“.Im zweiten Teil des Tutorials werden wir dieses Problem lösen.Aber wenn Sie bereit sind, ein Risiko einzugehen, warum versuchen Sie es dann nicht selbst? Sie können hierfür ein Wörterbuch verwenden wrapPointsLookup
.