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