Kampf in Godot! | Thomas Yanuziello | Skillshare

Playback-Geschwindigkeit


1.0x


  • 0.5x
  • 0.75x
  • 1x (normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Schau dir diesen Kurs und Tausende anderer Kurse an

Erhalte unbegrenzten Zugang zu allen Kursen
Lerne von Branchenführern, Ikonen und erfahrenen Experten
Wähle aus einer Vielzahl von Themen, wie Illustration, Design, Fotografie, Animation und mehr

Einheiten dieses Kurses

    • 1.

      Einführung

      1:44

    • 2.

      SET-UP

      0:32

    • 3.

      Lock On

      15:52

    • 4.

      Strafe

      13:47

    • 5.

      Angriff

      20:46

    • 6.

      Waffe

      17:20

    • 7.

      Hit

      15:43

    • 8.

      Dodge

      14:43

    • 9.

      Block

      15:12

    • 10.

      Aufnahme

      17:43

    • 11.

      Feind

      15:41

  • --
  • Anfänger-Niveau
  • Fortgeschrittenes Niveau
  • Fortgeschrittenes Niveau
  • Jedes Niveau

Von der Community generiert

Das Niveau wird anhand der mehrheitlichen Meinung der Teilnehmer:innen bestimmt, die diesen Kurs bewertet haben. Bis das Feedback von mindestens 5 Teilnehmer:innen eingegangen ist, wird die Empfehlung der Kursleiter:innen angezeigt.

50

Teilnehmer:innen

--

Projekt

Über diesen Kurs

Dieser Kurs ist eine Fortsetzung von Inventar und Shops in Godot!

Klicke auf meinen Website-Link in meinem Profil, um unserem Discord-Server beizutreten.

In diesem Kurs behandeln wir das Festlegen eines Ziels, Strafing Fortbewegung, Angriff, Treffer, Ausweichen, Blockieren, Schießen von Projektilen und die grundlegende feindliche KI.

Sie lernen auch nützliche Fähigkeiten für die Arbeit mit der Godot Spielengine, die Organisation und das Design Ihrer Projekte so an, dass sie skalierbarer sind.  Sie lernen, wie man mit GDscript programmiert und alles wird detailliert erklärt.  Unsere Skripte werden so geschrieben, dass sie hochgradig anpassbar und wiederverwendbar sind.  Alle Projektdateien sind auch auf GitHub verfügbar, wenn Sie das Projekt nach Abschluss der einzelnen Kurseinheit so überprüfen müssen, wie es war.  Diese Videos wurden mit Godot Version 4.3 aufgenommen.

Dieser Kurs ist Teil einer Serie, die mundgerechte Spielentwicklungsstücke beibringt, die alle austauschbar untereinander verwendet werden können.  Also lass mich wissen, welche Arten von Spielen Sie interessiert sind, wie man macht, und ich werde versuchen, sie in zukünftige Kurse in dieser Serie aufzunehmen.

Triff deine:n Kursleiter:in

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Kursleiter:in
Level: All Levels

Kursbewertung

Erwartungen erfüllt?
    Voll und ganz!
  • 0%
  • Ja
  • 0%
  • Teils teils
  • 0%
  • Eher nicht
  • 0%

Warum lohnt sich eine Mitgliedschaft bei Skillshare?

Nimm an prämierten Skillshare Original-Kursen teil

Jeder Kurs setzt sich aus kurzen Einheiten und praktischen Übungsprojekten zusammen

Mit deiner Mitgliedschaft unterstützt du die Kursleiter:innen auf Skillshare

Lerne von überall aus

Ob auf dem Weg zur Arbeit, zur Uni oder im Flieger - streame oder lade Kurse herunter mit der Skillshare-App und lerne, wo auch immer du möchtest.

Transkripte

1. Einführung: Kampf- und Videospiele können entmutigend und schwierig zu implementieren sein . Dieser Kurs vermittelt dir alle Werkzeuge und Kenntnisse, die du benötigst , um ein skalierbares und dynamisches Kampfsystem in Gado zu erstellen dynamisches Kampfsystem in Wir werden das Kampfsystem in einzelne Mechaniken aufteilen und diese zu einem robusten Action-Kampfsystem kombinieren einem robusten Action-Kampfsystem , das an Ihre Bedürfnisse angepasst werden kann Du wirst lernen, wie du Kampf- und Bewegungsanimationen miteinander verbinden kannst. Synchronisiere Trefferboxen mit Angriffsanimationen, setze Augenbilder in Ausweichanimationen ein und halte Feinde fest im Visier. Feuere Projektile mit einer arrangierten Waffe ab und kontrolliere Feinde mit KI-Skripten Falls du Hilfe benötigst, ist unser Discord-Server voll von anderen Studenten und Spieleentwicklern , die alle deine Fragen beantworten können Klicken Sie auf den Link zur Website in meinem Profil, um Mitglied zu werden. Ich werde ein Starterprojekt verwenden, das in God Version 4.3 erstellt das auf meinem GitHub verfügbar ist verwende ich kostenlose Ressourcen von it dot IO. Sie können Ihr eigenes Projekt jedoch mit verschiedenen Assets verfolgen . Um das Beste aus diesem Kurs herauszuholen, benötigst du in deinem Projekt eine Szene mit einem Charakter, den der Spieler kontrollieren kann , und mindestens einem Feind. Vielleicht möchtest du auch über ein Inventar- und Ausrüstungssystem verfügen Inventar- und Ausrüstungssystem ausgestattet werden können mit dem Charaktere mit einer Waffe und einem Schild Weitere Informationen zu diesen Themen finden Sie in meinem vorherigen Kurs Ein Kampf muss kein harter Kampf sein. Lasst uns unsere Waffen ziehen und uns gemeinsam durch den Kampf schlagen . S. 2. SET-UP: Hallo Freunde. Bevor wir anfangen, solltest du ein Projekt mit einem Spielercharakter haben , der sich in einer Umgebung bewegen kann , und einigen Feinden, gegen die er kämpfen kann. Vielleicht möchtest du auch ein Inventarmenü haben dem du Gegenstände ausrüsten kannst, darunter mindestens eine Mala-Waffe, eine arrangierte Waffe und einen Schild Im Laufe dieses Kurses werden wir unserem Projekt Steuerungen, Mechaniken und Animationen hinzufügen , um ein Ziel anzuvisieren, anzugreifen, auszuweichen, zu blockieren und 3. Lock On: unserer ersten Lektion ermöglichen wir dem Spieler, sich auf einen Feind zu konzentrieren. Beginnen wir mit dem Hinzufügen eines Eingabe-Mappings zum Umschalten der Sperre Öffnen Sie die Projekteinstellungen und wechseln Sie zur Registerkarte Eingabemap Wir können ein Eingabeereignis namens Toggle Lock hinzufügen. nach unten scrolle, um das neue Eingabeereignis zu finden, binde ich die Q-Taste auf Tastatur und die rechte Stick-Taste auf meinem Controller an dieses Im Skript zur Bearbeitung von Spielereingaben benötigen wir Verweise auf den Charakter, den Federarm und die Kamera, alle mit dem Add-On Ready eingerichtet Während der Eingabefunktion, nachdem wir überprüft haben, ob eine Pause , das Inventarmenü geöffnet oder geschlossen vorliegt, das Inventarmenü geöffnet oder geschlossen wurde und ob die Steuerung durch den Spieler deaktiviert wurde. Ich habe den Rest der Eingabe zur besseren Organisation in Kamerasteuerung und Charaktersteuerung aufgeteilt Kamerasteuerung und Charaktersteuerung . Derzeit besteht die einzige Kamerasteuerung darin, den Federarm, der die Kamera hält, mit der Maus zu drehen . Lassen Sie uns auch überprüfen, ob die Umschalttaste gedrückt wurde. Dies wird eine kontextsensitive Eingabe mit mehreren verschiedenen möglichen Funktionen Wir müssen wissen, ob der Spieler derzeit auf ein Ziel fixiert ist. Deklarieren wir also eine Variable, die das aktuell gesperrte Ziel als Knoten drei D enthält, sodass möglicherweise jedes Drei-D-Objekt in unserer Spielwelt gesperrt sein könnte. Wir können zunächst die Funktionen der Umschalttaste in zwei mögliche Kategorien einteilen , ob der Wert von target Null ist oder nicht, die wir auf just if target kürzen können Fangen wir mit dem S-Block an, in dem der Spieler momentan an nichts gebunden Hier müssen wir den Wert des Ziels dem nächstgelegenen sichtbaren Ziel zuweisen , und wir können die Verantwortung dafür delegieren, herauszufinden , welches Ziel der Kamera am nächsten ist Falls es kein nächstgelegenes sichtbares Ziel gibt, ist das Ziel immer noch Null In vielen Action-Adventure-Spielen beim Drücken der ToGo-Lock-Taste aber nichts, worauf man sich festlegen könnte. Die Kamera wird dann zurückgesetzt, sodass sie sich hinter dem Spielercharakter befindet, was wiederum vom Federarm Wenn der Spieler bereits ein Ziel im Visier hat und die Togo-Sperr-Taste drückt, gibt es auch mehrere Fälle, die berücksichtigt Wenn es mehrere sichtbare Ziele gibt, wird der Spieler neben dem Ziel, auf das er gerade gefesselt ist, das nächste sichtbare Ziel das er gerade gefesselt ist, das nächste sichtbare Ziel anvisieren. Wir können dieselbe Funktion der Kamera wiederverwenden, um das nächstgelegene Ziel zu finden Aber dieses Mal geben wir auch das aktuelle Ziel als Argument an, und wir werden den Algorithmus so schreiben, dass er dieses Ziel ignoriert Im folgenden Fall können wir das aktuelle Ziel trotzdem übergeben, da sein Wert Null ist, sodass wir nichts zu ignorieren haben. Wenn es nicht mehrere sichtbare Ziele gibt, diese Funktion ebenfalls Null zurück und die Sperre wird deaktiviert Unabhängig davon, ob es mehrere Ziele gibt oder nicht, wird in den meisten Spielen die Sperre in diesem Fall aufgehoben, wenn der Spieler ebenfalls nach unten drückt meisten Spielen die Sperre in diesem Fall aufgehoben, wenn der Wir können anhand eines Punktprodukts der beiden Vektoren feststellen, ob die angegebene Eingaberichtung der Richtung nach unten ähnelt und ob sie größer als 0,75 ist Dies deckt alle Richtungen ab, die sich in der Nähe von unten befinden, aber nicht bis zu den Diagonalen reichen Wir wollen die Möglichkeit haben, die Sperre von außerhalb des Skripts umzuschalten , daher wäre es eine gute Idee, es zu einer öffentlichen Funktion zu machen Nennen wir es Toggle Lock und geben ihm einen optionalen Parameter, um die Sperre mit dem Standardwert false zu erzwingen Sperre mit dem Standardwert false Der Wert von target wird auf Null gesetzt, wenn es ausgeschaltet wird Andernfalls kann es auf das nächste sichtbare Ziel gesetzt werden , das von der Kamera bestimmt wurde, wobei das aktuelle Ziel ignoriert wird, falls es eines gibt allen drei oben genannten Fällen kann nun Toggle Lock aufgerufen werden, wobei nur angegeben werden muss , dass die Sperre aufgehoben wird falls auch die Eingaberichtung nach unten angegeben wird. Andere Skripte können den Spieler auch zwingen, Andere Skripte können den Spieler auch zwingen die Sperre aus beliebigem Grund ein - oder auszuschalten Zum Spring-Arm-Skript wechseln. Nehmen wir an, der Spieler drückt die Sperrtaste, aber es sind keine Ziele sichtbar Wir wollen, dass der Federarm die Kamera hinter dem Charakter positioniert die Kamera hinter dem Charakter Wir benötigen also einen Verweis auf die Figur, an der der Federarm befestigt ist, was in meinem Fall immer der Elternknoten des Federarms sein wird . Wenn Sie eine andere Knotenstruktur verwenden, sollten Sie stattdessen diese Variable exportieren und ihren Wert im Inspektorfenster festlegen. Um die Kamera hinter der Figur im Laufe der Zeit schrittweise zu drehen , verwenden wir eine Tween-Variable vom Typ Tween Es wäre eine gute Idee, eine Variable für die Dauer des Tweens zu exportieren eine Variable für die Dauer des Tweens Ich nehme eine Viertelsekunde. Möglicherweise benötigen wir auch einen Wert für die bevorzugte X-Drehung , um die Drehung der Federarme um zwei zurückzusetzen. Ich verwende minus 0,5 Radiant und positioniere die Kamera leicht über der Figur, nach vorne und in einem Winkel leicht nach unten schaue Deklarieren wir außerdem eine Variable, die die Zieldrehung der Tweens als Vektor drei und initialisieren sie als Vektor drei mit der X-Rotation beim Zurücksetzen als X-Wert, aber Null für die Y - und der Funktion eine Definition geben, können wir auch einen optionalen Parameter für die Dauer des Tweens akzeptieren Parameter für die Dauer des Tweens , indem wir diesen als Standardwert verwenden , sodass er Um die Kamera hinter dem Charakter zu drehen, können wir eine neue private Funktion aufrufen der Federarme zu Wir geben an, dass die Y-Drehung der Drehung der Zeichenringe plus einer halben Umdrehung entspricht , die als Pi-Radiant dargestellt wird Als Nächstes schreiben wir die private Funktion, die die Drehung der Federarme zwickt und dabei eine Y-Zieldrehung als Gleitkommazahl akzeptiert, sowie eine Dauer für das Tween mit einem Standardwert für die exportierte Dauer Wir beginnen damit, die Y-Eigenschaft der Zielrotation auf die als Parameter akzeptierte Ziel-Y-Rotation als Parameter akzeptierte Ziel-Y-Rotation Um jedoch sicherzustellen, dass die Drehung immer den kürzesten Weg um das Zeichen nimmt, sollten wir ihren Wert so umbrechen, dass er immer zwischen dem aktuellen Rotationspunkt y minus einer halben Umdrehung und dem aktuellen Rotationspunkt Y plus einer halben Umdrehung liegt. Wenn ein Tween bereits existiert und läuft, sollten wir es beenden, bevor wir ein neues Tween erstellen Wir können dann die Drehung der Federarme über die Dauer mit der Zieldrehung verbinden Als Nächstes lassen wir die Kamera sichtbare Ziele erkennen. Meine Kamera hat noch kein skriptbasiertes Verhalten, also fügen wir ein neues Skript hinzu und legen es in den Skriptordner des Players Wir benötigen eine öffentliche Funktion, um das nächstgelegene sichtbare Ziel akzeptiert einen optionalen Parameter des aktuellen Ziels mit dem Standardwert Null, sodass wir ihn möglicherweise ignorieren können Dies gibt einen Knoten drei D zurück, und der Standardfall ist, Null zurückzugeben , wenn wir kein sichtbares Ziel finden konnten. Um zu bestimmen, welches der sichtbaren Ziele am nächsten ist, müssen wir eine Liste aller sichtbaren Ziele führen. Deklarieren wir eine weitere Variable, die alle sichtbaren Ziele als Array von Knoten drei Ds enthält. Initialisiert, um leer zu sein. Eine einfache Methode, um herauszufinden, welche Ziele sichtbar sind besteht darin, der Kamera einen D-Knoten des Bereichs drei zuzuordnen Nennen wir es Zielbereich. Dieser Bereich wird nach allem auf Kollisionsebene 11 Ausschau halten, die ich ausgewählt habe, um Feinde darzustellen. Vergewissere dich, dass die Kollisionsebene deiner Feinde auf dieselbe Ebene gesetzt ist auf der sie durch die Zielsperre maskiert Außerdem muss ich die transformierten Bereiche so zurücksetzen , dass sie am Ursprung der Kamera positioniert Der D-Knoten der Fläche drei benötigt eine Kollisionsform, und wir können die Shape-Ressource mit einem konvexen Polygon füllen die Shape-Ressource mit einem konvexen Polygon Mithilfe eines konvexen Polygons können wir die Form als Pyramide definieren, die das Sichtfeld der Kamera exakt nachahmt, jedoch Da das Sichtfeld der Kamera die Form einer vierseitigen Pyramide annehmen wird, die Form einer vierseitigen Pyramide annehmen wird, können wir es mit fünf Punkten definieren wobei der erste Punkt der Position der Kamera entspricht Die anderen vier werden entlang der Z-Achse positioniert, was der maximalen Entfernung unserer Sperre auf Reichweite entspricht. Ich verwende eine maximale Entfernung von 15 Metern. Wenn ich zur orthogonalen Ansicht von oben und die Umgebung für einen Moment ausblende, passe ich einfach schnell die Positionen der einzelnen Punkte auf der Pyramide an ungefähr dem Sichtfeld der Kamera entsprechen, 11,4 Meter nach links und nach Gleiche gilt für die orthogonale Ansicht von links, wobei die Y-Werte der Punkte der Pyramide um 6,4 Meter nach oben und unten angepasst 6,4 Bis wir eine Pyramidenform haben, die dem Sichtfeld der Kamera entspricht und sich über 15 Meter erstreckt Ich werde dann wieder zur perspektivischen Ansicht wechseln und wieder über die Sichtbarkeit der Umgebung sprechen. , wenn ein Körper diesen Bereich betritt das vom Körper eingegebene Signal mit dem Kameraskript verbindet, können wir den Körper an unsere Reihe sichtbarer Ziele anhängen Ebenso kann jedes Mal, wenn ein Körper diesen Bereich verlässt, der Körper aus dem Array gelöscht werden Jeder Drei-D-Kollisionskörper auf Schicht 11 , der sich innerhalb dieses Bereichs wird nun als sichtbares Ziel betrachtet In meinem Spring-Arm-Skript benötige ich ein beliebiges Tag, um die Funktion get parent zu verwenden. Wenn wir das Spiel starten und zum Remote-Szenenbaum wechseln, können wir die Kamera auswählen und ihre Eigenschaften im Inspektor ansehen, einschließlich der Anordnung der sichtbaren Ziele. Wenn sich die Kamera in der Szene bewegt, aktualisiert sich die Anordnung der sichtbaren Ziele automatisch und fügt jeden Feind hinzu oder entfernt ihn wenn er das Sichtfeld betritt oder verlässt. Durch Drücken der Sperrtaste wird eigentlich noch nichts anvisiert, aber wir können sehen, wie die Kamera dadurch hinter dem Charakter neu positioniert die Kamera dadurch hinter dem Bevor wir das Anvisieren eines Ziels zulassen, sollten wir vielleicht auch überprüfen, ob die Sichtlinie des Spielers zum Ziel durch das Gelände behindert wird Fügen wir der Kamera außerdem einen Drei-D-Knoten hinzu und nennen ihn Sichtlinie Suchen Sie sich dann im Kameraskript einen Verweis darauf. Um das nächste sichtbare Ziel mit unserer Kamera zu finden, Wenn das Array leer ist, seine Größe Null ist, dann gibt es keine sichtbaren Ziele berücksichtigt werden müssen, und wir sollten einfach zurückkehren. Wenn es sichtbare Ziele gibt, die berücksichtigt werden müssen, müssen wir die Entfernungen der einzelnen Ziele zur Kamera vergleichen , um herauszufinden , welches Ziel am nächsten ist. Dazu benötigen wir eine Variable, die die Entfernung zwischen dem aktuellen Ziel und der Kamera als schwimmend festlegt. Die nächste Entfernung als schwimmend und der Index des nächstgelegenen sichtbaren Ziels als Ganzzahl sichtbaren Wir setzen die nächste Entfernung mit dem Schlüsselwort I NF auf unendlich und den nächstgelegenen Index auf negativ eins, was bedeutet, dass es sich nicht um einen gültigen Index dass es sich nicht um einen Wenn nach der Iteration durch das gesamte Array sichtbarer Ziele der nächstgelegene Index immer noch negativ ist, wurde kein sichtbares Ziel als gültig angesehen, und wir sollten und wir Andernfalls können wir das sichtbare Ziel am nächstgelegenen Index zurückgeben das sichtbare Ziel am nächstgelegenen Index Wenn das sichtbare Ziel an Index I das aktuelle Ziel ist, können wir es mit der Continue-Anweisung überspringen. Für jedes andere sichtbare Ziel müssen wir dessen Entfernung von der Kamera berechnen. Wir können die Entfernung zum Quadrat verwenden da dies mathematisch effizienter ist Wenn die aktuelle Entfernung geringer ist als die nächste Entfernung, müssen wir prüfen, ob die Sichtlinie zu diesem Ziel Zuerst müssen wir jede Drehung der aktuellen Sichtlinie zurücksetzen jede Drehung der aktuellen Sichtlinie Stellen Sie dann die Zielposition des Strahlwurfs auf die globale Position des Ziels abzüglich der globalen Position der Kamera ein und erzwingen Sie eine Aktualisierung. Die Position der Charaktere befindet sich jedoch in der Regel auf dem Boden, leicht durch kleine Geländeabschnitte versperrt wird und nicht immer ein guter Indikator für die Sichtlinie Addieren wir auch 1 Meter nach oben. Wenn die Sichtlinie mit etwas kollidiert und dieses Etwas das sichtbare Ziel ist, dann wird die Sichtlinie durch nichts behindert, was dieses Ziel zum nächsten sichtbaren Ziel macht , das wir bisher gefunden haben Wir können die Entfernung, die der aktuellen Entfernung am nächsten ist , und den Index, der am nächsten ist, auf I setzen am nächsten ist , und den Index, der am nächsten ist, auf , bevor wir den Rest des Arrays durchgehen Dadurch wird nun entweder Null oder das der Kamera am nächsten gelegene sichtbare Ziel zurückgegeben oder das der Kamera am nächsten gelegene sichtbare Ziel Die Sichtlinie wird auch mit Ebene 11 kollidieren und nach Feinden suchen, aber auch Ebene eins, die durch das Gelände blockiert wird Es wäre auch nett, den Spieler anhand der Zielanzeige wissen zu lassen, worauf er sich eingelassen Fügen wir einen Sprite-Three-D-Node als untergeordnetes Element des Player-Eingabe-Handlers hinzu und benennen ihn in Zielindikator Für die Textur verwende ich einen leeren Mauszeiger in der Scrollbar. Ändern Sie jedoch die Eingabeeinstellungen, um das vormultiplizierte Alpha einzuschalten , damit es etwas flüssiger aussieht Und skalieren Sie es auf ein Viertel seiner Größe. ich dann den Flaggenbereich ausdehne, stelle ich die Plakatflagge so ein, dass sie immer zur Kamera zeigt Und bei der Option „Keine Tiefe wird das Sprite immer über alles andere gezogen , unabhängig von seiner Position im Drei-D-Raum relativ zur Kamera Die Zielanzeige kann standardmäßig unsichtbar sein , da der Spieler ohne Angabe eines Ziels startet Mit dem Add-on bereit einen Verweis auf die Zielanzeige abrufen Wir müssen es dann über dem verschlossenen Ziel positionieren. Nachdem wir also festgestellt haben, worauf der Spieler gefesselt ist, ob es ein Ziel gibt. Eine einfache Möglichkeit, den Zielanzeiger dem Ziel folgen , besteht darin, ihn auf dieses Ziel auszurichten. Wir können ihn dann ein paar Meter nach oben bewegen, um ihn über dem Kopf des Ziels zu positionieren und seine sichtbare Eigenschaft auf true zu setzen. Wenn es kein anzuzeigendes Ziel gibt, können wir den Indikator wieder auf diesen Knoten setzen und seine Sichtbarkeitseigenschaft wieder auf „fällt“ setzen, um ihn auszublenden. Lass es uns ausprobieren. Wenn wir die Sperrtaste drücken, der nächste Feind ins Visier genommen und die Anzeige wird über dem Kopf des Ziels positioniert Wenn Sie die Umschalttaste erneut drücken, wechseln Sie zum nächstgelegenen Feind Sie die Sperrtaste gedrückt halten und drücken , wird die Sperre ausgeschaltet Wenn es nur ein sichtbares Ziel gibt auf das wir bereits fixiert sind, ist die Sperre ebenfalls deaktiviert. In unserem Spiel hat der Spieler jetzt Feinde im Visier. In der nächsten Lektion werden wir das Verhalten der Kamera und des Charakters ändern das Verhalten der Kamera und des , während sie aktiviert sind. Wir sehen uns in der nächsten Lektion. 4. Strafe: Hallo, Freunde. In der vorherigen Lektion haben wir unserem Spiel eine kontextsensitive Umschalttaste hinzugefügt unserem Spiel eine kontextsensitive Umschalttaste hinzugefügt In dieser Lektion werden wir ändern, wie sich die Spielerknoten verhalten, wenn sie sich auf ein Ziel festlegen Beginnend mit dem Spielerskript senden wir, sobald ein Ziel festgelegt wurde, sobald ein Ziel festgelegt wurde, ein Signal aus, sodass jedes andere Skript den Wert einer Änderung des Ziels abhören und darauf reagieren kann , indem wir als Parameter angeben, was als Ziel ausgewählt wurde . Mithilfe eines Setters können wir das Signal immer dann ausgeben, wenn der Wert des Ziels aus irgendeinem Grund geändert wird Jetzt können sich alle drei Charaktere, der Federarm und die Kamera mit dem Signal verbinden und es verwenden, um ihre eigenen Variablen für das Ziel festzulegen für das Ziel Unabhängig vom Wert von target im Skript zur Bearbeitung von Spielereingaben haben alle anderen Knoten dieselben Informationen, auch wenn der Wert auf Null gesetzt ist. Schreiben Sie für jeden eine einfache Funktion, die eine lokale Zielvariable festlegt eine lokale Zielvariable sodass alle problemlos darauf zugreifen können. Sobald unser Charakter ein Ziel im Visier hat, würden wir erwarten, dass er sich dem Ziel zuwendet, anstatt in die Richtung zu schauen, in die er sich bewegt. In meinem Drehbuch erfolgt die Drehung des Charakters im Rahmen eines physikalischen Prozesses, der dem Charakter sagt, dass er in die Richtung der Bewegungseingabe schauen soll . Deklarieren wir eine neue Variable am Anfang des Skripts, deren Richtung als Drei angezeigt werden soll. Und ersetzen Sie im Funktionsaufruf die Eingaberichtung durch will in die Richtung zeigen. Dann können wir vor diesem Funktionsaufruf überprüfen, ob das Zeichen an ein Ziel gebunden ist. Wenn sie an ein Ziel gebunden sind, wird die Richtung, in die sie schauen wollen das Ziel gerichtet sein, was wir leicht bestimmen können, indem wir ihre globalen Positionen subtrahieren Wenn sie nicht fixiert sind, werden sie genauso wie zuvor in die eingegebene Bewegungsrichtung schauen wollen genauso wie zuvor in die eingegebene Bewegungsrichtung Jetzt blickt der Charakter auf das Ziel, auf das er sich fixiert hat, aber ihre lokalen Bewegungsanimationen sehen nicht besonders gut aus, da sie sich nur auf der Geschwindigkeit, in der sich der Charakter bewegt, mischen und nicht auf der Richtung In der Zustandsmaschine des Animationsbaums befindet sich die Figur im Jump-Ruhezustand , da es in der Szene keinen Boden Bei der Lokbewegung handelt es sich um einen eindimensionalen Mischraum, dem die Animationen „Gehen“ und „Laufen“ im Leerlauf auf der Grundlage der Bewegungsgeschwindigkeit der Figur Lassen Sie uns diesen Zustand entfernen und ihn durch einen anderen Zustandsmaschine ersetzen Wiederverbinden der Übergänge mit den anderen Zuständen, beginnend mit einem Übergang vom Start zur Fortbewegung, um ihn zum Standardzustand zu machen Ich hatte den Übergang zur Starthilfe mit einer Querstärke von 0,3 Sekunden aktiviert Und Sprungland zur Fortbewegung wechseln am Ende mit einer Quergeschwindigkeit von 0,67 Sekunden Ich lasse den Übergang von Fortbewegung zu Leerlauf vorübergehend weg, während ich in der Fortbewegungszustandsmaschine arbeite , sodass der Charakter im Fortbewegungsmodus bleibt und ich die Ergebnisse in Fortbewegungsmodus bleibt und ich die Ergebnisse sehen kann Durch Drücken der Play-Taste wird der Charakter in den Fortbewegungszustand versetzt und er wird abgeschaltet, weil dieser momentan leer ist. Innerhalb des Fortbewegungsmodus benötigen wir zwei verschiedene Gruppen von Fortbewegungsanimationen für den Fall, dass der Charakter an ein Ziel gefesselt ist und wann nicht, und um zwischen ihnen wechseln zu können Die Standardeinstellung wird dieselbe sein wie zuvor, ein eindimensionaler blonder Raum Nennen wir es nicht gesperrt. Dann können wir auch einen zweidimensionalen blonden Raum hinzufügen. Nennen wir das als gesperrt. Wenn Sie einen Übergang von „Start“ zu „ Nicht gesperrt“ hinzufügen , wird dieser Übergang zur Standardeinstellung. Wir können dann von „Nicht gesperrt“ zu „ gesperrt“ wechseln , wenn der Wert von „Ziel“ nicht Null ist. Wir können den Wert auf „Nur Ziel“ kürzen und ihm eine kurze Überblendung geben. Und mit demselben Crossfade zu not locked on, wenn nicht target zurückkehren . Innerhalb des nicht gesperrten Verschmelzungsbereichs. Wir können es genau so nachstellen, wie es vorher war, mit einem Mindestwert von Null, bei dem Animationen im Leerlauf, beim Gehen und Laufen auf der Grundlage der Bewegungsgeschwindigkeit des Charakters gemischt Wenn das erledigt ist, benutzen Sie die Semmelbrösel, um eine Ebene hinauf zur Fortbewegungszustandsmaschine zu gelangen, und drücken Sie die Play-Taste an der eingeschalteten Zustandsmaschine, um den Charakter in diesen Zustand zu zwingen Innerhalb des gesperrten Überblendfeldes mischen wir die Animationen basierend darauf, mischen wir die Animationen basierend welche Richtung sich der Charakter im Verhältnis zu seiner Vorwärtsrichtung bewegt, also in Richtung seines Ich stelle die Rasterausrichtung in Schritten von eins ein, um die Sache zu vereinfachen Wenn wir unsere Ansicht so positionieren, dass sie sich hinter der Figur und uns vorstellen, dass sie auf ein Ziel vor ihnen fixiert ist, dann gibt auf ein Ziel vor ihnen fixiert ist, die Y-Achse an, wie schnell sich die Figur auf das Ziel zu oder von ihm weg bewegt Die X-Achse gibt an, wie schnell sich die Figur nach links oder rechts bewegt und dabei das Ziel umkreist das Ziel umkreist Beginnen wir damit, die inaktive Animation in der Mitte zu platzieren. Für die X-Achse wollen wir auf der linken Seite eine Straf-Link-Animation und auf der rechten Seite eine Straf-Animation nach rechts platzieren linken Seite eine Straf-Link-Animation und auf der rechten Seite eine Straf-Animation nach rechts Für die Y-Achse können wir eine laufende Animation an der vorderen Position platzieren , wodurch Dreiecke im Verschmelzungsraum erzeugt werden, die zeigen, wie die verschiedenen Animationen zusammengefügt werden Und wenn wir in der negativen Y-Position eine Animation hinzufügen, die rückwärts läuft , wir auch mehr Dreiecke hinzu Wenn wir die Mischposition ändern, können wir sehen, wie der Charakter aussehen wird, während Bewegungseingaben in jede Richtung geben Je nachdem, welche Elemente du verwendest, kannst du diesem Mischraum auch diagonale Bewegungsanimationen hinzufügen. Manchmal simuliert diese Vorschau nicht genau , wie sich der Charakter verhalten wird , während das Spiel läuft. Und du solltest es immer testen, indem du das Spiel spielst , um sicherzugehen, dass es im Spiel gut aussieht. Aber bevor wir das tun, kehren wir zur Stammebene der Zustandsmaschine zurück und fügen den Übergang von Fortbewegung zu Leerlauf hinzu , vorausgesetzt , der Charakter befindet sich nicht auf dem Boden Früher habe ich für diesen Übergang eine Überblendzeit von 0,3 Sekunden Wir müssen auch den Teil unseres Skripts aktualisieren, der die Verschmelzungsposition des Mischraums festlegt, was in meinem Charakterskript Bodenphysik der Fall ist. den Animationsbaum auswählen, können wir den Eigenschaftspfad der nicht fixierten Mischposition kopieren und in der Set-Funktion aktualisieren. Dies muss jedoch nur festgelegt werden, wenn der Charakter nicht an ein Ziel gebunden ist. Wenn sie an ein Ziel gebunden sind, müssen wir stattdessen die Verschmelzungsposition des gesperrten Verschmelzungsbereichs festlegen . Die fixierte Verschmelzungsposition ist ein Vektor zwei mit einem X und einem Y , den wir berechnen müssen. Lassen Sie uns also eine Variable mit dem Namen locked on blend deklarieren, um sie zu speichern. Um zu vermeiden, dass dieselben Berechnungen mehrmals wiederholt werden, deklariere ich außerdem eine weitere Variable , um die Relativgeschwindigkeit der Figur zu speichern sich um ihre X-Z-Geschwindigkeit geteilt durch ihre Laufgeschwindigkeit. Nach der Berechnung dieses Werts die Verschmelzungsposition des nicht fixierten Mischbereichs auf kann die Verschmelzungsposition des nicht fixierten Mischbereichs auf die Länge dieses Vektors gesetzt werden. Wenn das Zeichen an ein Ziel gebunden ist, können wir den X-Wert der Verschmelzungsposition anhand des Punktprodukts des globalen Basisvektors x des Rigs mit seiner Relativgeschwindigkeit ermitteln Das Punktprodukt zweier Vektoren ergibt eine Zahl, die angibt, wie ähnlich oder unterschiedlich sie sind Wir prüfen also, wie ähnlich die Relativgeschwindigkeit eines Charakters einem Vektor ist , der direkt nach rechts von ihm zeigt. Je nachdem, wie dein Charakter aufgebaut ist welche Richtung als vorwärts betrachtet wird, musst du diesen Wert möglicherweise mit minus eins multiplizieren , um ihn umzukehren. Die Y-Mischposition kann auch mit derselben Methode bestimmt werden, allerdings unter Verwendung des vorwärts gerichteten Z-Vektors des Zeichens. Als Nächstes sollte die Kamera, während sie auf ein Ziel fixiert ist, auf das Ziel schauen , nicht auf den Spielercharakter. In der Prozessfunktion der Kamera, Delta ignoriert wird, können wir, falls es ein Ziel gibt, der Kamera sagen, dass sie auf das Ziel schauen soll und einen Meter hinzufügen, um nicht auf ihre Füße zu schauen Wenn wir den Wert des Ziels festlegen das Ziel auf Null gesetzt ist, können wir die Drehung der Kamera so zurücksetzen, dass sie wieder zur gleichen Drehung zurückkehrt wie ihr übergeordneter Knoten, der Federarm, und ihre Drehung auf Vektor 30. Möglicherweise möchten wir auch die Lock-On-Funktion auslösen wenn das aktuelle Ziel unsere sichtbare Reichweitengrenze Entweder das Sperren oder das automatische Umschalten auf ein näher gelegenes Ziel Fügen wir also ein Signal hinzu, wenn aktuelle Ziel die Reichweite verlässt, und senden es aus, wenn es sich bei dem Körper, Bereich verlassen hat, um das aktuelle Ziel handelt Wir können dieses Signal dann mit dem Skript zur Bearbeitung von Spielereingaben verbinden zur Bearbeitung von Spielereingaben Aufrufen der Toggle Lock-Funktion. Je nachdem, ob Sie möchten, dass das Verhalten zum nächstgelegenen Ziel wechselt oder einfach blockiert, möchten Sie vielleicht ein echtes Argument für die Stärke des Parameters binden für die Stärke des Parameters Im Springarm-Skript wollen wir, auf ein Ziel fixiert dass der Federarm immer vom Ziel weg zeigt, wenn wir sind, damit sowohl das Ziel als auch der Spielercharakter im Blickfeld der Kamera bleiben. Fügen wir eine neue Variable hinzu, um diese Richtung als Vektor drei beizubehalten. Wenn dann der Wert des Ziels festgelegt wird und er nicht Null ist, können wir den Wert der Zielrichtung so festlegen , dass er der Differenz unserer globalen Position minus der globalen Position des Ziels entspricht. Dies führt zu einem Vektor, der vom Ziel zurück zum Spielercharakter zeigt . Wir können dann die Tween-Rotationsfunktion erneut verwenden, sie erwartet jedoch einen Float-Parameter, der eine Y-Rotation darstellt Wir können die Y-Drehung, die in diese Richtung zeigt, mithilfe der Trigonometriefunktion A t two ermitteln mithilfe der Trigonometriefunktion und ihr die X- und Z-Werte unserer Zielrichtung geben die X- und Z-Werte unserer Sobald das Ziel festgelegt ist, dreht der Federarm die Kamera so, dass sie sich in die entgegengesetzte Richtung zum Ziel hinter dem Spieler Aber wir wollen, dass es dort bleibt. in der Prozessfunktion Wenn in der Prozessfunktion der Zielwert gesetzt wurde und in Klammern entweder das Tween nicht existiert oder nicht läuft, was bedeutet, dass das Tween beendet ist und der Federarm in Position ist, dann können wir die gleichen Berechnungen durchführen, aber einfach den Wert der Drehung y direkt setzen, aber einfach den Wert der Drehung y direkt setzen anstatt Dadurch zeigt der Federarm vom Ziel weg, während er am Ziel fixiert ist, sodass das Ziel und der Spielercharakter im Blickfeld der Kamera bleiben . Schließlich möchten wir im Skript zur Handhabung von Spielereingaben verhindern, dass der Spieler den Federarm dreht, während er auf ein Ziel fixiert ist. Das passiert an zwei verschiedenen Stellen in meinem Skript, eine für die PC-Steuerung mit der Maus und eine andere für die Controller-Unterstützung mit dem rechten Stick. Also füge ich beide einfach in eine if-Anweisung ein , um diese Eingaben nicht zuzulassen, solange ich an ein Ziel gebunden bin. Lass es uns ausprobieren. Wenn wir einen Feind im Visier haben, fokussiert sich die Kamera auf das Ziel, während sich der Federarm dreht, um die Kamera in die entgegengesetzte Richtung zu positionieren den Charakter bewegen, drehen sie sich, sodass sie dem Feind zugewandt sind, und animieren so fließende Bewegungen in alle Richtungen Der Federarm sorgt dass sich die Kamera hinter der Figur befindet und vom Ziel weg zeigt, vom Ziel weg zeigt, während die Kamera weiterhin auf das Ziel schaut Die normale Kamerasteuerung des Spielers wurde deaktiviert, während er gesperrt war. Befindet sich das anvisierte Ziel außerhalb der Reichweite , wechselt es automatisch zum nächstgelegenen Ziel oder sperrt , wechselt es automatisch zum nächstgelegenen Ziel oder sperrt ab, wenn es kein Ziel zum Anvisieren gibt. Wenn wir die Sperre erzwingen, fokussiert sich die Kamera wieder auf den Spielercharakter, normale Steuerung des Federarms wird wieder aufgenommen und die Bewegungsanimationen des Charakters kehren Unsere Spielerknoten passen jetzt ihr Verhalten an, wenn sie an ein Ziel gebunden sind. In der nächsten Lektion lassen wir den Spielercharakter Angriffe ausführen. Wir sehen uns in der nächsten Lektion. 5. Angriff: Hallo Freunde. In der vorherigen Lektion haben wir das Verhalten der Spielerknoten geändert , wenn sie auf ein Ziel fixiert sind. In dieser Lektion werden wir Angriffsanimationen hinzufügen, Angriffsanimationen damit sich die Charaktere gegenseitig angreifen können. Öffnen wir zunächst die Projekteinstellungen den Tab Eingabemap und fügen ein neues Eingabeereignis für Angriffe hinzu. Ich verwende die linke Maustaste und die rechte Schultertaste auf meinem Controller. Dann können wir im Player-Eingabe-Handler-Skript überprüfen, ob die Angriffstaste gedrückt wurde als wir nach Eingaben zur Charaktersteuerung suchen. Wenn die Angriffstaste in diesem Frame gedrückt wurde, sollten wir dem Charakter sagen, dass er angreifen soll. Aber was ist, wenn der Charakter beschäftigt ist? Sie könnten springen oder eine andere Aktion ausführen und wir möchten vielleicht nicht, dass sie diesem Moment angreifen können. Es wäre ziemlich frustrierend, wenn der Spieler warten müsste, bis ein Angriff möglich ist , bevor er die Taste drückt ziemlich frustrierend, wenn der Spieler warten müsste meisten modernen Spielen wird das Drücken der Taste für eine kurze Zeit nach dem Drücken der Taste als gültig angesehen, was als Eingabepufferung bezeichnet wird Fügen wir dem Eingabe-Handler des Spielers eine Zeit oder einen Knoten hinzu. Nennen Sie ihn Eingabepuffer und setzen Sie seine One-Shot-Eigenschaft auf true, sodass der Countdown jeweils nur einmal erfolgt. wir mit dem Add-On Ready einen Verweis auf diesen Eingangspuffer-Timer abrufen, können wir den Timer starten nachdem wir dem Charakter gesagt haben, dass er angreifen soll, dann auf sein Timeout-Signal warten Nachdem der Timer auf Null heruntergezählt ist, werden wir dem Charakter sagen, dass er die Anweisung zum Angriff stornieren soll Während der Countdown läuft, versucht der Charakter also jederzeit anzugreifen, wenn er bereit ist. Die Standardwartezeit für den Timer beträgt 1 Sekunde, was für den Eingabepuffer des Angriffs eine angemessene Zeitspanne darstellt. Eine weitere Eingabe, die wir vielleicht zwischenspeichern möchten, ist die Sprungeingabe. Nach dem gleichen Muster wie bei der Attack-Eingabe können wir den Timer starten, auf sein Timeout-Signal warten dann den Sprungeingang abbrechen. im Charakterskript damit beginnen, Lassen Sie uns im Charakterskript damit beginnen, eine neue Coderegion für den Kampf zu erstellen. Verschieben Sie dann die Zielfunktion des Spielers in diese Region. Wir benötigen eine öffentliche Funktion, die dem Charakter sagt , dass er angreifen soll, und eine weitere, die ihm sagt, dass er die Anweisung stornieren soll. Für die Sprungfunktion wird außerdem die zweite Sprungfunktion „Match and Cancel“ benötigt . Der Hauptzweck dieser Funktionen besteht darin, Variablen festzulegen, die vom Animationsbaum überprüft werden damit dieser weiß, in welche Zustände er reisen muss. Am Anfang des Skripts fügen wir weitere Variablen hinzu, die angeben , was der Charakter als Nächstes tun will Gepufferte Eingaben als Boolesche Werte, ob er springen oder angreifen will Dann setzt die Angriffsfunktion die Variable will angreifen auf true und Cancel attack setzt sie wieder Da die Eingabe gepuffert wird, müssen wir nicht mehr verlangen, dass sich der Charakter bewegen oder auf dem Boden sein muss, sondern wir können diese Verantwortung an die Zustandsmaschine der Animationsbäume delegieren Zustandsmaschine der Animationsbäume Außerdem müssen wir der Wiedergabe der Animation-Bree-State-Maschine nicht mitteilen Wiedergabe der Animation-Bree-State-Maschine , dass sie in den Startmodus wechselt Wir werden diesen Übergang automatisch vornehmen , wenn die Bedingungen erfüllt sind. Wir möchten jedoch nicht, dass diese beiden Variablen gleichzeitig wahr sind. Der Charakter wird entweder springen oder angreifen wollen , nicht beides. Jedes Mal, wenn eine gepufferte Eingabe auf true gesetzt wird, werden alle anderen auf false gesetzt, wodurch werden alle anderen auf false gesetzt die Anweisung überschrieben wird in der Charakterszene den Animationsbaum auswählen und zum Animationsbaumfenster wechseln, können wir die Zustandsmaschine sehen Lassen Sie uns den Übergang von der Fortbewegung zum Sprungstart so ändern , automatisch erfolgt, vorausgesetzt, dass sich der Charakter auf dem Boden befindet und sich bewegen kann und springen möchte Jetzt springt der Charakter automatisch, sobald er innerhalb von 1 Sekunde nach Drücken der Sprungtaste dazu in der Lage Dies ist besonders nützlich um Sprünge nacheinander zu verketten, da der Spieler die Sprungtaste drücken kann, bevor er den Boden berührt Schauen wir uns jedoch die Jump-State-Maschine an und überlegen wir uns, wie die Angriffsanimationen integriert Wir könnten von der Fortbewegung zur Attacke und wieder zurück übergehen zur Attacke und wieder zurück Aber die Animationen würden schlecht aussehen, wenn wir wollen, dass sich der Charakter beim Angriff bewegen kann Ich würde dem Charakter nicht erlauben, beim Springen anzugreifen. Stattdessen wäre es besser, Animationen, bei denen der Charakter bewegt wird , von Animationen zu trennen der Charakter bewegt wird , , bei denen Aktionen ausgeführt werden. Wenn Ihr State Machine noch nicht als Projektressource gespeichert wurde , klicken Sie auf das Drop-down-Menü neben Tree Root und wählen Sie Speichern unter. Ich habe meine bereits im Ordner mit den Charakterszenen gespeichert und ihr den Namen Charakteranimationen gegeben. Aber ich werde es in Charakterbewegungen umbenennen. Nachdem die Zustandsmaschine gespeichert ist, entfernen wir sie aus dem Animationsbaum der Figur und ersetzen sie stattdessen durch einen Mischbaum für Animationsknoten. Im Animationsbaum wird jetzt ein Diagramm angezeigt, das unseren Mischbaum enthält, sodass wir eine beliebige Anzahl von Animationen zusammenfügen können. Klicken Sie mit der rechten Maustaste in einen leeren Bereich und wählen Sie Laden. Navigiere dann durch deine Projektressourcen , um die Zustandsmaschine für die Charakterbewegung zu finden. Die Zustandsmaschine, die wir zuvor verwendet haben, ist jetzt ein Knoten im Blend-Tree-Diagramm, und das Ergebnis der Zustandsmaschine wird über den Stift auf der rechten Seite ausgegeben. Wenn wir die Ausgabe der Zustandsmaschine mit der Ausgabe des Blend-Trees verbinden , funktioniert die Animation genauso wie zuvor. Der Zweck des Mischbaums besteht jedoch darin , mehrere Animationen miteinander zu verbinden. Trennen wir den Pin. Klicken Sie dann mit der rechten Maustaste und fügen Sie einen Blend Two-Node hinzu. Der Blend Two-Node beginnt mit der Animation, die mit seinem Eingangs-Pin verbunden ist, und fügt einen Prozentsatz der Animation ein, der seinem Blend-Eingangspin verbunden ist. Das Ergebnis dieser Mischung wird den Pin auf der rechten Seite ausgegeben, den wir mit dem Blend Trees-Ausgang verbinden können. Die Animation, die wir mit den Bewegungen des Charakters mischen wollen , sind die Aktionen des Charakters, nämlich seine Angriffe. Wir können dem Blend-Tree eine weitere Zustandsmaschine hinzufügen und sie Aktion nennen. Verbinden Sie dann seinen Ausgang mit dem Blend-Eingangspin von Blend Two Nodes. Als Nächstes öffnen wir die Action State Machine und starten den Charakter in der Animation im Leerlauf. Übergang von „Start“ zu Inaktiv“, um ihn zum Standard-Aktionsstatus zu machen Als Nächstes benötigen wir einen Überblick unseren Charakter und können sowohl die Bewegungs- als auch die Actionstatus-Maschine starten , indem wir in den jeweiligen Startzuständen auf die Play-Schaltfläche Kehren Sie dann zur Wurzel des Blendbaums zurück. Unser Charakter scheint sich immer noch in der Jump-Idle-Animation zu befinden, da der Prozentsatz der Actionanimation in sie eingemischt wird, derzeit Null ist Wenn wir den Ziehpunkt auf eins ziehen, können wir sehen, wie sich die Animation allmählich von „Im Leerlauf springen“ in „Leerlauf“ ändert Klicken Sie anschließend auf die Schaltfläche „Filter bearbeiten und aktivieren Sie die Option „Filterung aktivieren“. Lassen Sie uns das Fenster zur Seite stellen, damit wir unseren Charakter sehen können , während wir einzelne Knochen filtern und entscheiden, auf welche Knochen unsere Actionanimationen angewendet werden sollen und auf welche nicht. Aktiviert alle Knochen, die Oberkörper des Charakters ausmachen. Jetzt wird der Unterkörper der Figur, einschließlich ihrer Position, durch den Bewegungszustand beeinflusst. Springe im Leerlauf, während ihr Oberkörper durch den Aktionszustand „Leerlauf“ gesteuert wird. Auf diese Weise können wir diese Animationen auf drei verschiedene Arten zusammenfügen . Wenn sich der Charakter bewegt, aber keine Aktion ausführt, ist der Mischwert gleich Null, wobei nur die Ausgabe der Bewegungszustandsmaschine verwendet wird . Wenn der Charakter eine Aktion ausführt, sich aber nicht bewegt, ist der Mischwert eins und die Filter sind ausgeschaltet, sodass nur die Ausgabe der Aktionszustandsmaschine verwendet wird und die Filter sind ausgeschaltet, sodass . Wenn sich der Charakter sowohl bewegt als auch eine Aktion ausführt, werden die Filter aktiviert. Dabei wird die Ausgabe der Bewegungszustandsmaschine für den Unterkörper des Charakters und die Ausgabe der Aktionszustandsmaschine für seinen Oberkörper verwendet. Nennen wir diese Mischung aus zwei Knoten „Unterer und Oberkörper“, da sie die Animationen des Oberkörpers mit den Animationen des Unterkörpers verbindet den Animationen des Unterkörpers Wenn der Mischwert jedoch Null oder Eins ist, die Animationen in einer der werden die Animationen in einer der Zustandsmaschinen nicht ausgeführt, um Verarbeitungszeit zu sparen. Dies kann zu Problemen führen , wenn wir uns darauf verlassen, dass sie Eigenschaften festlegen oder Methoden aufrufen Es kann nützlich sein, immer beide Zustandsmaschinen laufen zu lassen, auch wenn der Charakter keine Aktionen ausführt oder sich nicht bewegt. Um sicherzustellen, dass beide Zustandsmaschinen immer aktiv sind, können wir den Mischwert auf 1% setzen und ihn bei Ausführung einer Aktion auf 99% erhöhen. Wir können davon ausgehen, dass es mit einem Mischungsanteil von 1% beginnen sollte mit einem Mischungsanteil von 1% beginnen da der Charakter beim ersten Laden keine Aktionen ausführt. Zurück im Charakterskript, da der Animationsbaum viel komplexer werden wird , wäre es eine gute Idee, seine Verhaltensweisen in einem eigenen Skript zu abstrahieren. Wir können die Wiedergabevariable der Zustandsmaschine aus dem Zeichenskript entfernen und dem Animationsbaum ein neues Skript hinzufügen. Ich speichere es im Ordner für Charakterskripte. Im neuen Skript des Animationsbaums besteht unser Hauptziel darin, die drei Animationsmischungen zu erstellen , die wir gerade erwähnt haben. In der Prozessfunktion müssen wir den Parameter für die Füllmenge festlegen, müssen wir den Parameter für die Füllmenge festlegen wie wir es bei den Verschmelzungsräumen getan haben. Den Eigenschaftenpfad kopieren und einen Mischungswert angeben. Lassen Sie uns den Mischungsbetrag zu einer privaten Float-Variablen mit einem Standardwert von 1% und diesen Wert als Argument übergeben. Wir müssen dann den Wert von Blend Amount ändern je nachdem, ob der Charakter eine Aktion ausführt oder nicht . Speichern wir die Wiedergabe der Aktionszustandsmaschinen in einer Variablen. Diesmal verwenden wir das Schlüsselwort self, da dieses Skript an den Baum angehängt ist, und verwendet den Eigenschaftenpfad die Wiedergabe der Action State Machine. Dann können wir in der Prozessfunktion überprüfen, in welchem Knoten die Wiedergabe des Aktionszustands gerade befindet. Und wenn es sich im Ruhezustand befindet, bedeutet das, dass der Charakter keine Aktionen ausführt, und wir können den Mischwert auf 1% setzen. Andernfalls führen sie eine Aktion aus und wir können sie auf 99% setzen. Dies wird jedoch eine sofortige Änderung sein , die etwas nervös aussehen könnte Anstatt die Variable also direkt auf 1% oder 99% zu setzen, sollten wir sie im Laufe der Zeit einfach um einen kleinen Betrag in Richtung dieser Zahl bewegen Laufe der Zeit einfach um einen kleinen Betrag in Richtung dieser Zahl Mit der Funktion „Move Toward“ können wir von dem ausgehen, was die Variable gerade ist, und sie in Richtung Delta bewegen, wie wir sie haben wollen. Dadurch dauert der Übergang 1 Sekunde, was ein bisschen lang ist. Lassen Sie uns Delta also mit einer neuen Variablen multiplizieren , um die Mischgeschwindigkeit Ich gebe ihr einen Standardwert von vier. Der Übergang wird eine Viertelsekunde dauern. Um die Filter ein- oder auszuschalten, benötigen wir direkten Zugriff auf den Blend-Two-Node. Wir deklarieren also eine Variable, die sie aufnehmen soll, was vom Typ Animation Node Blend Two ist Wir können von der Baumwurzel des Animationsbaums aus darauf zugreifen , indem wir die Funktion get node verwenden Diese Funktion akzeptiert einen Zeichenkettennamen , den wir als denselben Namen angeben können, den wir dem Knoten im Blend-Tree-Diagramm gegeben haben , also unten plus oben. Achten Sie darauf, dass die Schreibweise exakt gleich ist. Wir dürfen die Filter nicht ein- oder ausschalten , während der Animationsbaum verarbeitet wird. Lassen Sie uns also eine öffentliche Funktion erstellen , damit das Charakterskript das für uns erledigt und dem Animationsbaum mitteilt, dem Animationsbaum mitteilt ob sich der Charakter bewegt oder nicht. Wenn sich der Charakter bewegt, sollten die Filter aktiviert sein, um die Aktionen des Oberkörpers mit den Bewegungen des Unterkörpers zu verbinden . Wenn der Charakter stationär ist, können Filter deaktiviert werden nur die Aktionsanimationen verwendet werden. Wenn wir schon dabei sind, fügen wir auch zwei weitere Funktionen hinzu, um die Mischungsmenge der Locomotion-Blend-Laces festzulegen , damit sie nicht vom Zeichenskript abstrahiert werden Legt fest, dass die Mischung gesperrt ist, wobei ein Vektor-Zwei-Parameter für die Füllmenge akzeptiert wird, Parameter für die Füllmenge der verschlossenen Verschmelzungsfläche festgelegt der verschlossenen Verschmelzungsfläche Und stellen Sie „Nicht gesperrt“ ein, akzeptieren einen Parameter vom Typ „Float“ für die Füllmenge den Parameter „ Füllmenge“ für den nicht gesperrten Mischbereich fest. Zurück im Zeichenskript können wir sehen, dass die Eigenschaftspfade zu den Füllmengen nicht mehr gültig sind, da sie sich nicht auf die Bewegungszustandsmaschine beziehen. diese Funktionen abstrahieren, behalten wir alle Änderungen am Animationsbaum bei, die in einem eigenen Skript enthalten sind Im normalen physikalischen Prozess müssen wir dem Animationsbaum auch mitteilen , müssen wir dem Animationsbaum auch mitteilen ob sich die Figur gerade bewegt oder nicht Wir gehen jetzt jedoch davon aus , dass für jeden Charakter dieses Skript an seinen Animationsbaum angehängt sein muss und dass er denselben Animationsbaum verwendet. Speichern wir also unseren neuen Animationsbaum als Projektressource. Ich lege es zusammen mit der Statusmaschine für Charakterbewegungen in den Ordner mit den Charakterszenen . Aktualisiere dann alle anderen Charaktere so, dass sie den neuen Animationsbaum verwenden , und hänge das Skript an ihn an, sodass sie alle auf die gleiche Weise funktionieren. Ich verwende in diesem Projekt nur den Barbaren und die Skelette, aber der Nachtmagier und der Schurke sollten ebenfalls aktualisiert werden, wenn du sie benutzt in diesem Projekt nur den Barbaren und die Skelette, aber der Nachtmagier und der Schurke sollten ebenfalls aktualisiert werden, wenn du sie Dies führt jedoch zu einem neuen Problem. Wenn jedes Zeichen dieselbe Blend-Tree-Ressource verwendet, wird die Änderung der Eigenschaft „ Filter aktivieren“ für ein Zeichen auch für alle Zeichen geändert. Wir können das umgehen, indem jedem Charakter eine eigene Kopie des Mischbaums geben. Um zu vermeiden, dass jede Änderung im Mischbaum jedes Charakters jedes Mal repliziert werden muss, verwende ich eine einfache Abkürzung Im Animationsbaum-Skript stelle während der Ready-Funktion die Eigenschaft tree root so ein, ich während der Ready-Funktion die Eigenschaft tree root so ein, dass sie ein Duplikat des Mischbaums Wenn Sie true als Argument angeben, werden auch alle Unterressourcen dupliziert , die diese Ressource verwendet. Seit dem Mischbaum, den dieser Animationsbaum als Wurzel verwendet , ist er nicht mehr derselbe, dem er ursprünglich zugewiesen wurde. zuweisen den Aktionsstatus Playback und Nach dieser Vervielfältigung müssen wir die Werte für den Aktionsstatus Playback und den Blend Two-Node Jedes Mal, wenn ein Charakter geladen wird, erstellt er seine eigene Kopie des Mischbaums und kann sein Filterverhalten ändern, ohne andere Charaktere zu beeinflussen Kehren wir zur Action-State-Machine der Charaktere zurück. Unser Charakter hat noch keine ausgerüsteten Gegenstände, also lasst uns sie in ein unbewaffnetes Idol Vorerst machen wir für diesen Übergang die Bedingung, ob sie einen Feind ins Visier nehmen oder ob sie mit einem kurzen Crossfade angreifen wollen . Sie können dann zurückwechseln, wenn sie keinen Feind ins Visier nehmen und auch nicht angreifen wollen Dann, um die Dinge zu organisieren. Füge außerdem eine weitere Zustandsmaschine namens Unarmed Attacks hinzu und gehe in die Zustandsmaschine über, und gehe in die Zustandsmaschine falls der Charakter angreifen möchte Angriffsanimation können sie dann wieder zum Am Ende der Angriffsanimation können sie dann wieder zum unbewaffneten Idol Bearbeitung der unbewaffneten Zustandsmaschine . Beginnen wir mit dem Schlag A für unbewaffnete männliche Angriffe. Dieser wird am Ende der Animation entweder zum Endschlag oder zum unbewaffneten männlichen Angriff B übergehen Endschlag oder zum unbewaffneten männlichen Angriff B , je nachdem ob der Charakter erneut angreifen möchte oder nicht Wir können dieses Muster wiederholen und am Ende der Animation entweder zum Ende oder zum unbewaffneten männlichen Angriffskick übergehen , je nachdem, ob der Charakter erneut angreifen möchte oder nicht möchte Und wir können eine endlose zyklische Kombination erstellen indem wir zum ersten Schlag zurückkehren , solange der Spieler die Angriffstaste gedrückt hält Wenn sie aufhören, die Angriffstaste zu drücken, die Zustandsmaschine in den Endmodus über, wiederum in den unbewaffneten Leerlauf zurückkehrt Möglicherweise möchten wir auch einschränken, wie sich der Spieler beim Angriff bewegt Zum Beispiel würde es keinen Sinn machen, sich der Charakter während der Kick-Animation überhaupt bewegt, da seine Füße beschäftigt sein sollten. Ich werde die Anzeige der Animationsspur vergrößern , damit sie der Länge dieser Animationen besser entspricht. Fügen wir dem Zeichenskript eine öffentliche Funktion hinzu, um Bewegungen einzuschränken. Dabei wird ein boolescher Parameter akzeptiert, der angibt ob sich die Figur bewegen kann oder nicht Dann setzen wir den Wert der Bewegungsvariablen auf das Gegenteil In der Kick-Animation des Charakters. Wir können eine Aufrufmethodenspur hinzufügen , die eine Methode auf dem Wurzelknoten der Figur aufruft. der Animation wird die Funktion „ Bewegung einschränken“ aufgerufen Zu Beginn der Animation wird die Funktion „ Bewegung einschränken“ aufgerufen, wobei „true“ als Argument übergeben wird, wodurch die Bewegung der Figur beim Treten eingeschränkt wird. Und eine weitere Taste am Ende der Animation kann die Bewegungsfähigkeit des Charakters wiederherstellen , indem das Argument auf Falsch gesetzt Aber damit das funktioniert, müssen wir zum Mischbaum zurückkehren und Funktionen zu den Filtern „Zwei Knoten verbinden“ hinzufügen , sodass die Aktionsfunktionen aufgerufen werden, wenn sich der Charakter sowohl bewegt als auch eine Aktion ausführt . Lass es uns ausprobieren. Unsere Animationen scheinen wie zuvor zu funktionieren. Sobald wir dem Charakter sagen, dass er angreifen soll, geht er in den unbewaffneten Ruhezustand bevor er einen Angriff ausführt Wenn wir weiter klicken, greifen sie wiederholt an und durchlaufen dabei die verschiedenen Animationen für unbewaffnete Es ist sogar möglich, sich während des Angriffs zu bewegen oder zu springen, und der Charakter verwendet die entsprechenden Animationen für seinen Ober- und Unterkörper, aber er darf sich beim Treten nicht bewegen oder springen Wenn wir uns auf ein Ziel festlegen, der Charakter in den unbewaffneten Ruhezustand und das Sperren geht zurück zum normalen Unser Charakter führt jetzt unbewaffnete Angriffe durch. In der nächsten Lektion werden wir Animationen für Waffenangriffe hinzufügen. Wir sehen uns in der nächsten Lektion. 6. Waffe: Hallo Freunde. In der vorherigen Lektion haben wir Oberkörperaktionen mit Unterkörperbewegungen kombiniert, sodass unser Charakter unbewaffnete Angriffe ausführen In dieser Lektion werden wir auch eine Vielzahl von Animationen für Waffenangriffe hinzufügen eine Vielzahl von Animationen für Waffenangriffe Fangen wir im Animationsbaum der Charaktere an, wo bereits unbewaffnete Leerlaufangriffe und unbewaffnete Nach diesem Muster fügen wir zwei Händen im Leerlauf In diesem Asset-Paket gibt es keine Animationen im Leerlauf mit einer Hand oder zwei Rädern Aber wir können einfach zwei neue Kopien der inaktiven Animation hinzufügen und sie umbenennen. Von jeder dieser inaktiven Animationen aus können wir dann eine Verbindung zu Angriffszustandsmaschinen herstellen, die genauso funktionieren wie die unbewaffneten Angriffe Von jeder der inaktiven Animationen zu den Angriffen verbinden , wenn der Charakter angreifen möchte, und am Ende der Animation zurückkehren Wir brauchen nur eine Möglichkeit, dem Charakter anhand seiner ausgerüsteten Waffe mitzuteilen, welche Animationen er verwenden soll. In diesem Projekt haben wir ein Skript namens enums, all unsere Aufzählungen enthält, zu dem wir einen weiteren Waffentyp hinzufügen werden Wir beginnen mit unbewaffnet als Standard und listen dann die verschiedenen Waffentypen auf, listen dann für die unterschiedliche Animationen erforderlich sind: einhändige Mala, zweihändige Mala und zweihändige Mala und Doppelräder Es ist wichtig zu wissen, dass der Aufzählung nur um eine nummerierte Liste handelt. Jeder dieser Werte ist also tatsächlich Zahlen Beginnend ist unbewaffnet Null, einhändig ist eins, zweihändig ist zwei und Doppelrad ist drei es sich bei der Aufzählung nur um eine nummerierte Liste handelt. Jeder dieser Werte ist also tatsächlich Zahlen. Beginnend ist unbewaffnet Null, einhändig ist eins, zweihändig ist zwei und Doppelrad ist drei. Im Zeichenskript fügen wir eine weitere Variable namens Angriffsanimation mit einem Typ unserer neuen Aufzählung Wir können diese Variable zu Testzwecken exportieren. Lassen Sie uns die Angriffsanimation des Charakters auf etwas anderes als unbewaffnet ändern auf etwas anderes als unbewaffnet Ich benutze den Zweihand-Nahkampf. Zurück in der Action-State-Machine können wir die Übergangsbedingung so einstellen, dass sie vom Leerlauf zum unbewaffneten Leerlauf wechselt , wenn die Angriffsanimation des Charakters Null ist, was in unserer Aufzählung unbewaffnet ist, und auch mindestens eine der anderen Bedingungen, indem wir sie in Klammern setzen Die Rückgabebedingung ist dann ebenfalls das Gegenteil. Entweder ist die Angriffsanimation nicht Null, oder beide anderen Bedingungen sind erfüllt. den verschiedenen Ruhezuständen Übergänge hinzufügen, können wir ihre Bedingungen so einstellen dieselben sind wie bei unbewaffnetem Leerlauf, nur einen anderen Wert für die Angriffsanimation verwenden Ich gebe jedem von ihnen auch die gleiche Überblendzeit. Dann unter den logisch entgegengesetzten Bedingungen wieder in den Leerlauf übergehen unter den logisch entgegengesetzten Bedingungen wieder in den In jeder der Angriffszustandsmaschinen können wir die Angriffsanimationen genauso verwenden wie bei den unbewaffneten Es gibt vier verschiedene einhändige Angriffe, wodurch ein Zyklus verschiedener Animationen solange der Charakter weiter angreifen möchte Wiederhole den gleichen Vorgang für Angriffe mit zwei Händen, bei denen es nur drei verschiedene Angriffe gibt. Und die Staatsmaschine mit zwei Rädern hat auch nur drei Angriffe Wir können das im Spiel testen, da die Angriffsanimation der Charaktere auf zweihändig eingestellt ist, verwenden sie die zweihändigen Angriffsanimationen Wir können ihnen sagen, dass sie auch einhändige Angriffsanimationen oder Animationen mit zwei Rädern verwenden sollen Jetzt müssen wir nur noch die Variable ändern, wenn wir den Charakter mit Gegenständen ausstatten In den benutzerdefinierten Ressourcen benötigen wir eine spezifischere Klasse, um eine Waffe zu beschreiben, die von der Ausrüstung geerbt wird eine Waffe zu beschreiben, die von der Ausrüstung geerbt ihr den Klassennamen Waffe geben, können wir eine zusätzliche exportierte Variable hinzufügen um den Waffentyp zu speichern, um den Waffentyp zu speichern, und wir können dieselbe Aufzählung wie den Typ verwenden Dann können alle Gegenstandsressourcen im Projekt , bei denen es sich um Waffen handelt, als Waffen umklassifiziert werden, wodurch ihnen ein Wert für ihren Waffentyp zugewiesen wird, sodass der Charakter weiß, welche Animationen er bei der Ausrüstung verwenden muss. Zu Demonstrationszwecken werde ich das X so aktualisieren, dass es eine Einhandwaffe Denken Sie daran, alle Felder, die nicht übernommen wurden, neu auszufüllen , wenn Sie das Ressourcenskript ändern Die Klasse als Zweihandwaffe und der Dolch als zweirädrige Waffe In der Int oder Skript , das ihr benutzt, um Gegenstände auszurüsten, benötigen wir eine Ausnahme, falls es sich bei dem Gegenstand, der ausgerüstet wird , um eine Waffe handelt Und wenn es sich entweder um eine Zweihandwaffe oder um eine Waffe mit zwei Händen handelt, müssen wir alles entfernen, was der Charakter in seinem Nebenhand-Slot ausgerüstet hat C prüft zuerst, ob in der Datei, im Fortschrittsausrüstungsfeld etwas Bestücktes im Nebenhandschlitz ist. Ich verwende das dann, um die Gegenstandstasten im Inventar des Spielers zu indizieren und das E für ausgerüstet von der Taste zu entfernen Setze dann auch den Wert der Ausrüstungsfelder auf negativ eins oder leer Ich werde dem Charakter dann sagen, dass alle Geräte in seiner Steckdose löschen soll. Im Charakterskript muss der Charakter wissen, was er in seinen Händen hält Fügen wir Variablen vom Typ Knoten drei D hinzu, um ihre Haupt- und Nebenausrüstung zu halten . unser Charakter eine Waffe trägt, kann dann auch etwas zusätzliche Logik hinzugefügt werden, falls es sich bei dem Gegenstand um eine Waffe handelt Der Haupthandgegenstand des Charakters kann dann dieser Waffe zugewiesen werden, und die Angriffsanimationen für die Charaktere können so eingestellt werden, dass sie denen der Waffe entsprechen, mit der sie ausgerüstet werden Wenn es sich bei dem Gegenstand um eine Waffe vom Typ Doppelrad handelt, füge ich auch eine weitere Kopie der Waffe in die Steckdose des Charakters ein. Und weise es der Variablen „ off hand“ zu. Wenn ein Ausrüstungsgegenstand ausgewechselt wird und diese Ausrüstung aus der Haupthand des Charakters entfernt wird , können wir die Variable Haupthand auf Null setzen und auch überprüfen, ob der Charakter gerade eine Doppelhand Null setzen und auch überprüfen, ob der Charakter gerade eine Doppelhand Bei doppeltem Tragen sage ich dem Charakter, dass er den Gegenstand auch in der Nebenhand ausführen soll Und dann setze ich die Angriffsanimation auf unbewaffnet. Ebenso sollten wir, wenn es sich bei dem Socket, der abgezogen wird, um die Off-Hand-Variable handelt, auf Null setzen Wir müssen die Angriffsanimation nicht mehr exportieren, da sie jetzt von der ausgerüsteten Waffe festgelegt wird Jetzt fängt der Charakter an, unbewaffnete Angriffe auszuführen. Wenn er jedoch mit einer Einhandwaffe ausgestattet , wechselt er zu einhändigen Angriffen Wir können sie mit einem Schild ausstatten dann zu einer Zweihandwaffe wechseln, und der Schild wird automatisch entfernt. Der Charakter verwendet jetzt Animationen für zweihändige Angriffe. Wechsel zu den Dolchen mit zwei Rädern hat der Charakter einen Dolch in beiden Händen und verwendet die Angriffsanimationen mit zwei Rädern Beim Ausrüsten der Dolche setzt der Charakter wieder unbewaffnete Angriffe Das Letzte, was unsere Angriffe brauchen, sind Hip-Boxen. Kollisionsbereiche, um zu erkennen, ob der Angriff tatsächlich einen Feind trifft und Schaden verursacht. die Waffenszenen öffnen, können wir jeder von ihnen Trefferboxen hinzufügen. Wir verwenden einen D-Node im Bereich drei , der standardmäßig weder überwacht noch überwachbar ist und auch keine Kollisionsebene oder Kollisionsmaske hat, weder überwacht noch überwachbar ist und auch keine Kollisionsebene oder Kollisionsmaske bis er dazu aufgefordert Da diese Charaktermodelle kurze Gliedmaßen und kleine Waffen haben , reichen ihre Angriffe nicht sehr weit Ich werde also sehr großzügig mit ihren Hüftboxen umgehen, sodass sie größer sind als die eigentlichen Waffen. Ich erstelle ein neues Skript für die Waffen und erbe vom Gegenstand. Ich ersetze das Skript, das an den Root-Node der Waffen angehängt ist, und öffne es zur Bearbeitung können wir der Waffe sagen, dass sie sich ihre Trefferbox schnappen soll, oder Mit Addon Ready können wir der Waffe sagen, dass sie sich ihre Trefferbox schnappen soll, oder auf sie verweisen. Fügen Sie dann Funktionen hinzu, um die Kollisionsmaske der Hit-Boxen auf eine neue Ganzzahl zu setzen . Und eine weitere, die die Hit-Box aktiviert oder deaktiviert , indem sie ihre Überwachungseigenschaft festlegt. Der Charakter, der diese Waffe in der Hand hält, kann jetzt angeben, auf welcher Kollisionsebene sich seine Feinde befinden, und Trefferbox aktivieren, wenn er die Waffe schwingt Das Charaktermodell benötigt außerdem eine Hüftbox für unbewaffnete Angriffe Genau wie die Waffen muss es überwachbar sein, weder überwachbar noch überwachbar sein, noch eine Kollisionsebene oder Kollisionsmaske haben und wird eine überdimensionale Kollisionsform haben Aber wir müssen es nicht sofort positionieren und können Verantwortung an die Animationen delegieren Im Charakterskript können wir mithilfe von Addon On Ready einen Verweis auf die unbewaffnete Hüftbox abrufen Addon On Ready einen Verweis auf die unbewaffnete Hüftbox abrufen Denken Sie daran, jedem Zeichen eine Hipbox hinzuzufügen oder die Funktion get node oder null zu verwenden, um Fehler zu vermeiden Lassen Sie uns außerdem eine Physik-Ebene mit drei D exportieren, um die Kollisionsebene der Feinde dieses Charakters aufzunehmen. Dadurch wird dem Inspektor ein Zahlenraster hinzugefügt , genau wie die Eigenschaften der Kollisionsebenen im Bereich drei D-Notizen. Auf diese Weise können wir festlegen, dass dieser Charakter versuchen wird , Dinge auf der gegnerischen Kollisionsebene „Hurt“ zu treffen , von der ich gesagt habe, dass sie Ebene 18 ist. Zwischenzeit können Gegner, die dasselbe Skript verwenden, ihre gegnerische Kollisionsebene als die HRT-Kollisionsebene des Spielers festlegen ihre gegnerische Kollisionsebene als die . Während der Bereitschaftsfunktion können wir die Kollisionsmaske der unbewaffneten Hüftbox als Kollisionsebene des Feindes festlegen der unbewaffneten Hüftbox als Kollisionsebene des Feindes Ebenso können wir jedes Mal, wenn eine Waffe ausgerüstet ist, ihre Kollisionsmaske so einstellen die Kollisionsebene des Feindes ist, sodass er weiß, welche Ebenen maskiert werden müssen , unabhängig davon , wer sie in der Hand hält Wir benötigen dann einige Funktionen im Charakterskript, um die Hüftboxen der Waffen während der Angriffsanimationen zu aktivieren und zu deaktivieren . Dabei akzeptieren wir einen booleschen Parameter , der angibt ob die Hüftbox aktiviert oder deaktiviert wird, und eine Ganzzahl für welche aktiviert oder deaktiviert wird und eine Ganzzahl für Und ich gebe ihr den Standardwert Eins , was die Haupthand bedeutet Mit Hilfe einer Match-Anweisung können wir drei separate Fälle erstellen die Hüftbox für unbewaffnete Angriffe, Angriffe mit Haupthand oder Angriffe außerhalb der Hand aktivieren Haupthand oder Angriffe außerhalb der Hand Wenn wir unbewaffnet sind, können wir die Überwachungseigenschaft der unbewaffneten Hüftbox auf aktiv setzen die Überwachungseigenschaft der unbewaffneten Hüftbox Ob Haupthand oder Nebenhand, dann können wir der Waffe sagen, dass sie ihre Trefferbox aktivieren oder deaktivieren soll ihre Trefferbox aktivieren oder deaktivieren Animationen unserer Charaktere können dann Tracks hinzugefügt werden, um die Trefferfelder zu aktivieren und zu deaktivieren Ich werde es einfach mit einem Angriff jeder Art demonstrieren, angefangen mit einem einhändigen männlichen Angriffskop. dieser Animation eine Spur mit einer Aufrufmethode hinzufügen, würden wir im Allgemeinen erwarten, dass die Trefferbox aktiviert wird, sobald sie anfängt zu schwingen in diesem Moment eine Taste hinzufügen, können wir das boolesche Argument auf true ändern, um die Trefferbox der Haupthandwaffe des Charakters zu aktivieren Wird dann am Ende des Swings deaktiviert , indem das Argument auf Falsch gesetzt Dadurch wird verhindert, dass Gegner in die Waffe hineinlaufen , wenn sie sich nicht bewegt , und sie fügen nur Schaden zu, wenn der Charakter die Waffe tatsächlich mit Gewalt schwingt Der Vorgang ist derselbe, wenn eine Waffe in die Hand genommen wird Wenn ein Titel hinzugefügt wird, ruft die Key-Framing-Funktion auf, die Trefferbox zu Beginn des Waffenschwungs zu aktivieren und am Ende des Schwungs zu deaktivieren Beim Einsatz von zwei Händen müssen wir angeben, welche Hüftbox aktiviert wird, ob es sich um angeben, welche Hüftbox aktiviert wird, die Haupthand oder die Nebenhand handelt, indem wir auch den Integer-Parameter auf zwei ändern, wenn die Hüftbox, die aktiviert oder deaktiviert wird, zur Nebenhand indem wir auch den Integer-Parameter auf zwei ändern, wenn die Hüftbox, die aktiviert oder deaktiviert wird gehört Und wenn wir unbewaffnet sind, müssen wir nicht nur die Hüftbox aktivieren, sondern sie auch so positionieren, dass sie sich an der richtigen Stelle Mithilfe eines Eigenschaften-Tracks können Sie der Eigenschaft Position der Hüftboxen“ einen Keyframe Dann ändern wir das Integer-Argument in den Funktionsaufrufen Null , um anzuzeigen, dass wir die unbewaffnete Hüftbox verwenden möchten Es ist eine gute Idee, sicherzustellen, dass sich die Hüftbox mindestens ein Frame an der richtigen Position befindet , bevor Sie sie aktivieren Es ist hilfreich, orthogonale Ansichten zu verwenden, um die Hüftbox aus mindestens zwei verschiedenen Winkeln exakt auf der Faust der Figur zu positionieren die Hüftbox aus mindestens zwei verschiedenen Winkeln exakt auf der Faust der Figur Klicken Sie dann auf das Schlüsselsymbol, um diese Position in der Animation mit einem Keyframe Wir werden diese Hüftboxen erst in der nächsten Lektion testen können , wenn wir dann auch noch Schmerzboxen hinzufügen, damit sie sie treffen können. Die Hüftbox wird nicht nur mit der Animation aktiviert, sondern folgt dann auch der Faust des Charakters. Denke daran, dass du diesen Vorgang für jede Angriffsanimation abschließen musst. Unser Charakter greift jetzt mit unterschiedlichen Animationen für jeden Waffentyp an. In der nächsten Lektion werden wir zulassen, dass Charaktere verletzt werden und Schaden erleiden. Wir sehen uns in der nächsten Lektion. 7. Hit: Hallo Freunde. In der vorherigen Lektion haben wir unseren Waffen- und Angriffsanimationen Hitboxen hinzugefügt. In dieser Lektion fügen wir unseren Charakteren Hurt-Boxen hinzu , damit sie von Angriffen getroffen werden können. Die Hurt-Box eines Charakters ist nur ein weiterer D-Node im dritten Bereich. Wir werden die Charaktermodelle erweitern. Sie werden nicht überwachen, aber sie werden anhand der Trefferboxen überwacht werden können Sie werden entweder auf der Hurt-Box-Ebene des Spielers oder auf der Herzbox-Ebene des Feindes entsprechend vorhanden Spielers oder auf der Herzbox-Ebene des Feindes entsprechend Aber du musst nichts maskieren da sie sowieso nicht überwachen. Bei der Kollisionsform der Hert-Boxen ist eine weitere Kapsel sehr häufig, aber sie ist normalerweise kleiner als die Kollisionsform des Charakters und vollständig im Charaktermodell enthalten Es wäre für den Spieler nicht fair , von etwas getroffen zu werden, das anscheinend keinen Kontakt aufnimmt Denkt daran, dass bei den Waffen übergroße Hüftboxen verwendet werden , also wäre es auch vernünftig, wenn die Herzboxen zu klein wären, aber ich passe meine an Kopf und Körper des Charakters Ich kopiere dann dieselbe Herzbox und füge sie in die Szenen meiner gegnerischen Charaktere ein. Dabei ändere ich deren Kollisionsebene in die gegnerische HRT-Ebene ändere ich deren Kollisionsebene in die gegnerische HRT-Ebene Dann verwende ich in unseren Waffenszenen die Axt als Beispiel Wir müssen das Signal des eingegebenen Bereichs der Hitbox mit dem Waffenskript verbinden Signal des eingegebenen Bereichs der Hitbox mit dem Waffenskript Wenn diese Waffentrefferbox in die Hurt-Box eines Charakters gelangt, benötigen wir diese Waffe, um diesem Charakter Schaden zuzufügen Lassen Sie uns vorerst eine öffentliche Variable für diesen Waffenschaden hinzufügen eine öffentliche Variable für diesen Waffenschaden Wenn die Kollision passiert, benötigen wir einen Verweis auf den Charakter, zu dem die Hurt-Box gehört. In meinem Projekt wird das immer der übergeordnete Knoten der Hurt-Box sein. Wir können dem Charakter dann sagen, dass er Schaden nehmen soll , und den Waffenschaden als Argument angeben. Es könnte auch nützlich sein, zu wissen, aus welcher Richtung der Schaden kommt. Wir können also den Unterschied zwischen ihren globalen Positionen normalisieren. Um all unsere Waffeninformationen an einem Ort zu speichern, sollte der Schaden als exportierte Variable zur Ressourcendatei hinzugefügt werden, und ich gebe ihr einen Standardwert von zwei Schaden Jede andere Waffenressourcendatei kann dann angeben, wie viel Schaden diese Waffe anrichten wird Denken Sie daran, das Signal „Bereich eingegeben“ auch für jede Waffenszene miteinander zu verbinden Signal „Bereich eingegeben“ auch für jede Waffenszene Ebenso benötigt die unbewaffnete Hüftbox unseres Charakters eine Signalverbindung, um dem Charakter mitzuteilen, dass er unbewaffneten Schaden anrichten soll Elternteil der Hurt-Box erreichen und ihm sagen, dass er einen Schaden erleiden soll, und ihm die normalisierte Richtung vorgeben Dann können wir im Charakterskript, wenn wir die Waffeninstanz erstellen, wenn wir die Waffeninstanz erstellen, ihren Schaden auf dieselbe Zahl wie die Ressource festlegen auf dieselbe Zahl wie die Ressource I. Wenn wir schon mal hier sind, schreiben wir auch die Funktion „ Schaden nehmen “ in der Kampfregion. Akzeptieren Sie die Höhe des zu erleidenden Schadens sowie die Richtung, aus der der Schaden kommt, geben Sie ihm den Standardwert Vektor 30. Um Schaden einstecken zu können, benötigen unsere Charaktere Gesundheit. Ich werde eine Exportkategorie für die Kampfvariablen hinzufügen. Deklariere dann eine für die maximale Gesundheit der Charaktere als Ganzzahl, die ich auf fünf setzen werde. Und ihre aktuelle Gesundheit auch als Ganzzahl, die wir mit add on ready auf ihre maximale Gesundheit setzen können . Lassen Sie uns auch ein paar boolesche Parameter dafür deklarieren , ob der Charakter tot ist oder nicht und ob der erlittene Schaden von hinten verursacht wurde, und mit dem Add-On Ready auch einen Verweis auf die RT-Box des Charakters abrufen mit dem Add-On Ready auch einen Verweis auf die RT-Box des Charakters Wenn der Charakter Schaden erleidet, wird die aktuelle Gesundheit des Charakters um die Höhe des erlittenen Schadens reduziert, aber wir wollen nicht zulassen, dass er unter Null fällt Wir können also die Max-Funktion verwenden, um sie entweder auf diese Berechnung oder auf Null zu setzen , je nachdem, welcher Wert höher ist Der Boolesche Wert von hinten kann dann auf „true“ gesetzt werden , wenn das Punktprodukt der Schadensrichtung mit dem vorwärts gerichteten Basisvektor des Charakters eine negative Zahl ist Wenn die aktuelle Gesundheit des Charakters, nachdem er Schaden erlitten hat, Null ist, stirbt er Andernfalls werden sie getroffen. Die Todesanimation erfolgt zwar automatisch, die Trefferanimation kann aber die Trefferanimation kann durch das Animations-Trees-Skript gesteuert werden, und wir werden dem System mitteilen, ob der erlittene Schaden unter oder über einem bestimmten Schwellenwert lag. Auf diese Weise können wir die Trefferanimation an die Höhe des erlittenen Schadens anpassen. Vielleicht möchten wir auch verfolgen, gesund ein Charakter ist oder wann er stirbt. Es wäre eine gute Idee, diese beiden Ereignisse als Signale zu übertragen. ein Signal für jede Änderung der Gesundheit des Charakters deklarieren , verwenden Argument und ein weiteres Signal Wenn wir ein Signal für jede Änderung der Gesundheit des Charakters deklarieren, können wir einen Prozentsatz der verbleibenden Gesundheit als Argument und ein weiteres Signal für den Tod des Charakters Geben Sie dann das Signal zur Änderung der Lebenspunkte aus, wenn Schaden erleidet, und das Würfelsignal , wenn der Charakter stirbt Um den Prozentsatz ihrer verbleibenden Lebenspunkte zu berechnen, teilen wir einfach ihre aktuelle Gesundheit durch ihre MX-Gesundheit. Da es sich bei diesen beiden Werten jedoch um ganze Zahlen handelt, wird das Ergebnis ebenfalls eine Ganzzahl sein, sodass es immer nur Null oder Eins ergibt wir die Division durchführen, müssen wir mindestens einen von ihnen Bevor wir die Division durchführen, müssen wir mindestens einen von ihnen zuerst schwimmend einsetzen, damit das Ergebnis auch Wenn wir nicht mehr möchten, dass tote Charaktere betroffen sind, können wir auch ihre Kollisionsebene auf Null und ihre Kollisionsmaske auf Eins setzen, sodass sie nur vom Terrain beeinflusst werden, sodass sie nur vom Terrain beeinflusst werden und ihre überwachbare Eigenschaft H rtbach auf False setzen Es ist auch möglich , dass ein Charakter während der Ausführung einer Aktion getroffen oder getötet wird Deshalb sollten wir auch verfolgen , welche Aktionen, die unterbrochen werden , Probleme verursachen können und sie in einer privaten Veranstaltung korrigieren. Zum Beispiel sollten wir wahrscheinlich alle ihre Hip-Boxen ausschalten, wenn ihre Angriffe unterbrochen wurden, was wir auch in einer separaten Funktion tun können, indem wir überprüfen, ob Verweise auf einzelnen existieren, bevor wir sie ausschalten. Im Animationsbaum der Charaktere wollen wir, dass der Charakter, der stirbt oder getroffen wird , alle anderen Animationen unterbricht und überschreibt Da dieser Mischbaum bereits als Ressource gespeichert ist, können wir ihn aus dem Animationsbaum entfernen und ihn durch eine Zustandsmaschine ersetzen Auf der obersten Ebene der Zustandsmaschine werden wir mit den Todesanimationen unserer Charaktere beginnen, da diese die absolut höchste Priorität vor allen anderen Animationen haben werden . Fügen Sie dann eine weitere Zustandsmaschine für die Trefferanimationen hinzu. Wir werden von Hit zu Death A wechseln , wenn der Charakter tot ist. Mit einem kurzen Crossfade. Oder alternativ zu Tod B, wenn sie auch von hinten getroffen wurden indem sie diese Priorität einräumen, indem sie sie auf Null setzen. Es ist vielleicht nicht nötig dass unser Charakter vom Tod zurückkehrt, aber es schadet nicht, den Übergang hinzuzufügen unter der Bedingung , dass er nicht tot ist. In der Hit-State-Maschine machen wir etwas Ähnliches mit den Trefferanimationen und fügen hier unseren Blendbaum als Standardanimation hinzu. Wir aktivieren die Übergänge zu den Trefferanimationen und kehren am Ende der Animationen zum Überblendbaum zurück. Wenn die Trefferanimationen ein- und ausgeblendet werden. Sobald die Statusmaschine für den Animationsbaum aktualisiert wurde, speichern wir sie als Projektressource. Ich nenne es Charakteranimationen. Und zum letzten Mal kann jeder Charakter aktualisiert werden, um die neue Zustandsmaschine zu verwenden. Im Animation Trees-Skript benötigen wir einen Verweis auf die Wiedergabe im Hit-Status. Da wir das Format des Baums aktualisiert haben, müssen wir außerdem all diese Eigenschaftspfade aktualisieren. Wir greifen nun auf den Blend-Knoten zu, indem wir den Tree-Knoten, dann den Blend-Tree-Knoten und schließlich den unteren und oberen Blend-Two-Node abrufen. der Get-Hit-Funktion eine Definition geben, können wir den booleschen Parameter erhalten, der angibt , ob das Zeichen leicht getroffen wird oder nicht Teilen Sie dann dem Trefferstatus mit , dass er weiterreisen soll, um entweder A zu treffen wenn er leicht getroffen wurde, oder B zu treffen, wenn er stärker getroffen wurde Lass es uns ausprobieren. Wenn wir das Skelett schlagen, reagieren sie darauf, leicht getroffen zu werden, rüsten sich eine Axt aus und greifen Sie werden härter getroffen. Ein dritter Treffer und sie sterben und fallen rückwärts, seit sie von vorne getroffen wurden Wir können die große Axt ausrüsten, die ich so eingestellt habe, dass sie einen Schaden von fünf hat, und ein anderes Skelett von hinten töten, und sie fallen nach vorne, wenn sie sterben Es wäre auch schön, die Gesundheit des Spielercharakters auf der Benutzeroberfläche verfolgen zu können . Fügen wir einen Kontrollknoten hinzu und nennen ihn Health Gauge. Ich werde es hinter alles andere auf der Benutzeroberfläche platzieren. Dies erfordert einen direkten Text zum Zeichnen des Rahmens, eine Farbe, die als Füllung aufgerichtet ist, und einen weiteren Direkttext, wenn wir ein Symbol wünschen Ich verwende einen schmalen Slider-Rahmen als Rahmenbild. Es ist sehr groß, also werde ich es auf ein Viertel seiner Größe verkleinern. Und ich verwende Icon, kleines Herz voll für das Icon. Größe und positioniere es , dass es im Verhältnis zum Rand gut aussieht Ich stelle dann die Farbe für die Farbe ect so ein, dass sie der Farbe des Herzens entspricht, und stelle die Position und die Abmessungen so ein, dass sie den Balken füllen. Ich setze die Größeneigenschaft zurück und verankere sie in der unteren linken Ecke. auf die Eigenschaft Größe X der Füllung klicken und sie ziehen, können wir sehen, wie der Messwert einfach auf einen beliebigen Prozentsatz eingestellt werden kann einfach auf einen beliebigen Prozentsatz eingestellt werden ein Skript an die Integritätsanzeige anhängen, können wir es einfach Gauge nennen, um es für alle anderen Messgeräte wiederzuverwenden holen wir uns einen Verweis Mithilfe von add on ready holen wir uns einen Verweis auf die Füllfarbe und deklarieren außerdem eine Variable, und deklarieren außerdem eine Variable die den Größenpunkt X der Füllung enthält, wenn das Messgerät vollständig gefüllt ist. Auf diesen Wert wurde die Eigenschaft size dot x gesetzt, die Eigenschaft size dot x wenn sie zum ersten Mal geladen wird Schreiben Sie dann eine öffentliche Funktion namens set value, einen prozentualen Float-Parameter akzeptiert. Alles, was wir tun müssen, ist die Eigenschaft Größe x der Farbe t auf den Prozentsatz multipliziert mit der maximalen Größe Wenn das Signal zur Änderung der Gesundheit des Spielercharakters mit der Funktion zur Einstellung des Werts der Anzeige verbunden wird, wird nun automatisch die Gesundheit des Spielers aufgezeichnet Um die Gesundheitsanzeige zu testen. Ich sage dem Charakter einfach, dass er jedes Mal, wenn der Spieler die Run-Taste drückt, zwei Schaden erleiden soll. Jetzt können wir sehen, dass die Gesundheitsanzeige des Charakters leer ist und der Charakter stirbt, wenn er leer ist Ich setze dann die Linie „Take Damage“ wieder auf „Laufen“ zurück. Unser Charakter wird jetzt getroffen und erleidet Schaden durch Angriffe. Und in der nächsten Lektion werden wir es Charakteren ermöglichen, zu vermeiden, dass sie getroffen werden, indem sie ausweichen Wir sehen uns in der nächsten Lektion. 8. Dodge: Hallo, Freunde. In der vorherigen Lektion haben wir unseren Charakteren erlaubt, von Angriffen getroffen zu werden, Schaden zu nehmen und zu sterben. In dieser Lektion helfen wir ihnen, Schaden durch Ausweichen zu vermeiden. Beginnen wir in den Projekteinstellungen, der Registerkarte Eingabe-Map, fügen ein Eingabeereignis zum Ausweichen hinzu Ich verwende die Leertaste oder die rechte Taste auf meinem Controller Im Spielerskript können wir dieselben Methoden wie Jump und Attack verwenden dieselben Methoden wie Jump und , um die Ausweicheingaben zu puffern. Im Charakterskript benötigen wir eine Variable dafür, ob der Charakter ausweichen will oder nicht. Aber ein Ausweichen ist nicht nur eine einfache Eingabe. Es erfordert auch eine Richtung als Vektor drei. In der Kampfregion benötigen wir eine Ausweichfunktion und eine Abbruchfunktion, wobei die boolesche Variable entsprechend gesetzt Und wenn alle Eingaben gepuffert sind, werden alle anderen gepufferten Eingaben auf False Da wir die Eingaberichtung bereits im Zeichenskript speichern , können wir überprüfen, ob das in dem Moment, in dem dem Charakter gesagt wurde, dass er ausweichen soll, der Vektor 30 ist Moment, in dem dem Charakter gesagt wurde, dass er ausweichen soll, der Vektor 30 Wenn ich keine Eingabe mache, möchte ich, dass der Charakter rückwärts ausweicht Ich verwende den Vorwärtsvektor des Charakters, indem ich ihn mit einer negativen Zahl multipliziere, um ihn Wenn wir Richtungseingaben geben, möchte ich, dass der Charakter in dieser Richtung ausweicht, aber immer mit voller Ich normalisiere die Richtung, um die Größe aus der Gleichung zu entfernen. In der Animation der Charaktere: Baumzustandsmaschine, Navigation durch die Tod- und Trefferanimationen in den Überblendbaum und schließlich die Bewegungszustandsmaschine Wir können die Ausweichanimationen in einem zweidimensionalen Mischraum hinzufügen in einem zweidimensionalen Mischraum Übergang von Fortbewegung zu Ausweichbewegung , wenn der Charakter ausweichen möchte, und zurück zur Fortbewegung am Ende der Animation Beide sind mit einem Kreuz überblendet. Da es sich um eine Verbindung zur Fortbewegung handelt, wird das Ausweichen nur ausgeführt während sich der Charakter auf dem Boden befindet Möglicherweise möchten Sie auch, dass die Luftausweichmanöver an den Jump-Ruhezustand angeschlossen sind Im Bereich „Ausweichmanöver ändere ich das Rasterausrasten auf den Faktor eins Füge dann die Animationen „Vorwärts ausweichen“, „Rückwärts ausweichen“, „Links ausweichen“ und „Ausweichen nach rechts“ hinzu, die miteinander vermischt werden , sodass der Charakter in jede Richtung ausweichen kann Das Animationsbaum-Skript muss in der Lage sein, den Überblendungsgrad dieses Verschmelzungsraums als Vektor zwei festzulegen, genauso wie wir den Mischungsgrad der gesperrten Zurück im Zeichenskript können wir, wenn wir dem Charakter sagen, dass er ausweichen soll wenn wir dem Charakter sagen, dass er ausweichen soll, die Animation anweisen , diesen Mischwert festzulegen der Ausweichrichtung handelt es sich jedoch einen Vektor drei im globalen Raum, wohingegen der Mischwert für das Ausweichen ein Vektor zwei im lokalen Raum der Charakteranlage ist ein Vektor zwei im lokalen Raum der Charakteranlage Wir können den Mischungsgrad berechnen, indem wir die Ausweichrichtung anhand eines Punktprodukts mit den Vektoren der Rig-Spaces vergleichen die Ausweichrichtung anhand eines Punktprodukts mit den Vektoren der Rig-Spaces Ich muss den Wert der X-Mischung umkehren und ihn mit minus eins multiplizieren Wenn wir das ausprobieren, wird die Ausweichanimation dreimal abgespielt und der Charakter bewegt sich nicht wirklich Die Animation wiederholt sich , weil man ausweichen will . Das gilt für eine volle Sekunde, aber die Animation ist nur 0,4 Sekunden lang Sie wird also so oft wie möglich wiederholt , bis die Variable Wants to Dodge wieder auf False gesetzt wird, bevor die erste Sekunde abgelaufen ist setzen Sobald das Ausweichen erfolgreich durchgeführt wurde, müssen wir die Variable auf False und außerdem eine gewisse Geschwindigkeit anwenden , um den Charakter zu bewegen. Beim Hinzufügen einer weiteren Funktion, ähnlich wie beim Anwenden der Sprunggeschwindigkeit, wenden wir die Ausweichgeschwindigkeit an und rufen diese Funktion aus der Animation auf. Wenn diese Funktion aufgerufen wird, ist der Charakter erfolgreich ausgewichen. Wir können die Variable auf „Falsch“ setzen, um zu verhindern, dass mehr Ausweichmanöver mit einer einzigen Eingabe erfolgen Dann stellen wir die Geschwindigkeit des Charakters so ein, dass sie der Ausweichrichtung multipliziert mit der Ausweichkraft Dadurch wird ein plötzlicher Geschwindigkeitsimpuls erzeugt, der den Charakter schnell in die Richtung bewegt, der den Charakter schnell in die Richtung bewegt in der er ausweicht wird eine weitere exportierte Variable für die Ausweichkraft des Charakters erstellt für die Ausweichkraft des Charakters Ich setze es auf acht. Ich möchte vielleicht auch, dass unser Dodge Augenrahmen hat, kurz für Unbesiegbarkeitsrahmen Das ist eine Zeitspanne, in der der Charakter nicht durch Angriffe verletzt werden kann So wie wir eine Funktion haben, die von unseren Angriffsanimationen aufgerufen wird , um die Hip-Box ein- oder auszuschalten, werden wir auch eine Funktion haben, die von den Ausweichanimationen aufgerufen wird, um die Hurt-Box ein- und auszuschalten Wir sollten set deferred verwenden , um die überwachbare Eigenschaft der Hurt-Box auf den Wert active zu setzen , falls dies während eines Kollisionsereignisses passiert Da es möglich ist, dass wir diese Funktion aufgrund einer Kollision aufrufen möchten und wir Collider nicht ein- oder ausschalten können , während sie In den Animationen der Charaktere müssen wir den Ausweichanimationen unserer Charaktere Funktionsaufrufspuren hinzufügen Ausweichanimationen unserer Charaktere Ich schalte zuerst die Hurt-Box des Charakters aus. Wenn der Charakter dann in der Animation so aussieht , als würde er anfangen, sich zu bewegen, wende ich die Ausweichgeschwindigkeit an. Sobald sie etwas Zeit hatten bis die Ausweichgeschwindigkeit den Charakter dem Angriff aus dem Weg geräumt hat, schalte ich die HRT-Box wieder ein indem ich das Argument auf true ändere. Dann wiederhole ich den gleichen Satz von Funktionsaufrufen für jede der Ausweichanimationen. sollte bei diesem Code zwar nicht passieren , so wie es derzeit der Fall ist, aber es könnte sein, dass der Charakter beim Ausweichen unterbrochen wird, was bedeutet, dass die Het-Box möglicherweise nie wieder aktiviert wird Je nachdem, wie das Spiel funktioniert, möchtest du vielleicht die Aktivierung der Box des Charakters in die Interrupt-Aktionen einbeziehen der Box des Charakters in die Interrupt-Aktionen Jetzt, wo die Ausweichgeschwindigkeit angewendet wird, gefällt mir nicht wirklich, wie die Ausweichanimation die Wurzelposition des Charakters bewegt, was zu einigen abrupten Bewegungen führt, sowohl beim Hineinfahren als auch beim Verlassen des Ausweichmanövers einigen abrupten Bewegungen führt, sowohl beim Hineinfahren als auch beim Verlassen des Ausweichmanövers also die Animationen öffne, entferne ich die Hauptschlüsselbilder aus den Ausweichanimationen Das Charakter-Rig bleibt dort verankert, wo sich der Charakter befinden sollte, was durch die Physik des Charakterkörpers bestimmt wird. Und dann wiederhole ich das auch für die anderen Ausweichanimationen. das Spiel ausführen, können wir uns den Remote-Szenenbaum ansehen, die RT-Box des Charakters finden und auf die überwachbare Eigenschaft achten Beim Ausweichen wird die Eigenschaft „Überwachbar“ auf „Falsch“ gesetzt und anschließend wieder auf „Wahr“ zurückgesetzt, und der Charakter animiert das Ausweichen dank der Entfernung der Root-Keyframes flüssiger mit der Geschwindigkeit Da das Ausweichen nun animiert ist und ordnungsgemäß funktioniert, wollen wir nun überlegen, ob wir dem Charakter erlauben wollen, gleichzeitig anzugreifen und auszuweichen Sollte der Charakter außerdem angreifen oder ausweichen dürfen , wenn er getroffen wird? Wenn wir dieses Verhalten nicht zulassen wollen, müssen wir nachverfolgen, wann der Charakter angreift, ausweicht oder getroffen wird Fügen wir unserem Charakter weitere boolesche Variablen hinzu : Script greift an, weicht aus und wird getroffen All diese Daten müssen exportiert werden , damit sie für den Animations-Player-Knoten zugänglich sind Mithilfe von Eigenschaftenspuren können die Trefferanimationen die Variable is hit zu Beginn der Animation auf true setzen. Und am Ende zurück zu „Falsch“. Dann können wir im Animationsbaum beim Übergang von Fortbewegung zu Ausweichmanöver überprüfen, beim Übergang von Fortbewegung zu Ausweichmanöver überprüfen, ob der Charakter ausweichen will und nichts getroffen wird angreift. Bevor wir in einen beliebigen Angriffszustand übergehen, können wir nicht nur überprüfen, ob der Charakter angreifen möchte, sondern auch, ob er nicht getroffen wird und nicht ausweicht Wir können dann den Vorgang der Einstellung der booleschen Variablen in den Jeder setzt die Variable is dodging Anfang auf true und am Ende auf false Auch hier gilt, dass bei jeder Angriffsanimation die Variable is attack zu Beginn der Angriffsanimation auf true gesetzt wird und am Ende fällt Falls Angriffe oder Ausweichmanöver unterbrochen werden, sollten wir diese Variablen ebenfalls wieder auf False setzen Es besteht auch die Möglichkeit, dass der Charakter stirbt, wodurch die Trefferanimation unterbrochen Also setzen wir hier die Variable is hit auf False. Damit die Angriffsvariable is von der Action State Machine gesetzt werden kann, müssen wir auch den Filter dafür und auch die Position der Hit-Box aktivieren . Um zu testen, ob das Ausweichen tatsächlich funktioniert , müssen die Gegner mit dem Angriff beginnen. Falls du die Animationen für feindliche Angriffe noch nicht eingerichtet hast, ganz einfach tun, indem du den Animations-Player des Charakters kopierst Animations-Player des Charakters kopierst und in die gegnerische Szene einfügst. Wir können dem Animationsbaum dann sagen den neuen Animation-Player verwenden soll. Und solange der Feind dieselbe Knochenstruktur wie der Charakter hat , funktionieren die Animationen alle gleich. Andernfalls musst du den Feind so einrichten, dass er über mindestens einen Angriff verfügt, mit dem eine Hüftbox aktiviert werden kann , wodurch die T-Box des Charakters maskiert Um den Feind anzugreifen, füge ich ihm in der Level-Szene einfach einen leeren Knoten Mit einem einfachen Skript, das ihnen sagt, sie sollen angreifen. Ich erstelle einen neuen Ordner für feindliche Skripte und nenne ihn Angriff. Nachdem ich mir einen Verweis auf den Charakter als übergeordnetes Element dieses Knotens geholt habe, sage ich dem Charakter in der Bereitschaftsfunktion, dass er angreifen soll Da die Variable niemals auf False zurückgesetzt wird, ist das alles, was benötigt wird, damit die Feinde endlos Angriffe ausführen können Lass uns versuchen, das Spiel mit sichtbaren Kollisionsformen zu starten Und schauen Sie sich den Remote-Szenenbaum an, in dem wir die Werte all unserer neuen Variablen sehen können. Der Charakter wartet, bis ein Angriff beendet ist, bevor er ausweicht und umgekehrt. Wenn wir das Skelett den Charakter treffen lassen, er Schaden und kann weder angreifen noch ausweichen, bis die Trefferanimation beendet ist. Und mit unserer neuen Ausweichaktion können wir dem Angriff des Skeletts ausweichen Wir lassen unseren Charakter jetzt ausweichen, um Angriffen auszuweichen, und einschränken, wann der Charakter kann In der nächsten Lektion werden wir es Charakteren ermöglichen, eingehende Angriffe mit einem Schild zu blockieren Wir sehen uns in der nächsten Lektion. 9. Block: Hallo Freunde. In der vorherigen Lektion haben wir unseren Charakteren geholfen, Schaden zu vermeiden , indem sie Angriffen ausgewichen In dieser Lektion ermöglichen wir ihnen, Angriffe mit einem Schild abzuwehren Beginnen wir in den Projekteinstellungen, der Registerkarte „Eingabekarte“, und fügen Sie ein Eingabeereignis zum Blockieren hinzu. Ich verwende die rechte Maustaste und die linke Schultertaste auf meinem Controller. Im Player-Skript muss die Blocktaste nicht gepuffert werden, da sie sich eher wie die Run-Taste verhält und das Verhalten des Charakters ändert, Verhalten des Charakters ändert während die Taste gedrückt gehalten wird wird ein Signal an den Charakter gesendet , entweder zu blockieren oder nicht, je nachdem, ob die Taste gedrückt oder losgelassen wird Das Zeichenskript kann diesen Wert dann in einer Variablen speichern. Möchte blockieren. Aber im Gegensatz zu den anderen Variablen besteht keine wirkliche Notwendigkeit, die blockierende Eingabe zu puffern. Fügen Sie dann im Kampfabschnitt eine Funktion hinzu, die diese Variable festlegt. Im Animationsbaum der Charaktere navigiert die Zustandsmaschine zur Action-Zustandsmaschine Wir können die Blockanimation und den Übergang dazu hinzufügen , wenn der Charakter mit einem kurzen Überblendvorgang blockieren möchte mit einem kurzen Überblendvorgang blockieren Gehen Sie dann zurück zu , wenn sie nicht blockieren möchten. wird der Charakter im Aktionszustand überblendet , dieser Animation wird der Charakter im Aktionszustand überblendet. Er veranlasst ihn seinen Schild zu heben Sobald diese Animation abgeschlossen ist, können wir zur Blockieranimation übergehen. Diese sollte auf eine Schleife gesetzt werden, damit der Schild aktiv bleibt, solange der Spieler die Blocktaste gedrückt hält Diese Einstellung kehrt ebenfalls in den Leerlauf wenn der Charakter nicht mehr mit einer kurzen Überblendung blockieren möchte . Vielleicht möchten wir auch in der Lage sein, von einigen unserer anderen Ruhezuständen , wie dem unbewaffneten Zustand und dem einhändigen Leerlauf, zur Blockanimation überzugehen Um die Anzahl der Übergänge möglichst gering zu halten, kombiniere ich zunächst die Zustände inaktiv und einhändig inaktiv, indem die Übergangsbedingungen logisch kombiniere, um den einhändigen Angriffszustand zu erreichen Wenn es sich um eine Angriffsanimation handelt, wollen sie angreifen und werden nicht getroffen und weichen nicht Kehren Sie dann am Ende der Angriffsanimation in den Leerlauf zurück. den einhändigen Ruhezustand lösche, Wenn ich den einhändigen Ruhezustand lösche, ordne ich die anderen Zustände neu an, damit sie etwas übersichtlicher sind Jetzt können Idole, die nicht aktiv sind oder unbewaffnet sind, in den Modus Blocken wechseln, wenn der Charakter blockieren möchte, und direkt wieder in den Modus Unbewaffnet wechseln, wenn die Angriffsanimation des Charakters Null ist und er entweder ein Ziel hat oder angreifen will und er nicht Mit einer Priorität von Null. Jetzt kann entweder im Leerlauf oder im unbewaffneten Leerlauf zum Blockieren übergehen, wenn der Charakter blockieren möchte Die Status Blockieren und Blockieren können den Leerlauf überspringen und direkt in den unbewaffneten Leerlauf mit einer Priorität von Null zurückkehren direkt in den unbewaffneten Leerlauf mit einer Priorität von Null Auf diese Weise muss der Charakter nicht zwei verschiedene Ruhezustände zwischen Blockieren und Angreifen durchlaufen zwei verschiedene Ruhezustände zwischen Blockieren und Angreifen Wenn wir es ausprobieren, kann unser Charakter beim Drücken der Blocktaste zur Blockanimation übergehen und wieder in den Leerlauf übergehen, wenn die Blocktaste losgelassen wird. Es wäre jedoch sinnvoller, den Charakter darauf zu beschränken diese Animation nur zu verwenden wenn er über einen Schild verfügt. Um das zu tun, benötigen wir ein weiteres Ressourcenskript. erbt von der Ausrüstung und gibt ihr den Klassennamen Shield Wenn Sie möchten, dass Ihre Schilde unterschiedliche Variablen haben , können wir sie hier definieren Fügen wir eine Variable für die Menge des Schadens hinzu, der durch das Blocken mit diesem Schild reduziert wird. Der Standardwert ist eins. Zugriff auf die benutzerdefinierte Ressource Barbarian Round Shields. Wir können es in einen Schild umwandeln und den Betrag der Schadensreduzierung ändern, wenn wir wollen Denkt daran, alle Eigenschaften , die aufgrund dieser Klassenänderung zurückgesetzt wurden, erneut aufzufüllen und alle Schilde so zu aktualisieren, dass sie das neue Klassenskript verwenden In der Schildszene müssen wir in der Lage sein, die Variablen aus der Gegenstandsressource im Schild zu speichern Gegenstandsressource im Schild genau wie wir es bei der Waffe getan haben ein neues Skript hinzufügen, wird es nur eine Ganzzahlvariable zur Schadensreduzierung und eine Dummy-Funktion zur Aktivierung der Hüftbox haben , die das boolesche Argument ignoriert und nichts tut In einer Minute wird klar, warum das notwendig ist. Wir können dann das an unseren Shield angehängte Skript durch das neue ersetzen . Im Charakterskript fügen wir der Ausrüstungskategorie eine weitere Variable hinzu , die angibt, ob der Charakter einen Schild trägt oder nicht. Wenn es sich beim Anlegen eines Ausrüstungsgegenstands um einen Schild handelt, legen wir ihn als Ausrüstung fest, geben den Schadensreduktionswert von der Gegenstandsressource an den Schild weiter von der Gegenstandsressource an den Schild und das Set hat Schild ist auf wahr Da die Nebenvariable nun einen Schild statt einer Waffe hält, werden alle Hüftboxen deaktiviert, wenn die Aktionen des Charakters unterbrochen wenn die Aktionen des Charakters unterbrochen werden Und da die Nebenhand nicht Null ist, weisen wir sie an, ihre Hüftbox zu deaktivieren Aber wir haben dem Schild gesagt, dass er diese Bitte ignorieren soll. Wenn dann beim Ausziehen eines Ausrüstungsgegenstands der Sockel die freie Hand ist, können wir davon ausgehen, dass der Charakter keinen Schild mehr in der Hand hält Wenn wir dem Charakter dann sagen, dass er blockieren soll, können wir die Bedingung hinzufügen, dass der Charakter auch mit einem Schild ausgerüstet sein muss Das Inventar-Skript wird auch beim Ausrüsten eines Schildes einige zusätzliche Bedingungen benötigen beim Ausrüsten eines Schildes einige zusätzliche Bedingungen um zu verhindern, dass der Charakter einen Schild ausrüsten kann, wenn seine eigene Hand bereits mit einer Zweihand - oder Handwaffe besetzt ist mit einer Zweihand - oder Handwaffe besetzt Dieser Vorgang hängt davon ab wie euer Inventar und eure Ausrüstungssysteme funktionieren Wenn es sich bei dem ausgewählten Gegenstand um einen Schild handelt und der Charakter etwas Ausgerüstetes in seiner Haupthand hat und der Charakter derzeit entweder die Zweihand - oder die Doppelrad-Animation verwendet , werde ich die Haupthandbuchse ausrüsten und dem Charakter sagen, dass er die Ausrüstung in seiner Haupthand entfernen soll die Ausrüstung in seiner Haupthand Wenn wir es ausprobieren. Der Block-Button wird jetzt ignoriert, wenn der Charakter kein Schild besitzt. Wir können eine Zweihandwaffe ausrüsten und dann den Schild ausrüsten. Die Zweihandwaffe wird automatisch deaktiviert, und dann wird der Schild ausgerüstet Und jetzt kann der Charakter mit dem Schild blockieren. Lassen Sie uns als Nächstes betrachten, wie die blockierende Eingabe mit unseren anderen Aktionen funktioniert. Wenn der Spieler blockiert und sich entscheidet, entweder anzugreifen oder auszuweichen, dann möchte ich, dass diese Aktionen bei der Unterbrechung des Blocks Vorrang haben Aber wenn wir die Variable will blockieren einfach auf False setzen, dann muss der Spieler die Blocktaste loslassen und erneut drücken, um mit dem Blockieren fortzufahren Stattdessen können wir eine andere boolesche Variable deklarieren. Nennen wir es Interrupt-Block. Wenn der Charakter angreifen oder ausweichen möchte, kann diese Variable auf true gesetzt werden Und wenn der Angriff oder das Ausweichen abgeschlossen ist, können wir ihn wieder auf False setzen, damit der Charakter automatisch weiter blockieren kann. Ich werde die Funktion zum Hinzufügen von Ausweichgeschwindigkeit vereinfachen einfach Cancel Dodge aufrufen. Dann können wir im Animationsbaum die Bedingungen für den Übergang aus dem Block oder der Blockierung hinzufügen , sodass auch berücksichtigt werden kann, ob der Block unterbrochen wird. Und lassen Sie die Übergänge nicht zurück zum Blockieren, bis der Block nicht mehr unterbrochen wird. Jetzt hört der Charakter auf zu blockieren während er angreift, und kehrt automatisch zum Blockieren zurück, solange die Blocktaste weiterhin gedrückt gehalten wird. Und das Gleiche funktioniert auch beim Ausweichen. Das Letzte, was wir tun müssen, ist, den Schaden eingehender Angriffe beim Blockieren zu reduzieren den Schaden eingehender Angriffe beim Blockieren Dafür müssen wir wissen, ob der Charakter blockiert. Da das Blockieren nicht auf eine einzelne Animation beschränkt ist und die Animation wiederholt wird, können wir dem Animator nicht einfach sagen , dass er eine boolesche Variable auf true oder false setzen soll Fügen wir die Blockhit-Animation hinzu. Aktiviert den Übergang zu dieser Animation vom Blockieren bis zur Rückkehr am Ende der Animation. Um zu wissen, ob der Charakter blockiert, ziehen wir uns vor, in welchem Zustand sich diese Zustandsmaschine gerade befindet. Befindet er sich entweder im blockierenden oder blockierten Zustand, dann ist der Schild des Charakters aktiv. Die Blockanimation ist auch ziemlich lang. Dazu gehört nicht nur das Anheben des Schildes, sondern auch ein Zyklus von Blockanimationen. Ich denke nicht, dass der Charakter erst dann als blockend betrachtet werden sollte , wenn der Schild vollständig aufgezogen ist, aber ich möchte auch nicht warten, bis die Blockanimation beendet ist. Deshalb werde ich im Animations-Player des Charakters die Länge der Blockanimation reduzieren, damit sie nach dem Anheben des Schildes nach einer Drittelsekunde stoppt. dem Animationsbaum-Skript eine öffentliche Funktion hinzu, wir dem Animationsbaum-Skript eine öffentliche Funktion hinzu, die überprüft, ob der Charakter blockiert, und einen booleschen Wert zurückgibt Speichern des Namens der Aktion wird zunächst der aktuelle Knoten in einer Zeichenkettenvariablen angezeigt Wir können zurückkehren, wenn es sich entweder um eine Blockierung oder einen Block-Treffer handelt. Außerdem benötigen wir eine weitere Funktion um die Blocktrefferanimation abzuspielen, die dem Aktionsstatus mitteilt, die dem Aktionsstatus mitteilt den Blocktrefferstatus zu wechseln. Dann im Charakterskript, ganz oben in der Funktion „Schaden nehmen“. Wir können überprüfen, ob die Animation des Charakters gerade blockiert wird und ob die Richtung, aus der der Schaden kommt, die Vorderseite des Charakters ist. verwenden ein Punktprodukt der Schadensrichtung mit dem vorwärts gerichteten Basisvektor des Charakters Wenn der Wert eine positive Zahl ist, kommt der Schaden von irgendwo vor ihnen. Das würde allerdings einen weiten Winkel abdecken, also eine volle Halbkugel vor dem Charakter. etwas verwenden, das näher an einem Viertel oder einer Hälfte liegt, können wir es auf eine Kegelform beschränken. Unter diesen Bedingungen sollte der Angriff erfolgreich geblockt werden, wodurch der Schaden durch die Schadensreduzierung des Schildes reduziert wird. Verwenden Sie die Max-Funktion, um den Wert auf mindestens Null zu begrenzen. Wir können dann den Animationsbaum anweisen die Blocktrefferanimation abzuspielen, und wenn der Schaden vollständig auf Null reduziert wurde , ich einfach zurück, da der Charakter keinen Schaden erleidet. Lass es uns ausprobieren. Den Schild ausrüsten und den Angriff des Skeletts blockieren Der Schaden wird auf Null reduziert und die Animation des Blocktreffers wird abgespielt Wenn der Charakter von der Seite oder von hinten Schaden erleidet, erleidet er trotzdem Schaden. Unser Charakter ist jetzt in der Lage, Angriffe mit einem Schild von vorne abzuwehren. In der nächsten Lektion geben wir ihnen eine Fernkampfwaffe, mit der Projektile abgefeuert werden können Wir sehen uns in der nächsten Lektion. 10. Aufnahme: Hallo, Freunde. In der vorherigen Lektion haben wir unserem Charakter erlaubt, Angriffe mit einem Schild abzuwehren. In dieser Lektion geben wir ihnen eine passende Waffe, mit der sie Projektile abfeuern können Dieses Asset-Paket enthält keinen Bolzen für die Armbrust, also mache ich in der Armbrust-Szene zunächst einen Ich beginne mit einem starren Körper mit drei D-Knoten und benenne ihn in Bolzen Ich positioniere ihn so , dass die Basis des Bolzens in der Armbrust ruht wobei sein blauer Z-Basisvektor nach vorne zeigt, wo er schießen wird Als Nächstes füge ich einen D-Knoten der Netzinstanz drei als untergeordneten Knoten hinzu und fülle ihn mit dem Zylindernetz Reduzieren Sie den Radius und die Höhe, drehen Sie es so, dass es nach vorne zeigt und positionieren Sie es so, dass es entlang der Z-Achse nach vorne Ich gebe ihm einfach ein Grundmaterial und stelle die Albedo auf eine braune Farbe ein Dann füge einen einfachen Drei-D-Knoten als weiteren untergeordneten Knoten hinzu, sodass er an derselben Position und Drehung platziert wird, und benenne ihn in Amo-Socket um. Setzen Sie dann den Amo-Sockel wieder an die Armbrust ein und behalten Sie dabei diese Position und Den Bolzen wieder an der Amobuchse befestigen, sodass seine Position und Drehung Verhältnis zu seinem Mutterteil jetzt Null sind Der Bolzen kann jetzt zu einer eigenen Szene gemacht werden Ich lege diese in einen neuen Ordner für Projektile und lösche sie dann aus der Armbrustszene Die Armbrust kann jetzt einfach geladen werden indem ein Bolzen als untergeordnetes Element dieses Knotens Der Bolzen benötigt eine Kollisionsform. Ich verwende eine Kapsel mit den gleichen Abmessungen und der gleichen Position wie der Zylinder. den Solver-Bereich zu erweitern, muss der Kontaktmonitor aktiviert und die maximale Anzahl an Kontakten auf einen Wert größer als Null gesetzt Wenn der Bolzen mit dem Gelände kollidieren soll, muss er die erste Kollisionsebene maskieren Und ich möchte, dass sich meine Bolzen langsam bewegen, damit ich sehen kann, was sie tun Ich möchte aber nicht, dass sie aufgrund der Schwerkraft herunterfallen. Also setze ich ihre Schwerkraft-Skala auf Null. ein Skript an den Bolzen anhängen, können wir es Projektil nennen, sodass es für andere Arten von Projektilen in unserem Spiel verwendet werden kann, und es im Ordner mit Objektskripten speichern Sobald ein Bolzen instanziiert ist, wird er in die Armbrust geladen Und zu diesem Zeitpunkt möchten wir vielleicht Informationen vom Charakter oder der Waffe an die Munition weitergeben vom Charakter oder der Waffe an die Munition Lassen Sie uns dafür eine öffentliche Funktion einrichten. Aber vorerst setzen wir die Eigenschaft Freeze einfach auf true, da der starre Körper nichts tun muss, bis die Waffe abgefeuert ist. Um das Projektil abzufeuern, wenden wir eine Impulskraft an die von der Waffe als Vektor drei gesendet In diesem Moment kann der starre Körper damit beginnen, den Bolzen mithilfe von Physik durch die Spielszene zu bewegen seine Eigenschaft „Einfrieren“ auf „Falsch“ zu setzen Wir wollen nicht mehr, dass das Projektil den Transformationseigenschaften seines Elternteils, der Armbrust, folgt den Transformationseigenschaften seines Elternteils, der Armbrust, Es sollte wieder Teil der Spielszene sein, wo es sich bewegen und frei agieren kann Falls es nicht direkt in die Richtung zeigt , in die es abgefeuert wird, können wir dem Bolzen sagen, er soll auf einen Punkt im Raum schauen, seine eigene globale Position abzüglich der Richtung der Impulskraft darstellt Wenden Sie dann die Impulskraft auf den Bolzen an, damit er sich in diese Richtung bewegt. das vom Körper eingegebene Signal vom starren Körper mit dem Skript verbunden wird, wird diese Funktion aufgerufen, wenn der Bolzen mit etwas auf der ersten Kollisionsebene, dem Gelände, in Kontakt kommt. In diesem Fall kann die Schraube genau dort bleiben, wo sie den Kontakt aufgenommen hat, wodurch ihre Eigenschaft „Einfrieren“ wieder auf „true“ gesetzt wird, aber erst verschoben, da dies während einer Kollision passiert Es ist sehr wichtig, dass Sie jedes Mal, wenn Sie eine Funktion in ein Spiel implementieren , das eine große Anzahl von Knoten instanziiert , auch eine Methode zur Bereinigung dieser Knoten implementieren Andernfalls könnten Sie am Ende sehr große Mengen haben, die dazu führen, dass die Bildraten sinken und Ihr Spiel schließlich zum Absturz gebracht wird Eine gängige Praxis bei Projektilen besteht darin, ihnen eine maximale Lebensdauer zu geben Fügen wir unseren Projektilen einen Zeitknoten hinzu und stellen ihn so ein, dass er einmal herunterzählt Ich stelle ihn auf 10 Sekunden ein. Rufen Sie dann mit dem Add-On Ready einen Verweis auf die Uhrzeit oder den Knoten auf. Wir werden den Timer starten, wenn wir das Projektil abfeuern. Wenn es am Ende nichts trifft, wollen wir es trotzdem aufräumen, damit es nicht für immer in die Ferne fliegt Das Time-Up-Signal wird mit dem Projektilskript verbunden. Dadurch wird das Projektil aus der Spielszene befreit Zurück in der Armbrust-Szene benötigen wir ein neues Drehbuch für diese Waffe Wir können ihr einen Namen für Fernkampfwaffe geben und sie in den Ordner mit den Artikelskripten legen Das Skript, das an diese Waffe angehängt ist, durch eine Fernkampfwaffe ersetzen und ihm einen Verweis auf die benutzerdefinierte Ressourcendatei für die Armbrust geben einen Verweis auf die benutzerdefinierte Ressourcendatei für die Wir können die Munition als gepackte Szene exportieren, als Fertighaus, die wir als Blaupause verwenden können, um so viele zu instanziieren, wie Blaupause verwenden können, um so viele zu instanziieren Dann weisen Sie den Bolzen im Inspektor als Munition für die Armbrust zu Wir benötigen einen Verweis auf die Munitionsbuchse, die bei „on ready“ verwendet wird, und einen Verweis auf die Munition, die gerade in die Fernkampfwaffe geladen ist geladen Es könnte auch nett sein, einen Schadensbonus zu haben, den die Waffe zu den von ihr abgefeuerten Schüssen als Ganzzahl addiert von ihr abgefeuerten Schüssen als Ganzzahl addiert Die Menge an Impulskraft, die die Waffe auf ihre Munition ausübt , wenn sie schwimmend abgefeuert wird. Ich verwende eine niedrige Zahl wie Zehn, damit wir leicht sehen können, wie sich die Bolzen durch die Luft bewegen, und die Kollisionsmaske unserer Feinde, damit Informationen vom Charakter über die Waffe an die Munition weitergegeben werden können Waffe an die Munition Beim Ausrüsten der Waffe Charaktere die Hüftbox und die Kollisionsmaske der Waffen fest, sodass wir dieselbe Funktion problemlos wiederverwenden können , um die Maskenvariable festzulegen Und genau wie beim Schild können wir eine Funktion hinzufügen, um die Hüftbox zu aktivieren Dabei ignorieren wir diesen Parameter und kehren einfach zurück Da die Waffe keine eigene Hüftbox hat. Die Waffe muss in der Lage sein, das Projektil mit einer öffentlichen Funktion abzufeuern, und wir lassen den Charakter die Richtung, in die das Projektil fliegen soll, als Parameter angeben Richtung, in die das Projektil fliegen soll , als Parameter Alles, was die Waffe tun muss, ist, diesen Funktionsaufruf an die Amo weiterzuleiten und die Richtung mit der Waffenstärke zu multiplizieren Setzen Sie dann die Referenz der geladenen Amo auf Null, da die Waffe nicht mehr geladen ist, und eine Reload-Funktion, die einen neuen Bolzen instanziiert und ihn der Variablen zuweist Fügen Sie es dann als untergeordnetes Element der Amo-Buchse hinzu und geben Sie ihm die richtige Position und Drehung, die erforderlich sind, um gut in der Armbrust zu sitzen Wir können dann alle Informationen weitergeben die die Munition benötigt, bevor sie abgefeuert wird, wie zum Beispiel den Waffenschaden und die Kollisionsmaske Lassen Sie uns also weitermachen und diese als Parameter zur Onload-Funktion im Projektilskript hinzufügen Parameter zur Onload-Funktion im Projektilskript Unser Charakterskript benötigt eine Variable, um zu wissen, ob die Waffe, die sie in der Hand halten, gerade geladen ist Und zwei neue Funktionen: Nachladen und Schießen. Reload, setzt die Variable einfach auf true und teilt dann der Haupthandwaffe mit, dass sie nachladen soll Vorerst setzt Shoot die Variable einfach auf False und weist dann die Hauptwaffe an, in eine bestimmte Richtung zu schießen, wobei der Basisvektor der Charakter-Rigs vorwärts weitergegeben Wenn die Waffe nicht ausgerüstet ist, weil sie komplett aus dem Szenenbaum entfernt wird, wird auch die Munition entfernt Also setze ich die Variable Weapon is loaded zu diesem Zeitpunkt einfach wieder auf False Aufzählung der Waffentypen benötigen wir zwei weitere Einträge für einhändige Angriffe, die Nummer vier sein werden, und zweihändige Reichweitenangriffe die Nummer fünf. In der benutzerdefinierten Ressource Armbrüste ändere ich das Skript von Ausrüstung auf Waffe Ich ändere den Waffentyp auf Reichweite mit einer Hand, verringere den Schaden und füge das Symbol wieder hinzu Ebenso ändere ich die schwere Armbrust auf Reichweite mit zwei Händen Im Animationsbaum der Charaktere werden wir mehr Aktionen für Fernangriffe benötigen Diese Zustandsmaschine wird schon ziemlich groß und chaotisch, also werde ich die Reichweitenangriffe in eine andere Zustandsmaschine packen in eine andere Zustandsmaschine Übergang in diese Zustandsmaschine, wenn die Charaktere entweder vier oder fünf angreifen , und sie wollen angreifen, ohne getroffen zu werden und auch nicht ausweichen Kehren Sie dann am Ende der Animation in den Leerlauf zurück. Und ich werde beide Übergänge mit ein bisschen Überblendung mischen. Innerhalb der Reichweite zum Angriff auf die Zustandsmaschine können wir Animationen für das Schießen und Nachladen hinzufügen Sowohl für einhändige als auch für zweihändige Fernangriffe. Wir müssen nur einmal das richtige Spiel spielen und dann zur Action-State-Machine zurückkehren. Also werden sie alle am Ende übergehen. Übergängen zu einer Hand muss die Angriffsanimation auf vier eingestellt sein. Und für beide Hände ist f eingestellt . Ob die Schuss - oder Nachladeanimationen abgespielt werden, hängt vom Wert der geladenen Waffe Da die Animationen nun vom Animationsbaum abgespielt werden können , benötigen wir die Animationen, um Funktionen im Zeichenskript aufzurufen Während der Shooting-Animation fügen wir dem Bild einen Methodenaufruf, Track und Scrub hinzu, bevor der Charakter vor dem abgefeuerten Projektil Fügen Sie dann ein Schlüsselbild hinzu, um die Schussfunktion aufzurufen. Ebenso werden wir während der Nachladeanimation versuchen, ein Bild auszuwählen, wenn der Charakter mit dem Nachladen der Waffe fertig ist Und fügen Sie der Spur der Aufrufmethode ein Schlüsselbild hinzu, um die Waffe tatsächlich neu zu laden Wenn wir wollen, dass diese Animationen den Charakter daran hindern, andere Aktionen auszuführen, müssen wir eine boolesche Variable setzen wie wir es bei den Angriffen getan haben Ich werde einfach die Angriffsvariable is wiederverwenden. Und das auch für die zweihändigen Fernkampf-Animationen . Lass es uns ausprobieren. Wir können den Charakter mit der Armbrust ausrüsten und wenn wir einmal die Angriffstaste drücken, wird er die Armbrust mit einem Bolzen laden die Angriffstaste ein zweites Mal drücken, feuern sie die Armbrust nach vorne ab, und der Blitz schießt heraus, bis er auf etwas in der Umgebung trifft, wo er stoppt und sich nach 10 Sekunden selbst zerstört Jetzt brauchen wir die Bolzen, um Feinden Schaden zuzufügen. Zurück in der Bolz-Szene müssen wir dem Bolzen eine Trefferbox hinzufügen. Die Trefferbox benötigt eine Kollisionsform. Ich benutze die Kugel. Ich positioniere sie am anderen Ende des Bolzens und gebe ihr einen kleineren Radius. Genau wie bei unseren anderen Hip-Boxen muss es noch nicht überwacht werden oder eine Kollisionsmaske haben. Wenn wir mit at on ready einen Verweis auf die Hüftbox abrufen, exportieren wir auch eine Variable für den Schaden an den Schrauben Ich verwende den Standardwert Eins. Wenn der Bolzen vom Charakter in die Armbrust geladen wird , wäre das eine gute Gelegenheit Informationen weiterzugeben, wie etwa etwaige Schadensboni und die Kollisionsmaske Der Waffenschadenbonus kann zum Schaden der Bolzen hinzugefügt werden, und die Kollisionsebene der Hüftbox kann auf die gegnerische Kollisionsebene des Charakters gesetzt werden Wenn das Projektil abgeschossen wird, können wir die Hüftbox anweisen, nach gegnerischen Herdenboxen Ausschau Verbindung des eingegebenen Signals im Hüftkastenbereich mit dem Projektilskript Wir können der Hurt-Box mitteilen , dass das Projektil getroffen wurde, um der übergeordneten Figur mitzuteilen, dass sie Schaden erleiden soll Aus der Richtung der Hurt-Boxen wird die globale Position abzüglich der globalen Position des Bolts normalisiert Der Bolzen kann dann aus der Szene entfernt werden. Und wenn der Blitz auf Gelände trifft, sollte er nicht mehr überwachen, um Schaden zu Deshalb setzen wir ihn auf „Falsch verzögert“ Im Charakter-Skript möchte ich absolut sichergehen, dass, wenn der Charakter auf ein Ziel fixiert ist, das Projektil direkt auf dieses Ziel abgefeuert wird Die Schussfunktion teilt sich also in zwei verschiedene Verhaltensweisen auf, je nachdem ob der Charakter auf ein Ziel fixiert ist oder nicht. Sie ruft eine separate Funktion auf, um auf ein Ziel zu schießen das Ziel als Argument zu überholen Die Waffe sollte jedoch nur dann auf das Lockdown-Ziel feuern , wenn der Charakter ihnen zugewandt ist. So können wir überprüfen, ob das Punktprodukt des Charakters auf der Basis des Forward-Basisvektors und der normalisierten Differenz ihrer globalen Positionen eine positive Zahl ist Je näher dies an einer positiven Zahl liegt, desto ähnlicher sind sie sich, desto mehr wendet sich der Charakter ihnen zu Ich würde sagen, etwas größer als 0,75 ist nah genug, um auf das Lockdown-Ziel zu schießen Im Distanzwaffen-Skript dem Schuss auf ein Ziel eine Definition und akzeptiert ein Ziel als Parameter Wir können jetzt die Richtung als die Differenz der Positionen der Schlucken berechnen , normalisiert und mit der Kraft multipliziert Da dabei die Gubal-Position der Waffe und nicht die Gubal-Position des Charakters verwendet wird , die Richtung genauer Und ich füge 1 Meter zur Position des Ziels hinzu, damit ich nicht auf seine Füße Lass es uns ausprobieren. Wenn ich eine Fernkampfwaffe ausrüste und ein Ziel anvisiere, stelle ich mich zunächst einfach zur Seite, und das Projektil schießt immer noch nach vorne, da der Charakter dem Ziel nicht zugewandt Ich gehe auf das Ziel zu und feuere einen zweiten Blitz ab Diesmal schießt er direkt auf das Ziel und Wir haben jetzt Projektile, die mit Fernwaffen abgefeuert werden und Gegner oder die Umgebung treffen In der nächsten Lektion werden wir es Feinden ermöglichen, Spieler zu entdecken und sich zu wehren Wir sehen uns in der nächsten Lektion. 11. Feind: Hallo Freunde. In der vorherigen Lektion haben wir Fernangriffe hinzugefügt, bei denen Projektile abgefeuert In dieser Lektion ermöglichen wir Feinden, den Spielercharakter zu entdecken, zu verfolgen und anzugreifen In der Friedhofsszene haben wir einen einfachen Knoten hinzugefügt, der den Feind anweist, ständig anzugreifen Lasst uns das entfernen und anfangen, eine komplexere Version zu entwickeln , die nur dann angreift, wenn sich der Spielercharakter in Reichweite befindet, um getroffen zu werden In der Szene mit den Skeleton-Minions fügen wir ihr einen untergeordneten Knoten vom Typ Node Three D hinzu, da er auf drei D-Positionen und Rotationen zugreifen muss drei D-Positionen und Rotationen Ich nenne es Aggression. Fügen Sie dann einen D-Node des Bereichs drei hinzu, der die Angriffsreichweite des Feindes darstellt. Ich gebe ihm eine Kollisionsform und verwende eine Kugel. Wenn ich die Größe der Kugel etwas größer anpasse, gebe ich ihr einen Radius von 1 Meter und positioniere sie dann so, dass sie 1 Meter dem Boden und 1 Meter nach vorne liegt. Der Bereich der Angriffsreichweite wird auf Kollisionen überwacht , sodass die Herdenbox des Spielers maskiert Lassen Sie uns ein Skript an diesen Knoten anhängen und es in den Ordner feindlicher Skripte legen Da der Zweck dieses Skripts darin besteht, einen Charakter genau wie den Spielereingabe-Handler-Knoten zu steuern , benötigen wir einen Verweis auf den Charakter von diesem Knoten gesteuert wird. So wie ich meinen Szenenbaum strukturiere, wird dieser Knoten immer das direkte Kind des Charakterknotens sein , sodass ich auf den Charakter zugreifen kann, indem ich get parent aufrufe. die Signale für den eingegebenen Bereich und den verlassenen Bereich mit dem Skript verbinde , benenne ich die Parameter und gebe ihnen der Übersichtlichkeit halber Typen Wenn die Hurt-Box des Spielercharakters die Angriffsreichweite betritt, wollen wir dem Feind sagen, dass er angreifen soll Und wenn die Hert-Box den Angriffsbereich verlässt, können wir dem Feind sagen, dass er nicht angreifen soll Wir können diesen Zweig als eigene Szene speichern und ihn im Ordner mit feindlichen Szenen Dann lösche ihn aus dieser feindlichen Szene. E Zurück in der Friedhofsszene können wir unseren feindlichen Aggressionsknoten an einen oder alle unsere Feinde anhängen Aggressionsknoten an einen oder alle unsere Feinde sie den Spielercharakter automatisch angreifen, wenn er die Angriffsreichweite erreicht Lass es uns ausprobieren. Die Feinde greifen noch nicht an, aber wir greifen an, wenn wir ihre Angriffsreichweite erreichen, und hören auf, wenn wir sie verlassen. Als Nächstes ermöglichen wir den Feinden, den Spielercharakter aus größerer Entfernung zu sehen . die Szene mit den Aggressionsknotenpunkten öffnen, können wir einen weiteren D-Bereich hinzufügen , der die Sicht eines Feindes repräsentiert. Um dieser Szene eine Kollisionsform hinzuzufügen, verwende ich eine weitere Kugel mit einem viel größeren Radius. Ich verwende 5 Meter und positioniere sie so, dass sie vor dem Feind und etwas über dem Boden liegt. In diesem Bereich kann die Kollisionsebene des Spielercharakters überwacht werden . Ich verwende Ebene neun. Fügen Sie dann einen Strahl hinzu, der drei D-Knoten als Sichtlinie bildet, und bewegen Sie diesen ebenfalls vom Boden nach oben. Dieser sucht nach derselben Ebene wie das Sichtfeld, wird derselben Ebene wie das Sichtfeld, aber auch durch das Gelände behindert Da ich die neunte Ebene verwendet habe , bei der es sich um den Körper des Charakters und nicht um das T-Feld handelt, verbinde ich die Eingangs - und Ausgangssignale mit dem Aggressionsskript Wenn ein Körper in das Sichtfeld gerät, speichere ich ihn in einer Variablen, nennen wir ihn Ziel vom Typ Körper drei D. Aber wir müssen auch sicherstellen, dass sie auch eine klare Sichtlinie haben , bevor wir aggressiv werden Also brauchen wir einen Verweis auf die Besetzung. Und wir können in einer booleschen Variablen speichern, ob der Feind den Spieler gesehen hat oder nicht booleschen Variablen speichern, ob der Feind den Spieler gesehen hat Lassen Sie uns jetzt auch einen Verweis auf das feindliche Divisionsfeld Antwort: Wenn wir die Prozessfunktion verwenden, können wir zunächst überprüfen, ob der Zielwert gesetzt wurde. Wenn es Null ist, kann der Feind den Spielercharakter nicht sehen. Wir sollten einfach zurückkehren. Wenn der Feind den Spieler noch nicht gesehen hat, können wir seine Sichtlinie zum Ziel überprüfen. Wir setzen die Zielposition des Raycasts so ein, dass der Differenz ihrer globalen Positionen entspricht, wobei ein Meter über dem Boden hinzugefügt Nachdem Sie den Raycast gezwungen haben, zu aktualisieren, ob er mit etwas kollidiert und dass es sich bei dem Objekt mit dem es kollidiert, um das Ziel handelt, wird die Sichtlinie nicht durch das Gelände Wir können die Variable „ Spieler gesehen“ auf „Wahr“ setzen. Wenn der Wert dieser Variablen wahr ist, ändert sich das Verhalten des Feindes und wir lassen ihn den Spielercharakter verfolgen. Wenn der Spielercharakter das Sichtfeld des Feindes verlässt das Sichtfeld des Feindes der Körper das Ziel ist und der Feind den Spieler noch nicht gesehen hat, müssen wir seine Sichtlinie nicht mehr überprüfen, sodass wir das Ziel auf Null setzen können Dieser Aggressionsknoten ist ein untergeordnetes Element des Charakterknotens , der sich nicht dreht Das Sichtfeld und die Angriffsreichweite ändern sich also nicht mit dem Charakter-Rig. Wir können die Zeichenreferenz verwenden um die Rotation des Rings zu erfassen, auf die Y-Eigenschaft zuzugreifen und sie diesem Knoten durch die Y-Rotation zuzuweisen Es wird also der gleichen Drehung folgen. Vielleicht möchten wir diesem Feind auch sagen, dass er aufhören soll, den Spielercharakter zu verfolgen. In diesem Fall können wir das Ziel auf Null setzen, hat Ziel gesehen auf falsch und diesem Charakter sagen, dass er sich ohne Richtung bewegen soll. Ein guter Zeitpunkt, um diese Funktion aufzurufen , wäre, wenn der Feind stirbt. Also die Ready-Funktion überschreiben. Wir können das Todessignal dieses Charakters mit der Stoppfunktion verbinden Todessignal dieses Charakters mit der Stoppfunktion Wenn der Feind den Spielercharakter zum ersten Mal sieht, können wir auch das Todessignal des Ziels mit der Stoppfunktion verbinden , um zu verhindern, dass der Feind versucht, den Spielercharakter zu töten nachdem er bereits gestorben ist. Ich werde dieselbe Funktion auch verwenden um die Sicht dieses Feindes auszuschalten seine Überwachungseigenschaft auf „Falsch“ zu setzen. Damit sich der Feind auf den Spieler zubewegt, müssen wir zunächst einige Änderungen an unserer Level-Szene vornehmen. Fügen wir der Ebene eine Navigationsregion mit drei D-Knoten hinzu. Anschließend werden alle Knoten , die zur Erstellung unserer Navigationskarte verwendet werden, diesem Knoten untergeordnet , einschließlich Boden und Hindernisse. Wenn das erledigt ist, wählen Sie den Knoten für die Navigationsregion und füllen Sie das Navigationsnetz mit einem neuen Navigationsnetz Klicken Sie dann auf die Schaltfläche „ Navigationsnetz aufklappen“. Das Navigationsnetz bedeckt das Gelände mit Dreiecken , die einen Bereich bilden, in dem die Charaktere laufen können die Navigationsmesh-Ressource erweitern, können wir ihre Eigenschaften sehen Der einzige Bereich, der derzeit Anlass zur Sorge gibt , ist der Agentenbereich. Agenten sind unsere Charaktere, die dieses Navigationsnetz verwenden werden , um sich durch die Szene zu bewegen. einen kurzen Blick auf die Kollisionskapseln unserer Charaktere Ich habe einen kurzen Blick auf die Kollisionskapseln unserer Charaktere geworfen und ihnen eine Höhe von 2,6 Metern und einen Radius von 0,75 Metern gegeben und einen Radius von 0,75 Metern Ich kopiere diese Werte in die Höhe und den Radius des Agenten in der Ressource Navigationsmessung und erstelle dann das Navigationsnetz neu Das Netz lässt jetzt mehr Abstand zu Wänden und Hindernissen. Um die Navigationsregion nutzen zu können, benötigen alle unsere Charaktere einen weiteren Knoten, einen Navigationsagenten mit drei D-Nodes. Vergewissere dich, dass du jedem Charakter einen hinzufügst. Mit Add On Ready einen Verweis auf diesen Knoten abrufen. Wir können dann eine Funktion in das Zeichenskript schreiben , mit der jedes Zeichen angewiesen werden kann, aus irgendeinem Grund zu einer beliebigen Stelle im Navigationsnetz zu navigieren irgendeinem Grund zu einer beliebigen Stelle im Navigationsnetz zu Das ist auch für viele Dinge außerhalb des Kampfes sehr nützlich . eine Zielposition als Vektor Drei annehmen, setzen wir die Zielposition des Navigationsagenten auf dieselbe Position. Der Navigationsagent verwendet automatisch das Navigationsnetz, dem dieselbe Navigationsebene zugewiesen wurde, um einen Pfad zu erstellen, der dem Zielort so nahe wie möglich kommt . Wenn die Agenten die Position des nächsten Pfads ermitteln aufrufen, geben wir den ersten Wegpunkt auf diesem Pfad als Vektor drei zurück geben wir den ersten Wegpunkt . Wir können dann die aktuelle globale Position des Charakters subtrahieren , um einen Vektor zu erhalten, der von unserer aktuellen Position zur ersten Position auf dem Pfad zeigt der von unserer aktuellen Position zur ersten Position auf dem Pfad Wenn wir das mit 101 multiplizieren , um die vertikale Komponente zu entfernen, dann normalisieren wir diesen Vektor Er entspricht nun funktionell einem Eingabevektor, der von unserem Skript zur Bearbeitung von Spielereingaben erzeugt wird , wenn der Spieler den Analogstick kippt oder die WASD-Tasten benutzt Wir können dies also der Variablen für die Eingangsrichtung zuweisen. Und den Rest erledigt der Physikprozess , indem er dem Charakter sagt, dass er diesen Pfad beschreiten soll, wodurch er zu seinem Ziel gelenkt wird. Es wäre eine gute Idee, alles, was einem Charakter passiert , wenn er stirbt, in eine öffentliche Funktion zu verschieben , alles, was einem Charakter passiert , wenn er , falls er durch etwas anderes als Schaden sterben könnte. Wenn ein Charakter stirbt, sollten wir ihm sagen, dass er aufhören soll, sich zu bewegen. Und wenn ihnen gesagt wird, sie sollen sich bewegen oder etwas unternehmen, sollten wir diese Aufforderungen ignorieren falls der Charakter bei seiner Rückkehr tot ist. Zurück im Aggressionsskript müssen wir dem Feind nur sagen, dass er sich seinem Ziel nähern soll, sobald er es gesehen hat. Bevor wir es ausprobieren, wählen wir einen Feind aus. Ich benutze den Skeleton Warrior und wähle seinen Navigationsagenten Three D Node aus. im Bereich D Bug auf den Aktivieren-Schalter, Klicke im Bereich D Bug auf den Aktivieren-Schalter, um im Spiel gerenderten Pfad sehen zu können dem ersten Skelett nähern, Sobald wir uns dem ersten Skelett nähern, bestätigt uns die Sichtlinie sofort, dass sie uns sehen können, und der Navigationsagent findet einen Weg, Navigationsagent findet auf dem der Feind auf uns zugehen Dann greifen Sie uns an. Wenn wir diesen Feind besiegen , wollen wir diesmal die Aufmerksamkeit des Schurken auf Da sie sich hinter dem Grabstein befinden, ist die Sichtlinie nicht bestätigt und der Feind Und wenn wir uns dem Krieger nähern, können wir um das offene Grab herumrennen und sehen, wie der Navigationsagent den Pfad automatisch in Echtzeit aktualisiert, um den kürzesten Weg zurückzulegen, um den Spieler zu erreichen Vielleicht möchten wir auch , dass unsere Feinde Waffen einsetzen können Zurück in der Friedhofsszene fügen wir einem unserer Feinde einen weiteren Basisknoten hinzu und nennen ihn und nennen Wenn ich ein Skript an diesen Knoten anhänge, lege ich es in den Skriptordner des Feindes Wir müssen lediglich einen Verweis auf den übergeordneten Knoten, den Charakter, abrufen und eine Waffe exportieren, mit der wir diesen Charakter ausrüsten können dem Charakter dann in der Bereitschaftsfunktion, Sag dem Charakter dann in der Bereitschaftsfunktion, dass er die Waffe benutzen soll. Ich werde meinem Skelettkrieger sagen , er soll eine große Axt ausrüsten. Kopiere dann diesen Knoten und füge ihn auf einem anderen Feind ein und tausche die Waffe gegen etwas anderes Ich gebe dem Schurken ein paar Messer. In jeder Szene unserer Feinde müssen Knochenansatzknoten hinzugefügt werden. Sie folgen ihrem Platz auf der linken Seite und auf der rechten Seite. Wir können dann das Socket-Array für die Ausrüstung der Charaktere mit diesen Knoten füllen Socket-Array für die Ausrüstung der Charaktere , um sie beim Ausrüsten von Waffen zu verwenden Schließlich wäre es schön, das Spiel nicht neu laden zu müssen , wenn Lassen Sie uns also das Signal für den Tod der Spielercharaktere mit dem Game Manager-Skript verbinden Signal für den Tod der Spielercharaktere mit dem Game Manager-Skript Nachdem es schwarz geworden ist, weise ich den Szenenbaum einfach an, die aktuelle Szene neu zu laden und alles wieder auf den Stand zurückzusetzen, wie es war, als die Szene zum ersten Mal geladen wurde Lass es uns ausprobieren. Der Skelettkrieger ist mit dem großen A ausgestattet und verwendet die Animationen für zweihändige Angriffe. Wenn wir sterben, wird die gesamte Szene neu geladen. Und wenn sie dieses Mal gegen den Schurken antreten, sind sie mit Messern ausgestattet und verwenden Animationen auf zwei Rädern Wir haben jetzt ein komplexes Kampfsystem in unserem Spiel mit einer Vielzahl von Mechaniken, die an die Bedürfnisse Ihres Spiels angepasst werden können an die Bedürfnisse Ihres Spiels angepasst