Dialog und Veranstaltungen in Godot! | Thomas Yanuziello | Skillshare
Suchen

Playback-Geschwindigkeit


1.0x


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

Dialog und Veranstaltungen in Godot!

teacher avatar Thomas Yanuziello, Indie Game Developer

Schau dir diesen Kurs und Tausende anderer Kurse an

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

Schau dir diesen Kurs und Tausende anderer Kurse an

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

Einheiten dieses Kurses

    • 1.

      Einführung

      1:40

    • 2.

      Dialogfeld

      11:53

    • 3.

      Monolog

      13:12

    • 4.

      Event-Manager

      10:31

    • 5.

      Interagieren

      11:21

    • 6.

      Auswahl

      12:33

    • 7.

      Flaggen

      12:11

    • 8.

      Kamera

      15:00

    • 9.

      Animation

      11:49

    • 10.

      Richtung

      11:53

    • 11.

      Modularität

      10:56

    • 12.

      Was kommt als Nächstes?

      1:38

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

Von der Community generiert

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

22

Teilnehmer:innen

--

Projekt

Über diesen Kurs

Dieser Kurs ist eine Fortsetzung der Grundlagen der Spielentwicklung in Godot.

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

In diesem Kurs behandeln wir die Erstellung von Dialogfeldern, Ereignissen und Interaktionen und verknüpfen sie dann mit Fortschrittsflags, Kamerasteuerungen und Charakteranimationen.

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

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

Triff deine:n Kursleiter:in

Teacher Profile Image

Thomas Yanuziello

Indie Game Developer

Kursleiter:in
Level: Beginner

Kursbewertung

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

Warum lohnt sich eine Mitgliedschaft bei Skillshare?

Nimm an prämierten Skillshare Original-Kursen teil

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

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

Lerne von überall aus

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

Transkripte

1. Intro: Willkommen zu meinem Kurs über Dialog - und Veranstaltungssysteme in Gado Dieser Kurs ist eine Fortsetzung der Grundlagen der Spieleentwicklung in Gado, kann aber auf jedes Projekt angewendet werden , bei dem es um einen Charakter geht, den der Spieler steuern kann, mit NPCs oder Objekten zu interagieren indem er eine Taste drückt und einen Dialog anzeigt Du kannst gerne unserem Discord-Server beitreten um gemeinsam mit deinen Kollegen an diesem Kurs zu arbeiten In diesem Kurs werden wir uns mit der Erstellung von Dialogfeldern, Ereignissen und Interaktionen befassen Verbinde sie dann mit Fortschrittsmarkierungen, Kamerasteuerungen und Charakteranimationen. Wenn Sie fertig sind, verfügen Sie über ein umfangreiches Dialog - und Event-System für Ihr Spiel, mit dem Sie hochwertige Zwischensequenzen und komplexe, verzweigte Erzählungen erstellen können hochwertige Zwischensequenzen und , die auf die Entscheidungen der Spieler reagieren und es ihnen ermöglichen, im Spiel voranzukommen Außerdem erlernst du nützliche Fähigkeiten um mit der Gada-Game-Engine zu arbeiten und deine Projekte so zu organisieren und zu gestalten, organisieren und zu gestalten dass Sie werden lernen, wie man mit dem GD-Skript programmiert, wobei alles ausführlich erklärt wird Wir werden objektorientierte Entwurfsprinzipien in unseren Skripten, Vererbung, Kapselung und Abstraktion sowie andere Entwurfsmuster der Softwareentwicklung wie Singleton und Composite Pattern anwenden objektorientierte Entwurfsprinzipien in unseren Skripten, Vererbung, Kapselung und Abstraktion sowie andere Entwurfsmuster der Softwareentwicklung , um sie für Projekte jeder Größe zu organisieren, anpassbar und wiederverwendbar zu halten für Projekte jeder Größe zu organisieren, anpassbar und wiederverwendbar Alle Projektdateien sind auch auf Github verfügbar, falls Sie das Projekt nach Abschluss jeder Lektion überprüfen nach Diese Videos wurden mit Gadot Version 4.2 0.2 aufgenommen. Das Projekt beginnt mit Inhalten aus den Remaster-Paketen K Kits Character und Dungeon von K L Auberg und dem Guy-Basispaket Alle können kostenlos auf Dot IO heruntergeladen werden. 2. Dialogfeld: Hallo, Freunde. Bevor wir anfangen, solltest du in deinem Projekt ein Spiel gesehen haben, das einen Charakter enthält, den der Spieler kontrollieren kann , und ein Level, in dem er herumlaufen kann. Du solltest andere Charaktere haben, die als NPCs oder Objekte agieren können, mit denen der Charakter interagieren kann In diesem Kurs werden wir dem Spieler die Möglichkeit geben, durch Drücken einer Taste mit der Umgebung zu interagieren , um entweder einen Dialog mit einem anderen Charakter einzuleiten oder mit einem Objekt zu interagieren diesen Interaktionen gehört, dass der Spieler im Spiel voranschreitet , Entscheidungen trifft und grundlegende Zwischensequenzen mit benutzerdefiniertem Kameraverhalten und Animationen erstellt grundlegende Zwischensequenzen mit benutzerdefiniertem Kameraverhalten und Animationen Du kannst dein eigenes Projekt verwenden, um diesen Kurs zu verfolgen, oder ein Starterprojekt mit dem Titel Godo Dialog Course Main Branch von meinem Github herunterladen ein Starterprojekt mit dem Titel Godo Dialog Course Main Branch von meinem Github Godo Dialog Course Main Ihr Projekt kann zwei D oder drei D und fast jedes Spielgenre sein, bei dem der Spieler mit der Umgebung oder NBCs interagiert Beginnen wir damit, der Spielszene ein Dialogfeld hinzuzufügen. Je nachdem, welche Elemente Sie verwenden, möchten Sie den Stammknoten des Dialogfelds möglicherweise zu einem Panel oder einem Panel-Container machen . Aber diese Elemente sind so umfangreich , dass ich sie verkleinern möchte, was voraussetzt, dass der Panel-Knoten keine untergeordneten Elemente hat, da die Skalierung vererbt würde, und das möchte ich nicht. möchten Sie vielleicht, dass das Dialogfeld Aus künstlerischen Gründen möchten Sie vielleicht, dass das Dialogfeld über dem FAD sichtbar Es hängt wirklich davon ab, wie Sie es verwenden möchten. Ich lasse meins zuerst hinter allem anderen auf der Benutzeroberfläche zeichnen. Mit dem Stammknoten meiner Dialoge, nur ein einfacher Kontrollknoten, der eigentlich nichts darstellt, was auf dem Bildschirm gezeichnet wird Ich verankere den Dialog am unteren Bildschirmrand, sodass er die gesamte Breite abdeckt, und setze den oberen Anker auf zwei Drittel vom oberen Bildschirmrand nach unten Das Dialogfeld wird das untere Drittel des Bildschirms abdecken, was bei meiner Fenstergröße bei etwa 240 Pixeln liegt. Dann füge ich einen untergeordneten Knoten hinzu, ein Bedienfeld, um das eigentliche Feld auf dem Bildschirm zu zeichnen, und setze seine Anker auf Full Wreck, sodass es mit dem übergeordneten Objekt übereinstimmt Ich gebe dem Gruppenknoten für den Dialog ein neues Thema. Wir können dem Thema ein Panel hinzufügen und ihm eine Box-Textur im neuen Stil geben , um es zu zeichnen. Ich verwende Box Orange Rounded als Textur aus meinem Dialogfenster mit Texturrändern von 256 Pixeln auf allen Seiten. Dieses Bild ist mit 1522 Pixeln riesig . Ich werde den Knoten auf die halbe Größe herunterskalieren. Verwenden Sie dann die Rasterausrichtung und stellen Sie Abmessungen so ein, dass sie dem übergeordneten Knoten des Dialogfelds entsprechen Die meisten Dialogfelder enthalten mindestens den Namen der Person, die gerade spricht, und eine vertikal angeordnete Dialogzeile Fügen wir einen vertikalen Box-Container hinzu und fügen darin auch zwei Beschriftungen hinzu. Eine für den Namen des Sprechers und eine weitere für eine Dialogzeile. Für die Dialogzeile empfiehlt es sich jedoch möglicherweise, anstelle einer normalen Bezeichnung eine Rich-Text-Bezeichnung zu verwenden . Rich-Text-Labels ermöglichen die Verwendung von BB-Code, um alle möglichen Formatierungstricks auf Ihren Dialogtext anzuwenden, z. B. fett, kursiv oder sogar Farben und Animationen Sie können den Ton des Sprechers ausdrücken, verwandte Themen mit einzigartigen Farben verknüpfen oder wichtige Stichwörter hervorheben, oder wichtige Stichwörter hervorheben damit sich der Spieler diese besser merken Ich werde die Größe des vertikalen Felds so anpassen, dass es in die Grenzen des Dialogfelds Ich neige dazu, die amerikanische Schreibweise von Dialog zu verwenden, wenn mich auf eine Benutzeroberfläche beziehe, auf der Text angezeigt Ich verwende jedoch die traditionelle Schreibweise von Dialog, wenn mich auf ein Gespräch zwischen Charakteren in einer Szene beziehe . Füllen wir diese mit Platzhaltertext damit wir sehen können, wie sie aussehen Jemand spricht und er sagt etwas Oram Ipsum. Wenn Sie die Option „ Inhalt anpassen“ aktivieren, wird der Rich-Text-Label-Node gezwungen , sich an seinen Inhalt anzupassen, wie es bei einem normalen Label-Node Lassen Sie uns die Standardschriftart und -größe für das Design festlegen dabei die besser lesbare Schrift als Standard mit einer angemessenen, leicht lesbaren Größe verwenden . Ich werde 32 verwenden dem Theme eine Rich-Text-Bezeichnung hinzufügen, können wir die Standardfarbe für die Dialogzeile festlegen und nicht den Namen des Sprechers, da unterschiedliche Knotentypen handelt. Ich werde Schwarz verwenden, um mich besser von der orangefarbenen Box abzuheben . Dann können wir den Label-Node zum Theme hinzufügen und eine andere Schriftart verwenden, um den Namen des Sprechers anzuzeigen. Ich gebe den Namensetiketten auch eine andere Farbe und einen Schatten, damit sie noch besser zur Geltung kommen. Ich werde eine schickere Schrift für das Namensschild des Sprechers verwenden. Bevor du irgendwelche Dialoge für dein Spiel schreibst, solltest du dir eine grobe Schätzung davon wie viel Text in deinem Spiel bequem auf den Bildschirm passt Stellen Sie sicher, dass Ihr Dialogfeld eine angemessene Menge an Text anzeigen kann und dennoch gut lesbar ist eine angemessene Menge an Text und dennoch gut lesbar solche falschen Platzhaltertexte verwenden, können wir uns ein Worst-Case-Szenario ausdenken , wie viel Text wir anzeigen können, und das als feste Grenze verwenden, wenn wir Dialoge für das Spiel wie viel Text wir anzeigen können , und das als feste Grenze verwenden, schreiben Es sollte auch ein Hinweis für den Spieler sein , dass der Dialog beendet ist und das Spiel darauf wartet, dass sein Beitrag fortgesetzt Fügen wir dem Dialogfeld eine Schaltfläche hinzu. Da ich möchte, dass die Textur der Schaltflächen der Skalierung der Box-Textur entspricht, werde ich sie als untergeordnetes Element der Box verwenden und sie unten rechts verankern. eine einzigartige Schaltfläche handelt, Da es sich um eine einzigartige Schaltfläche handelt, verwende ich den Abschnitt „Theme Override“, um ein neues Texturstil-Feld hinzuzufügen, das nur für diese spezielle Schaltfläche gilt, anstatt das entsprechende Feld im Theme festzulegen verwende ich den Abschnitt „Theme Override“, um ein neues Texturstil-Feld hinzuzufügen, das nur für diese spezielle Schaltfläche gilt, anstatt das entsprechende Feld im Theme ein neues Texturstil-Feld hinzuzufügen, das nur für diese spezielle Schaltfläche gilt, anstatt das entsprechende Feld im . Ich verwende das Pfeilsymbol. Sie anhand der Pixelmaße des Definieren Sie anhand der Pixelmaße des Bilds die Größe der Schaltfläche und positionieren Sie sie dort, wo sie gut aussieht. Ich werde mit demselben Pfeilsymbol weitere Stilfelder für die anderen Schaltflächenstatus erstellen . Wenden Sie dann die Farbmodulation für jeden anderen Status an. Ausgeblichenes Grau für Deaktivierte, grüne und gelbe Farben für die anderen. Das Design für Schaltflächen ist weiterhin verfügbar, wenn wir es später verwenden möchten, um dem Dialogfeld thematische Schaltflächen hinzuzufügen, ohne dass sich dies auf diese Schaltfläche auswirkt Vergewissere dich, dass du überprüfst, wie dein Dialogfeld im Kontext des Spiels und nimm alle erforderlichen Anpassungen vor bis du mit dem Aussehen zufrieden bist Sobald du mit deinem Dialogfeld zufrieden bist, können wir es standardmäßig ausblenden, indem in der Szenenstruktur auf das Symbol neben dem Dialogfeld klicken. Als Nächstes fügen wir ein Skript hinzu und speichern es im UI-Skriptordner. Nehmen wir einen Verweis sowohl auf die Lautsprecherbezeichnung als auch auf die Rich-Text-Bezeichnung des Dialogs und weisen sie privaten Variablen zu Unser Skript muss in der Lage sein, jede Dialogzeile anzuzeigen , die von einem beliebigen Sprecher in unserem Spiel gesprochen wird, was bedeutet, dass es eine öffentliche Funktion benötigt zwei Parameter akzeptiert, nämlich wer spricht und was er sagt. Beides als Saiten. Beide können gesetzt werden, indem auf die Texteigenschaft zugegriffen sie dem an die Funktion übergebenen Parameter zugewiesen In älteren Versionen von Godot wird das Rich-Text-Label separate Eigenschaften für Text und BB-Code-Text haben separate Eigenschaften für Text und BB-Code-Text Stellen Sie sicher, dass Sie die BB-Code-Texteigenschaft verwenden wenn Ihr BB-Code funktionieren soll Wir können dies funktionaler gestalten , indem wir den Lautsprecher optional machen und die sichtbare Eigenschaft der Lautsprecherbezeichnung so einstellen, dass sie davon abhängt, ob der Name des Sprechers eine leere Zeichenfolge ist oder nicht. Wenn wir die Reihenfolge der Parameter vertauschen, können wir den Parameter auch optional machen, indem Standardwert einer leeren Zeichenfolge zuweisen Optionale Parameter müssen bei der Definition einer Funktion immer hinter den obligatorischen Parametern aufgeführt werden bei der Definition einer Funktion immer hinter den obligatorischen Parametern aufgeführt Wir sollten auch die sichtbare Eigenschaft der Dialogbox festlegen . Lassen Sie uns das in einer separaten öffentlichen Funktion namens open tun. Und auch eine geschlossene Funktion , um sie auf False zu setzen. Außerdem wird ein Verweis auf die Schaltfläche „ Weiter“ abgerufen. Nachdem der Text angezeigt wurde, sollten wir die Continue-Taste anweisen, den Fokus zu übernehmen, damit sie mit einem Controller aufgerufen werden kann Lassen Sie uns das Signal, das auf die Taste gedrückt wurde, mit dem Skript verbinden und damit das Dialogfeld vorerst schließen. Im Game Manager-Skript können wir uns einen Verweis auf die Dialogbox holen. Wenn das Spiel zum ersten Mal startet, können wir der Dialogbox mitteilen, dass eine Nachricht angezeigt wird. Hallo Welt. Da der Name des Lautsprechers optional ist, wollen wir uns ansehen, wie er ohne ihn funktioniert. Lassen Sie uns dieses Mal einen Lautsprechernamen hinzufügen, Ghost. Der Geist wird sagen: Boo, ich bin ein gruseliges Gespenst, aber es wird ein BB-Code darauf angewendet, damit der Spieler ein besseres Gefühl dafür bekommt wie die Zeile gelesen werden soll. Wenn Ihre Beschriftungen die Grenzen des Bereichs verlassen , werden sie abgeschnitten Wir können dieses Verhalten jedoch in den Eigenschaften des Steuerelements ändern, indem wir den Clip-Inhalt deaktivieren Es gibt viele verschiedene BB-Code-Tags , die eine Vielzahl von Effekten bieten, und Sie können sogar Ihre eigenen erstellen, indem Sie ein benutzerdefiniertes Skript verwenden , das vom Rich-Text-Effekt übernommen Eine vollständige Liste der BB-Code-Tags finden Sie in den Google Docs Wir können jetzt ein Dialogfeld anzeigen , um dem Spieler Informationen zu geben. In der nächsten Lektion fügen wir eine Tippanimation hinzu und zeigen Dialogsequenzen an. Wir sehen uns in der nächsten Lektion. 3. Monolog: Hallo Freunde. In der vorherigen Lektion haben wir der Spielszene eine Dialogbox hinzugefügt. In dieser Lektion animieren wir das Tippen, sodass der Text schrittweise erscheint und das Feld Dialogsequenzen anzeigt Zu Demonstrationszwecken habe ich wieder auf die Verwendung von Guram Ipsum für diese Lektion verwiesen und werde das Dialogfeld nun sichtbar machen Wenn der Rich-Text-Labelknoten für den Dialog ausgewählt ist, erweitern Sie den angezeigten Textbereich Wir können sehen, dass es sich bei der Anzahl der sichtbaren Zeichen um eine leicht zu bearbeitende Eigenschaft handelt eine leicht zu bearbeitende Eigenschaft deren Standardwert negativ ist Ein negativer Wert von sichtbaren Zeichen ist offensichtlich unmöglich und wird verwendet, um unbegrenzt zu bedeuten Wenn wir diese Zahl jedoch anpassen, indem darauf klicken und sie langsam nach rechts ziehen, können wir sehen, wie der Text verschwindet und sich allmählich füllt die Anzahl der sichtbaren Zeichen von Null auf die Länge der Zeichenfolge zunimmt in unserem Dialogskript Wenn wir in unserem Dialogskript den anzuzeigenden Text festlegen, können wir auch die sichtbaren Zeichen auf Null setzen Wir wollen dann die Anzahl der sichtbaren Zeichen im Laufe der Zeit schrittweise erhöhen , bis alle Zeichen sichtbar sind. Da wir nicht wissen, wie viele Zeichen es gibt, können wir eine Wile-Schleife verwenden, um denselben Code immer wieder zu wiederholen, solange die Bedingung erfüllt ist Die Bedingung ist in diesem Fall, solange die Anzahl der sichtbaren Zeichen geringer ist als die Gesamtzahl der Zeichen Überprüfung der Dokumentation für den Rich-Text-Label-Knoten. Wir können sehen, dass es eine Funktion namens get total character count gibt, die praktischerweise die Gesamtzahl der Zeichen ohne BB-Code-Tags zurückgibt . Die Anzahl der sichtbaren Zeichen ist zwar geringer als die Gesamtzahl der Zeichen, wir können ein Zeichen zu den sichtbaren Zeichen hinzufügen. Aber diese Schleife und die gesamte Funktion werden innerhalb eines einzigen Frames ausgeführt. Der gesamte Text wird immer noch sofort angezeigt. Wir müssen der Schleife sagen, dass sie bei jeder Iteration für eine kurze Zeit pausieren soll jeder Iteration für eine kurze Zeit pausieren Wir können den Loop anweisen, auf ein Signal zu warten , das vom Szenenbaum ausgegeben wird, ein Signal, das einmal in jedem Prozess-Frame ausgegeben wird, 60 Mal pro Sekunde mit den Standard-Projekteinstellungen In dieser Schleife werden die Zeichen nun mit einer Geschwindigkeit von 60 Zeichen pro Sekunde angezeigt einer Geschwindigkeit von 60 Zeichen pro und automatisch an die Bildrateneinstellung des Projekts angepasst. Aber was ist, wenn wir die Bildrate des Projekts nicht verwenden wollen? Fügen wir stattdessen der Einstellungsressource eine Variable für die Schreibgeschwindigkeit hinzu und geben ihr einen Standardwert von 90 Zeichen pro Sekunde. In der Szene mit den Einstellungen können wir eine Bezeichnung und einen Schieberegler hinzufügen , damit der Spieler die Tippgeschwindigkeit ändern kann. Und gib ihm einen angemessenen Bereich. Ich setze es auf 30-120 Zeichen pro Sekunde mit einem Schrittwert von zehn Verbinde das Signal mit dem geänderten Wert mit dem Skript. Und ändern Sie die Einstellungsressource so, dass sie dem Wert in der Ready-Funktion entspricht und ihn initialisiert Weitere Informationen zu den Spieleinstellungen finden Sie im Kurs Grundlagen der Spieleentwicklung in dieser Reihe Zurück im Dialogfeld-Skript benötigen wir eine Variable, die festlegt, wie viel Zeit seit Beginn der Eingabe vergangen ist , und sie auf Null setzen, bevor die Tippschleife beginnt. Dann können wir in jeder Schleifeniteration die Zeit hinzufügen, die durch den Zugriff auf die Funktion get process Delta T vergangen ist. Da wir wissen, get process Delta T vergangen ist. wie viele Sekunden seit Beginn der Eingabe vergangen sind und wie viele Zeichen wir pro Sekunde eingeben möchten, müssen wir diese beiden Zahlen nur miteinander multiplizieren , um die Anzahl der sichtbaren Zeichen zu erhalten. Mal sehen, wie es aussieht. Wir können sogar die Tippgeschwindigkeit in den Spieleinstellungen ändern. Aus dem Debug-Protokoll geht hervor, dass wir die Genauigkeit einschränken und einen Float in eine Ganzzahl umwandeln Wir könnten entweder die Schreibgeschwindigkeit in einen Float umwandeln oder diese Warnung ignorieren , da wir wissen, dass der Slider ohnehin so konfiguriert war , dass er nur Ganzzahlen verwendet Also füge ich vor dieser Zeile ein Warnhinweis-Tag zum Ignorieren hinzu. Godo weiß, dass man die Warnung vor der Einschränkung der Genauigkeit ignorieren muss. Grund passiert dies auch im gleichen Grund passiert dies auch im Einstellungsmenü-Skript Jetzt ist die Tippgeschwindigkeit etwas schneller, aber einige Spieler möchten die Tippanimation vielleicht trotzdem überspringen. Lassen Sie uns also das Verhalten der Schaltfläche „Weiter“ ändern. Wenn der Spieler die Weiter-Taste drückt und die Anzahl der sichtbaren Zeichen geringer ist als die Gesamtzahl der Zeichen, können wir die Anzahl der sichtbaren Zeichen sofort der Gesamtzahl der Zeichen gleichsetzen . Dadurch wird der gesamte Text angezeigt und die Wile-Schleife wird unterbrochen, da ihre Bedingung nicht mehr erfüllt ist Wenn die Anzahl der sichtbaren Zeichen nicht geringer ist als die Gesamtzahl der Zeichen, bedeutet dies, dass die Eingabe bereits abgeschlossen In diesem Fall sollten wir das Dialogfeld schließen. Damit dies mit einem Controller funktioniert, muss die Schaltfläche „Weiter“ aktiviert werden , bevor mit der Eingabe begonnen wird. Wenn die Tippanimation gestartet wird und der Spieler die Taste „Weiter“ drückt, wird entweder die Tippanimation übersprungen oder der Dialog geschlossen, nicht beides. Wenn Sie die Tippanimation überspringen, hat der Spieler trotzdem die Möglichkeit , sie zu lesen, bevor er weitermacht Aber was ist, wenn wir wollen, dass ein Charakter mehr als eine Dialogzeile sagt mehr als eine Dialogzeile und das Dialogfenster geöffnet lässt Dafür können wir eine weitere öffentliche Funktion zur Anzeige von Dialogen hinzufügen . Diesmal wird ein Array von Zeichenketten als erstes Argument akzeptiert . Lassen Sie uns damit beginnen, einfach unsere andere Funktion aufzurufen , um die erste Zeile anzuzeigen, indem wir den Index Null für das Array und ihn zusammen mit dem Namen des Sprechers weitergeben , damit er in das Dialogfeld eingegeben Um dann mit der zweiten Zeile fortzufahren , wenn die Continue-Taste gedrückt wird, muss sich das Skript merken, um welche Zeilen es sich handelt und welche Zeile gerade angezeigt wird Da der Gültigkeitsbereich dieses Arrays nur im Kontext dieses Funktionsaufrufs liegt , kann nicht von einer anderen Funktion aus darauf zugegriffen werden. also eine neue Zeilenvariable, ein Array von Zeichenketten, deklarieren, können wir ihren Wert oben in der neuen Funktion und eine weitere Variable zuweisen, mit der wir uns merken welche Zeile gerade als Ganzzahl angezeigt wird Wir können sie auch am Anfang des Funktionsaufrufs auf Null auch am Anfang des Funktionsaufrufs setzen und damit das Array indizieren Wenn dann die Continue-Taste gedrückt wird, können wir ihr eine hinzufügen und dann überprüfen, ob sie immer noch kleiner als die Größe des Arrays ist . Wenn ja, gibt es mehr Dialoge, sodass wir die erste Funktion erneut aufrufen können. ändern dies in die private Variable, die wir oben deklariert und zum Speichern eines Arrays von Zeichenketten verwendet haben, die an die öffentliche mehrzeilige Funktion übergeben wurden . Wenn Sie möchten, dass der Name des Sprechers weiterhin angezeigt wird, müssen Sie ihn ebenfalls in einer Variablen speichern. Und wenn nicht, dann ist der Dialog beendet und wir können das Dialogfenster ausblenden. Aber jetzt funktioniert die Schaltfläche Weiter nicht wie erwartet, wenn wir nur eine einzige Dialogzeile anzeigen. Wir müssen die öffentliche Funktionalität der Anzeige einer Dialogzeile von den Details trennen die öffentliche Funktionalität der Anzeige einer Dialogzeile von , wie dies erreicht wird , indem wir eine private Methode erstellen, die das tut. Die öffentlichen Funktionen, die entweder eine Leitung oder mehrere Leitungen akzeptieren, können nun beide die private Funktion aufrufen um ihre Ziele intern zu erreichen. Die erste Funktion kann die einzelne Zeile als einzigen Inhalt im Array speichern als einzigen Inhalt im Array und die aktuelle Zeile auf Null setzen Jetzt verhält sie sich genau wie die mehrzeilige Funktion Aber egal, ob Sie oder jemand anderes die Dialogskripte für Ihr Spiel schreibt, es gibt jetzt mehrere Optionen eine einzelne Zeile oder mehrere Dialogzeilen anzuzeigen Das Öffnen des Dialogfelds und das Fokussieren müssen für jeden Dialog , der angezeigt wird, nur einmal durchgeführt werden Und mit der Schaltfläche „Weiter“ muss auch nur die Funktion für die nächste Zeile aufgerufen werden Normalerweise organisiere ich Funktionen in meinen Skripten so , dass sie öffentlich oben und privat unten und verwandte Funktionen zusammenhalten. Dies folgt zwei objektorientierten Prinzipien: Abstraktion, bei der die Details, wie Dinge privat ausgeführt werden, innerhalb des Skripts ausgeblendet werden, und Kapselung, bei der nur die Funktionen öffentlich zugänglich gemacht werden, die andere sehen und verwenden sollen Versuchen wir, eine Figur zu simulieren, die mehrere Dialogzeilen spricht Zuerst deklarieren wir eine Variable, die eine Abfolge von Dialogen über ein Array von Zeichenketten enthält, und übergeben diese als erstes Argument an den Funktionsaufruf, das wir durch Öffnen einer eckigen Klammer füllen Aber da die Abfolge mehrerer langer Zeichenketten ziemlich viel Platz beansprucht, bevorzuge ich es, jede von ihnen in einer eigenen Zeile zu haben, und es hilft, Einrückungen zu verwenden, um sie zu organisieren Dann kann die schließende eckige Klammer verwendet werden , um deutlich zu markieren , wo dieses Array endet die Szene ausführen, können wir sehen , dass die erste Zeile angezeigt wird. Wenn Sie auf die Schaltfläche Weiter klicken, wird die nächste Zeile angezeigt . Wenn Sie auf die Schaltfläche Weiter während die Zeile noch tippt, überspringen wir die Tippanimation und zeigen die gesamte Zeile an. Wenn alle vier Zeilen angezeigt wurden, wird durch Klicken auf die Schaltfläche Weiter das Dialogfeld geschlossen. Aber ich möchte nicht jedes Mal eine Variable deklarieren, sie auffüllen und eine Funktion aufrufen müssen jedes Mal eine Variable deklarieren, sie auffüllen und eine Funktion aufrufen Ich würde es vorziehen, alles in einer Codezeile zu machen. Nach einem ähnlichen Format können wir die Variablendeklaration durch den Funktionsaufruf ersetzen Funktionsaufruf Die Klammern fügen eine weitere Einrückungsebene Unser Array wird deklariert und im Funktionsaufruf zusammen mit dem Namen des Sprechers aufgefüllt Funktionsaufruf zusammen mit dem Namen des Sprechers das Array ist jetzt jedoch kein Typ angegeben, aber da Godo Script eine lose typisierte Sprache ist , ist das Wir können die Typanforderungen tatsächlich aus den Funktionsparametern unseres Dialogskripts entfernen aus den Funktionsparametern unseres Dialogskripts Achten Sie jedoch darauf, nur gültige Argumente zu übergeben , da Sie sonst Fehler erhalten. Wir können jetzt längere Dialogsequenzen mit animiertem Tippen und Überspringen anzeigen Dialogsequenzen mit animiertem Tippen und Überspringen In der nächsten Lektion werden wir benutzerdefinierte Event-Skripte erstellen , die komplexe Dialogsequenzen anzeigen können komplexe Dialogsequenzen anzeigen Wir sehen uns in der nächsten Lektion. 4. Veranstaltungsmanager: Hallo, Freunde. In der vorherigen Lektion haben wir das Dialogsystem mit Tippen, Überspringen und mehreren Zeilen verbessert Überspringen und mehreren Zeilen In dieser Lektion erstellen wir einen Eventmanager, der sich um den Dialog in unseren Spielen kümmert und ihn mit anderen Systemen synchronisiert Beginnen wir in der Spielszene, fügen wir einen neuen Basisknoten hinzu und nennen ihn Event Manager. Das Game Manager-Skript kann mithilfe von add on ready zusammen mit dem Player-Node einen Verweis auf diesen Knoten abrufen mithilfe von add on ready zusammen mit dem Player-Node einen Verweis auf diesen . Stellen Sie sich den Szenenbaum wie eine Organisation vor. Wenn verschiedene Filialen etwas voneinander anfordern möchten, müssen sie die Anfrage normalerweise Wenn verschiedene Filialen etwas voneinander anfordern möchten , über einen Manager senden , der über beiden steht. In diesem Fall geht etwas in der Ebene direkt an den Anfang des Spielszenen-Managers, um die Erlaubnis anzufordern , den Event-Manager für die Durchführung eines Events zu verwenden. Wenn irgendetwas in unserer Spielszene ein Ereignis auslösen will, brauchen sie nur den Spielmanager zu bitten, ein Ereignis zu starten das Ereignis als Argument zu übergeben und das Ereignis als Argument zu übergeben. Eventuell möchten wir auch Ereignisse mit einer gemeinsamen Funktion abschließen . Der Spielmanager kann den Spielerknoten deaktivieren, sodass der Spieler den Charakter während eines Events nicht kontrollieren kann . Und wenn das Event vorbei ist, können wir die Kontrolle des Spielers wiederherstellen. Sobald alle Vorbereitungen getroffen sind, teilen Sie der Veranstaltung mit, dass sie startklar sind, und geben die Referenz des Event-Managers weiter. Kann dies flexibler machen, indem dem Funktionsaufruf auch ein optionaler boolescher Parameter mit dem Standardwert true hinzugefügt ein optionaler boolescher Parameter Funktionsaufruf auch ein optionaler boolescher Parameter mit dem Standardwert true Jetzt ist es möglich, einige Ereignisse zu schreiben , ohne dass dem Spieler die Kontrolle entzogen wir im Player-Skript eine öffentliche Variable hinzu, eine öffentliche Variable Spielersteuerung zu aktivieren und zu deaktivieren In den gleichen Zeilen, in denen wir überprüfen, ob das Spiel vor der Verarbeitung von Eingaben unterbrochen wurde, können wir eine Bedingung hinzufügen, indem wir den logischen Operator oder verwenden , der durch zwei Pipes dargestellt wird Wenn das Spiel pausiert oder der Spieler deaktiviert wurde, kehren wir zurück und Wenn sich der Charakter jedoch bewegt während der Spielerknoten deaktiviert ist, läuft er weiter in dieselbe Richtung, bis die Steuerung wieder aktiviert ist. Wir können definieren, wie eine Variable gesetzt wird, sowie automatische Funktionen mit einem Setter hinzufügen Nach einer Variablendeklaration mit einem Doppelpunkt können wir einen Codeblock schreiben, um den Zugriff auf diese Variable besser einzuschränken eine Set-Funktion erstellen einen neuen Wert als Parameter akzeptieren, können wir den neuen Wert unserer Variablen zuweisen Aber wir wollen auch sicherstellen, dass dem Charakter sagen, dass er aufhören soll, sich zu bewegen, wenn der Spielerknoten nicht aktiviert wir dem Charakter sagen, dass er aufhören soll, sich zu bewegen, wenn der Spielerknoten nicht aktiviert ist. Dieses Verhalten wird jedes Mal automatisch , wenn die aktivierte Variable auf False gesetzt wird. Ähnlich wie bei einem Szenenmanager besteht die Aufgabe des Event-Managers darin, die Kommunikation zwischen den verschiedenen Teilen der Szene zu erleichtern . Aber dieses Drehbuch hat nicht die gleichen Aufgaben wie ein Szenenmanager, also erbt es nicht von dieser Klasse Es kann einfach vom Knoten erben. Ich werde es jedoch trotzdem im Ordner des Managers speichern, da es immer noch als Manager betrachtet wird Am Anfang des Skripts benötigen wir Verweise auf alles, was üblicherweise an einem Ereignis beteiligt sein könnte. Der Charakter, die Dialogbox und die FAD, alles sind öffentliche Variablen Möglicherweise möchten Sie dem Event-Manager auch zusätzliche Funktionen hinzufügen, um häufig verwendete Verhaltensweisen zu bündeln , eine Ereigniswarteschlange zu erstellen oder Ereignisse sogar innerhalb anderer Ereignisse zu verschachteln Jetzt muss jedes Skript in unserer Spielszene nur noch auf den Game Manager verweisen um ein Event zu starten, Dialoge zu präsentieren, ein - und auszublenden und sogar den Charakter zu steuern. Lassen Sie uns zur Level-Szene wechseln und ein grundlegendes Szenario einrichten , in dem dem Spieler, wenn er diesen Raum betritt, eine Nachricht angezeigt wird . Dafür benötigen wir einen D-Knoten im Bereich drei mit einer Kollisionsform. Ich mache daraus eine Kiste, die den gesamten Zugang zum Raum abdeckt , sodass der Spieler den Raum nicht betreten kann ohne mit diesem Bereich zu kollidieren Denkt daran, dass diese Art von Ereignissen, die durch Nähe ausgelöst werden, für manche Spieler störend sein können und daher sparsam eingesetzt werden sollten Die meisten Spieler ziehen es vor, an Ereignissen teilzunehmen, bei denen ihnen die Kontrolle freiwillig durch Drücken einer Taste Es muss auf keiner Kollisionsebene existieren und maskiert nur bei Kollisionen mit dem Spieler Es muss nur für den Spieler überwacht werden und darf durch nichts überwacht Wir können ein Skript anhängen und einen neuen Ordner erstellen, in dem alle unsere Event-Skripte wiederhergestellt T nennt es Raum betreten verbindet das vom Körper eingegebene Signal mit dem Skript. Wir können schreiben, was passiert, wenn der Spielercharakter diesen Bereich betritt. Wir können den Spielmanager anhand des Dollarzeichens finden , beginnend mit dem Wurzelknoten. Wir können dem Spielmanager sagen, dass er ein Ereignis starten soll, indem wir uns selbst als Argument als das Ereignis übergeben, das gestartet werden soll. Vielleicht möchtest du das mit ad on ready machen, aber ich würde empfehlen, es zu tun wenn das Event ausgelöst wird. Da nicht jedes Mal, wenn ein Level in dein Spiel geladen wird, alle Ereignisse ausgelöst werden , musst du sie nicht alle auf einmal im Szenenbaum durchsuchen, musst du sie nicht alle auf einmal im Szenenbaum durchsuchen, obwohl es effizienter wäre es nur dann zu tun, wenn sie es benötigen. Da wir die Karossereferenz nicht benötigen, sollten wir ihr einen Unterstrich voranstellen um die Engine zu vermarkten Bevor wir das Event starten, können wir auch noch einmal überprüfen, ob das, was als Argument übergeben wurde, nicht Null ist Und wenn es nicht Null ist, stellen Sie außerdem sicher, dass es eine Methode namens run event hat. die Logik umkehren, können wir überprüfen, ob dies Null ist oder ob es nicht die Run-Event-Methode Wenn eine dieser Bedingungen zutrifft, können wir zurückkehren und die Anfrage ignorieren Ich bevorzuge es, wenn nicht Event hier zu verwenden, was dasselbe bedeutet Lassen Sie uns auch eine Warnmeldung an den Entwickler ausdrucken , in der wir ihm mitteilen, dass er einen Fehler gemacht hat , den er beheben muss. Push-Warnung wird im Protokoll eine gelbe Warnmeldung angezeigt , ohne dass das Spiel unterbrochen wird Das Event-Skript kann diese Run-Event-Funktion nun als eine Reihe von Anweisungen definieren diese Run-Event-Funktion nun als eine Reihe von , die je nach Bedarf über den Event-Manager an eine der anderen Szenenkomponenten weitergeleitet werden, und alles kann mithilfe von Signalen synchronisiert werden mithilfe von Signalen Um unser Szenario zu erstellen, müssen wir nur den Event-Manager aufrufen, um auf das Dialogfeld zuzugreifen und ihm mitzuteilen, dass er eine Meldung anzeigen soll. Dann sag dem Game Manager , dass das Event vorbei ist. vor jeder Funktion eine Gewichtung hinzufügen, können wir ein Signal von ihr zurückgeben, sodass das Event weiß, wann diese Aufgabe abgeschlossen ist. zum Dialogbox-Skript wechseln, haben wir die Funktion „ Zeile anzeigen“ und geben ein Signal zurück, wenn der Dialog beendet ist. Und machen Sie dasselbe auch für die Mehrzeilenfunktion. Am Anfang des Skripts können wir dem Signal eine Definition geben und es ausgeben, wenn wir das Dialogfeld schließen. Das Hauptziel dieser ganzen Infrastruktur besteht darin, Drehbücher zu erstellen, die sich wie ein Drehbuch lesen klare Anweisungen geben, wer sagt , wie sie sich verhalten, wo sie stehen, worauf die Kamera schaut usw. Wenn der Spieler diesen Raum betritt, wird ihm jetzt eine Nachricht angezeigt wurde dem Spieler vorübergehend die Kontrolle entzogen Während die Nachricht angezeigt wird, wurde dem Spieler vorübergehend die Kontrolle entzogen. Beim Drücken der Continue-Taste das Dialogfenster das Signal aus, dass der Dialog abgeschlossen ist Dadurch kann das Event-Skript weiterlaufen, das Event beenden und der Spieler die Kontrolle wieder Wir haben jetzt einen Eventmanager, der die Spielersteuerung deaktiviert, während ein Ereignis stattfindet , das einen Dialog beinhaltet In der nächsten Lektion werden wir eine interaktive Komponente erstellen, mit der der Spieler interagieren kann, um Wir sehen uns in der nächsten Lektion. 5. Interagieren: Hallo Freunde. In der vorherigen Lektion haben wir einen Eventmanager hinzugefügt , der ein Event-Skript ausführen kann. In dieser Lektion fügen wir Interaktionen hinzu , die der Spieler initiieren kann. Eine populärere Methode, Ereignisse auszulösen, ist, wenn der Spieler eine Taste drückt, um mit etwas oder jemandem zu interagieren. Öffnen Sie die Projekteinstellungen und wechseln Sie zur Registerkarte Eingabekarte. Fügen wir eine Interaktionsschaltfläche hinzu. Ich verwende E auf der Tastatur oder Y auf meinem Controller. Dann können wir im Spielerskript überprüfen, ob die Interaktionstaste gedrückt wurde, und wenn ja, dem Charakter sagen, dass er mit dem oder dem, was auch immer sich vor ihm befindet, interagieren soll . Um herauszufinden, wer oder was das wäre, können wir a verwenden. In der Charakterszene fügen wir dem Rig vom Typ drei D einen untergeordneten Knoten Wir möchten, dass der Strahl vor die Figur zeigt, eine angemessene Entfernung um mit etwas interagieren zu können, ich setze ihn auf 2 Meter. Da das Rig das Ding ist, das sich tatsächlich dreht, dreht sich der Raycast als Kind mit Die Kollisionsmaske bestimmt , womit der Strahl kollidieren kann Wir wollen, dass dieser Strahl Wechselwirkungen findet. Wir sollten Interaktionen eine eigene Kollisionsebene geben. Wenn ich die Projekteinstellungen auf der Registerkarte „Allgemein“ unter Ebenennamen drei D-Physik-Ebenen öffne, stelle ich Ebene fünf so ein, dass sie speziell für Interaktionen vorgesehen ist. Der Strahlwurf kollidiert mit Ebene fünf, wird aber auch durch Ebene eins blockiert, sodass der Spieler nicht mit etwas auf der anderen Seite einer Wand interagieren kann sodass der Spieler nicht mit etwas auf der anderen Seite einer Wand interagieren mit etwas auf der anderen Seite einer den Bereich mit der Breite der Kollisionen erweitern, suchen wir nach beiden Bereichen, unseren Interaktionen und körperähnlichem die Höhe des Strahlwurfs positionieren, ist es am logischsten , ihn irgendwo auf Schulterhöhe oder zumindest irgendwo zwischen Brust- und Augenhöhe Wir können dies aber auch als Gelegenheit nutzen, um bestimmte Reichweitenbeschränkungen für unsere Interaktionen einzuführen. Positionieren wir die CSG-Box vor dem Charakter und stellen wir uns vor , dass sich unser interagierbares Objekt oder unser NPC oben auf der Box befindet Wie groß kann die Box sein, bevor die Person oder das Ding, das sich darüber befindet, nicht mehr interagierbar ist Da würde der Strahl mit der Kiste kollidieren und nicht mit dem Ding darüber Ich denke, es ist vernünftig , die Interaktion mit etwas zuzulassen , das 1 Meter höher als der Charakter ist, aber nicht 1,5 Meter Also werde ich es irgendwo dazwischen positionieren. 1,3 Meter scheinen gut zu sein, was der halben Höhe des Colliders des Charakters entspricht Im Zeichenskript können wir mithilfe von add on ready einen Verweis auf den Cast-Knoten abrufen mithilfe von add on ready einen Verweis auf den Cast-Knoten Beachten Sie jedoch, dass für diese Art jeder Charakter den Cast-Knoten haben muss. Indem Sie die Dollarzeichen-Annotation in eine Funktion ändern , erhalten Sie node oder null. Wir können den Knotenpfad als Zeichenkettenargument übergeben, das wir kopieren können, indem wir mit rechten Maustaste auf den Knoten klicken und Pfad kopieren auswählen oder den Knoten anklicken und ihn direkt in die Anführungszeichen ziehen . Jetzt wird diese Variable für jedes Zeichen ohne gecasteten Knoten einfach auf Null gesetzt, anstatt einen Fehler zu generieren. Fügen wir dem Charakterskript eine Funktion namens interact hinzu , die wir vom Spielerskript aus aufgerufen haben als die Interact-Taste gedrückt wurde. Zuerst überprüfen wir, ob der Cast-Knoten existiert, dann können wir überprüfen, ob er mit etwas kollidiert Wir können dann überprüfen, ob das Objekt, mit dem der Ray Cast kollidiert ist, eine Methode namens interact hat, und wenn ja, sie aufrufen Wenn der Strahlwurf nicht existiert, passiert nichts. Wenn der Strahlwurf auf nichts trifft, passiert nichts. Wenn der Strahlwurf auf ein Terrain wie auf eine Wand trifft, es für das Terrain keine Methode namens interact, es passiert also nichts. Trifft der Raycast auf ein Objekt auf Ebene fünf, das über eine Methode namens interact verfügt, ruft er diese Methode löst ein Interaktionsereignis Aber wenn man an all die vielen verschiedenen Dinge in einem Spiel denkt , mit denen der Spieler interagieren könnte, sind ein NPC und eine Tür beide per Knopfdruck interagierbar, haben aber sonst nicht viel gemeinsam Ein NPC möchte vielleicht dieselben Eigenschaften und Verhaltensweisen erben, die ein spielbarer Charakter beim Herumlaufen und dergleichen verwendet ein spielbarer Charakter beim Herumlaufen Eine Tür benötigt allerdings Eigenschaften wie die Tatsache, ob sie verschlossen ist oder nicht , und Verhaltensweisen wie Öffnen Verwendung einer Vererbungsstruktur. Ihr könntet alle Türen zu NPCs machen , die sich einfach nicht bewegen, oder alle Charaktere zu Türen machen , deren Verhalten und Eigenschaften, die ansonsten türähnlich sind, ignoriert werden dass alle NPCs und alle Türen interagierbar Es ist besser, das interaktive Verhalten als abstraktes Elternteil von Türen und NPCs zu verwenden, impliziert aber dennoch, dass sein sollten, was in den meisten Spielen oft nicht der Fall ist Vielleicht möchtest du eine NPC-Klasse haben, die vom Charakter erbt , aber auch von einer anderen Klasse erbt, um zusätzliche Funktionen der Interaktionsfähigkeit zu erhalten . Aber Godot erlaubt keine Mehrfachvererbung. Es wäre besser, wenn das interagierende Verhalten von Türen, NPCs und allem anderen unabhängig von der Art der Sache wäre, und allem anderen unabhängig von der Art der Sache wäre mit der du Wir können stattdessen das zusammengesetzte Muster anwenden , um dies effizienter zu erreichen einen untergeordneten Knoten erstellen, der die Interaktion repräsentiert, können wir dann jedem beliebigen Objekt ein Interaktionsverhalten zuordnen Wenn wir einen untergeordneten Knoten erstellen, der die Interaktion repräsentiert, können wir dann jedem beliebigen Objekt ein Interaktionsverhalten zuordnen. In unserem Level haben wir ein paar verschiedene Charaktere. Wählen wir einen aus und fügen ihm einen untergeordneten Knoten hinzu, um die Interaktionskomponente dieses NPCs als D-Node im Bereich drei darzustellen die Interaktionskomponente dieses NPCs als D-Node im Bereich drei Dieser Bereich wird auf nichts überwacht werden, aber er wird durch den Strahlwurf, den wir zuvor erzeugt haben, überwachbar sein durch den Strahlwurf, den wir Daher wird es eine Kollisionsschicht von fünf haben, sodass es durch den Strahlwurf erkannt werden kann, und seine Maske kann Null sein, da es nach nichts sucht Es wird eine Kollisionsform benötigen. Ich nehme eine Kapsel und sie ist größer als der Charakter. Der Strahl muss nicht genau direkt auf sie zeigen. Was die Höhe der Kapsel angeht, können wir dieselbe Logik wie zuvor in umgekehrter Reihenfolge anwenden. Stellen Sie sich dieses Mal vor, unser Charakter steht auf der Kiste. Wie hoch kann die Kiste sein, bevor unser Charakter nicht mehr mit dem auf dem Boden stehenden NPC interagieren darf mit dem auf dem Boden stehenden NPC Ich setze dieselben Einschränkungen und lasse den Spieler mit etwas interagieren, das sich 1 Meter unter ihm befindet, aber nicht 1,5 Meter Wenn ich weiß, dass der Strahl 1,3 Meter über dem Boden geworfen wird Meter über dem Boden , auf dem der Spielercharakter steht, dann liegt die Kollisionsform der Interaktionen bei diesem t plus 1 Meter. Es erscheint vernünftig, ihn 2,6 Meter hoch zu machen, was zufällig auch die gleiche Höhe wie der Collider des Charakters hat Beachten Sie jedoch, dass selbst ein winziges Objekt wie ein Schlüssel, der auf dem Boden liegt, einen Collider benötigen wird, der so hoch ist, dass er von der Neufassung getroffen wird Wir können ein Skript an diese Interaktion anhängen. Nennen wir es Bilddialog. Und speichern Sie es im Ordner mit den Event-Skripten. Dieses Skript benötigt zwei Funktionen Interact und Run Event. Die Interact-Funktion ist weitgehend dieselbe wie in der vorherigen Lektion und fordert den Spielleiter auf, dieses Skript als Ereignis auszuführen. Bei der Funktion „Event ausführen können wir den Magier sagen lassen, was wir wollen. Und beenden Sie die Veranstaltung, nachdem sie zu Ende gesprochen haben. Lassen Sie uns nun diesen Interaktionsknoten duplizieren und ihn an der Tür anbringen. Dann duplizieren Sie auch das Magier-Dialogskript und nennen Sie es Zellentür. Ersetzen Sie das an diese Interaktion angehängte Skript und bearbeiten Sie es dann so, dass es so aussieht, als ob die Tür verriegelt ist. In nur wenigen einfachen Schritten sind wir in der Lage, jede Art von Interaktion zu erstellen , die der Spieler durch Drücken der Interaktionstaste mit einem beliebigen Objekt oder NPC initiieren kann durch Drücken der Interaktionstaste mit einem beliebigen Objekt oder NPC initiieren mit einem beliebigen Objekt oder NPC Da ich die Größe einer normalen Wand geändert habe , um die Tür zu erstellen, erbt die Kollisionsform ihre Skalierungseigenschaft Aber nachdem sie innerhalb der Tür zentriert wurde, ist sie immer noch gut darin, die Tür zu umschließen. Lass es uns ausprobieren. Das Drücken der Interaktionstaste , wenn wir vor nichts stehen, funktioniert nicht. Aber wenn wir auf den Magier zugehen, können wir die Interaktionstaste drücken, um einen Dialog einzuleiten. Ebenso können wir auch zur Tür gehen und mit ihr interagieren. Wir haben jetzt eine Tür, die der Spieler noch nicht öffnen kann, und im NPC kann der Spieler mit ihm sprechen, indem er eine Taste drückt In der nächsten Lektion werden wir dem Dialogsystem Dialogoptionen und Konversationsbäume hinzufügen Dialogsystem Dialogoptionen und Konversationsbäume hinzufügen Wir sehen uns in der nächsten Lektion. 6. Auswahl: Hallo, Freunde. In der vorherigen Lektion haben wir eine Interaktionskomponente erstellt , die an alles in unserem Spiel angehängt werden kann. In dieser Lektion fügen wir dem Dialogfeldsystem verzweigte Dialogoptionen hinzu Zunächst müssen wir dem Dialogfeld weitere Schaltflächen hinzufügen Dialogfeld weitere Schaltflächen hinzufügen Es liegt an Ihnen, wie und wo Sie Ihre Dialog-Optionsschaltflächen positionieren möchten . Ob sie sich im selben Dialogfeld befinden , in einem separaten Feld, das in der Mitte des Bildschirms schwebt Dialog begleitet wird oder nicht. Für mein Spiel werde ich meine Buttons in der Dialogbox haben . Hinzufügen eines weiteren vertikalen Box-Containers zur Dialogbox. Nennen wir es Optionen, und es wird drei Schaltflächen mit den Namen Option Null, Option eins und Option zwei enthalten . Ich gebe jedem von ihnen einen Standardtext und stelle ihren Text so ein, dass er nach links ausgerichtet wird. Wenn ich den Namen des Sprechers verberge und den Dialog auf maximal zwei Zeilen beschränke, sollte alles in die Box passen. Ich verankere es einfach unten rechts in der Dialogbox und verschiebe es an eine Position, an der es gut aussieht. Wenn Sie beim Klicken und Ziehen die Alt- oder Optionstaste gedrückt halten, werden nur der ausgewählte Knoten und seine untergeordneten Knoten verschoben Knoten das Dialogfenster bearbeiten, können wir vier Schaltflächen hinzufügen Ich nehme die Standardschriftfarbe Schwarz. Deaktiviert, verblasstes Grau. Fokussiert, abgedeckt und ganz weiß gedrückt Fügen Sie einen schwarzen Umriss hinzu, sodass der weiße Text immer noch lesbar ist Auf der Registerkarte Konstanz lege ich den Umriss auf zwei Punkte fest Als Nächstes ersetze ich alle Stilfelder der Schaltflächen durch leere Stilfelder, sodass sie einfach als normaler Text angezeigt Wenn ich den Container für das vertikale Feld „Optionen“ auswähle, verwende ich den Abschnitt „Theme Override“, um zwischen den einzelnen Optionsfeldern einen Abstand von 12 Pixeln hinzuzufügen Abstand von 12 Pixeln , um den Abstand zwischen den einzelnen Optionsfeldern zu erhöhen. Nehmen Sie sich etwas Zeit, um das Layout Ihres Dialogfelds zu organisieren, und testen Sie anhand von gefälschtem Platzhaltertext die Grenzen, wie viele Informationen gleichzeitig angezeigt werden können, gleichzeitig angezeigt werden können, einschließlich der Anzahl der Optionen Sie dem Spieler anbieten möchten Wenn Sie mit der Darstellung aller Elemente zufrieden sind, denken Sie daran, das Dialogfeld auszublenden Wir müssen das Skript ändern, damit alles angemessen angezeigt werden kann. Lassen Sie uns mithilfe der Methode Get children einen Verweis auf die Optionen als Array ihrer untergeordneten Knoten abrufen. Und bei einer öffentlichen Funktion namens Display Options, eine Dialogzeile als Zeichenfolge und eine Reihe von Zeichenketten für die Optionen akzeptiert eine Reihe von Zeichenketten für , aus denen der Spieler wählen kann. Wie bei der Funktion „Zeile anzeigen weisen wir dem Zeilenarray nur die einzelne Zeile zu , die als Parameter übergeben wurde , setzen es in eckige Klammern und setzen die aktuelle Zeile auf Null. Bei der Anzeige von Dialogoptionen möchte ich, dass der Name des Sprechers ausgeblendet wird . Deshalb stelle ich eine leere Zeichenfolge ein. Wir können dann das Dialogfeld anweisen, es zu öffnen, falls es noch nicht geschehen ist, und mit der Eingabe der nächsten Zeile beginnen. Der Unterschied zum Anzeigen einer einfachen Dialogzeile besteht jedoch in einer einfachen Dialogzeile besteht jedoch der Anzeige der Optionsfelder, was ich erst tun möchte, wenn die Zeile mit der Eingabe fertig ist. Dafür benötigen wir ein weiteres Signal, das von der nächsten Zeilenfunktion ausgegeben wird. Nennen wir es fertig geschrieben. Und warte nach dem nächsten Telefonanruf auf dieses Signal. Wir müssen dieses Signal auch oben im Skript definieren . Sobald die Eingabe abgeschlossen ist, ist die Schaltfläche Weiter nicht mehr relevant. Deshalb sollten wir ihre sichtbare Eigenschaft auf Stürze setzen , um sie zu verbergen. Wir können dann eine Viererschleife verwenden, um durch die Reihe der Optionsfelder zu iterieren Da wir jedoch die Indizes des Button-Arrays mit den Indizes des String-Arrays abgleichen müssen , können wir stattdessen eine andere Art von Vier-Schleife verwenden Mit dem Alias I, das in Programmierung allgemein für den Index verwendet wird, gefolgt vom Schlüsselwort, können wir die Größe des Arrays durchgehen Der Wert von I beginnt bei Null und wird um eins erhöht , bis er die Größe des Button-Arrays erreicht hat, in diesem Fall drei, und endet Wir können jetzt den Wert von i verwenden , um zu überprüfen, ob er kleiner ist als die Größe des String-Arrays, das als Parameter an diese Funktion übergeben wurde. Falls der Dialog weniger als die maximale Anzahl von Optionen hat . Wenn dies zutrifft, können wir die Texteigenschaft der Schaltfläche am Index auf den Zeichenkettenwert desselben Index setzen und die Schaltfläche auch so einstellen, dass sie sichtbar ist. Wenn der Schaltflächenindex größer als die Anzahl der Auswahlmöglichkeiten ist, sollte die Schaltfläche nicht sichtbar sein. Schließlich können wir die obere Taste anweisen, den Fokus zu übernehmen, sodass sie mit einem Controller aufgerufen werden kann. Damit dies problemlos mit unseren anderen Funktionen zur Anzeige von Dialogen funktioniert, müssen wir die Sichtbarkeit der Schaltfläche „Weiter“ und der Optionsschaltflächen beim Eingeben von Dialogzeilen ein- und ausschalten Schaltfläche „Weiter“ und der Optionsschaltflächen beim Eingeben von Dialogzeilen ein- und beim Eingeben von Dialogzeilen Außerdem verschiebe ich die Zeile, die der Schaltfläche „Weiter“ mitteilt , dass sie den Fokus übernehmen soll, damit sie sich auch hier befindet Wenn alles korrekt angezeigt wird, müssen Sie dem Event-Skript nur noch mitteilen, welche Option der Spieler ausgewählt hat. Der Rückgabetyp dieser Funktion wird eine Ganzzahl sein. Der Index der Taste, die der Spieler gedrückt hat. Er entspricht dem Index der ausgewählten Wahl. Jede unserer Schaltflächen ruft nach einem Klick eine Funktion auf. Rufen wir sie bei gedrückter Option mit einem Integer-Parameter namens index Diese Funktion kann, genau wie das Drücken der Continue-Taste, das Dialogfenster schließen und ein Signal ausgeben. Rufen wir das gewählte Signal und übergeben den Index als Argument über das Signal. Am Anfang des Skripts können wir diesem Signal eine Definition geben und dieses Mal dem Signal auch ein Integer-Argument namens choice geben . Die Funktion mit den Anzeigeoptionen kann jetzt eine gewählte Gewichtung zurückgeben. Das bedeutet , dass sie wartet, bis der Spieler eine der Tasten drückt, erhält dann den Integer-Index der Taste, die gedrückt wurde, und gibt ihn zurück. Als letztes müssen Sie die Signale, die auf die Taste gedrückt wurden, mit dieser Funktion verbinden . Stellen Sie sicher, dass Ihr Skript gespeichert wurde , damit die Engine diese neue Funktion finden kann. Wählen Sie die einzelnen Tasten aus, verbinden Sie das gedrückte Signal und wählen Sie den Dialogfeldknoten aus der Liste aus. Ignorieren Sie die vorgeschlagene Empfängermethode und klicken Sie auf die Auswahltaste. Dadurch wird eine Liste von Funktionen im Dialogskript angezeigt , deren Parameter den Signal-Argumenten entsprechen. Da das gedrückte Signal keine Argumente hat, sind nur Funktionen ohne Parameter kompatibel. Klicken Sie auf den Schalter Nur kompatible Methoden, um eine vollständige Liste der Funktionen zu sehen , und wählen Sie die gedrückten Optionen Um das Kompatibilitätsproblem zu beheben, müssen wir dem Signal im Abschnitt für Fortgeschrittene unsere eigenen Argumente hinzufügen dem Signal im Abschnitt für Fortgeschrittene Mithilfe der Dropdownliste können wir einen beliebigen eingebauten Typ für das Argument auswählen. Derjenige, den wir verwenden möchten, ist eine Ganzzahl. dem Signal ein Integer-Argument hinzufügen, können wir seinen Wert als Array-Index der Schaltfläche festlegen. Die Optionsschaltfläche Null ist Index Null. Klicken Sie und stellen Sie eine Verbindung her. Wir können diesen Vorgang dann mit den restlichen Optionsfeldern wiederholen und dabei den Argumentwert für jedes Feld so ändern, den Argumentwert für jedes Feld so ändern dass er seinem Index im Array entspricht. Das Argument wird nun an die Funktion bei gedrückter Option übergeben , vom ausgewählten Signal ausgegeben und von der Funktion mit den Anzeigeoptionen zurück an das Event-Skript zurückgegeben mit den Anzeigeoptionen , das sie aufgerufen hat. Um die Dialogoptionen zu testen, modifizieren wir das Maj-Dialog-Eventskript Ähnlich wie die Anzeige einer einzelnen Dialogzeile. Wir können auf den Dialog Anzeigeoptionen warten, der eine kurze Dialogzeile bietet, gefolgt von einer Reihe von Optionen. Diese Anweisung gibt ausschließlich eine Ganzzahl zwischen Null und der Anzahl der Optionen im Array zurück. die zurückgegebene Ganzzahl einer Variablen zuweisen, können wir unseren Dialog dann anhand ihres Werts verzweigen Sie können dafür eine if-Anweisung verwenden, aber ich finde Match-Anweisungen für diesen Zweck viel sauberer Das Schlüsselwort match funktioniert ähnlich wie switch in anderen Sprachen. In dem Codeblock, der auf die Match-Anweisung folgt, können wir eine Option angeben, gefolgt von einem Doppelpunkt, dann innerhalb dieses Codeblocks mit dem fortfahren, was in diesem Fall passieren wird. Und geben Sie für jede unserer Dialogoptionen unterschiedliche Fälle an. Lass es uns ausprobieren. Ich habe die Texteingabegeschwindigkeit auf das Minimum eingestellt , um die Schaltfläche Weiter zu testen. Wenn wir mit dem Magier sprechen, sagt er eine Dialogzeile, die wir überspringen können. Nach dem Überspringen werden uns drei Optionen angezeigt, die in den Fokus gerückt sind, und die Schaltfläche Weiter ist nicht mehr verfügbar Wenn Sie eine der Optionen auswählen, der Dialog basierend auf der Auswahl fortgesetzt Wenn wir es erneut tun, können wir eine andere Option auswählen. Der Magier sagt etwas anderes. Wir können dieses Skript noch weiter vereinfachen, indem die Variablendeklaration durch die Match-Anweisung ersetzen . Wir haben jetzt Dialogoptionen aus denen der Spieler wählen kann, was zu verzweigten Dialogbäumen führt In der nächsten Lektion können wir es dem Spieler ermöglichen, während dieser Ereignisse im Spiel voranzukommen Wir sehen uns in der nächsten Lektion. 7. Flaggen: Hallo Freunde. In der vorherigen Lektion haben wir dem Spieler erlaubt, aus einer Liste von Optionen zu wählen und anhand dieser Auswahl haben wir einen verzweigten Dialog erstellt In dieser Lektion verwenden wir Fortschrittsmarkierungen, um die Art und Weise zu ändern, wie Ereignisse ablaufen Beginnen wir damit, dass sich der Dialog eines NPCs jedes Mal ändert , wenn der Spieler mit ihm interagiert In jedem Skript, das Sie für die Speicherdatei Ihres Spiels verwenden, verwenden wir in diesem Projekt eine benutzerdefinierte Ressource namens progress Wir können eine exportierte Variable hinzufügen um nachzuverfolgen, wie oft der Spieler mit dem Spieler interagiert hat, als Ganzzahl, die natürlich standardmäßig den Wert Null In meinem Projekt wurde das eigentliche Speichern und Laden von Dateien entfernt Denken Sie daran, dass meine Demonstrationen immer mit den Standardwerten beginnen. Weitere Informationen zum Speichern Fortschrittsinformationen und benutzerdefinierten Ressourcen finden Sie im vorherigen Kurs dieser Reihe, Grundlagen der Spieleentwicklung. Im Mage Dialogue-Skript können wir unsere Run-Event-Funktion starten, indem zuerst den Wert dieser Variablen abgleichen. Je nachdem, wie oft der Spieler mit dem Magier gesprochen hat, können wir dann wie oft der Spieler mit dem Magier gesprochen hat, verschiedene Dialoglinien bereitstellen. Es wäre sinnvoll , wenn der Spieler noch nie mit dem Magier gesprochen hat, das erste Mal mit einer Einführung zu beginnen. Wir können dann auf dieselbe Variable zugreifen und ihren Wert um eins erhöhen Und wenn der Spieler das nächste Mal mit dem Magier spricht, wird er etwas anderes sagen und auch den Wert um eins erhöhen Wenn eine Standardoption hinzugefügt wird, wird diese im Gado-Skript mit einem Unterstrich statt mit einem Wert gekennzeichnet Wir können eine sich wiederholende Dialogzeile bereitstellen, wenn der Spieler alle vorherigen Optionen ausgeschöpft hat Beim dritten Mal sprechen wir mit dem Magier und jedes Mal danach werden wir diese Dialogzeile erstellen. Lass es uns ausprobieren. Wenn wir zum ersten Mal mit dem Magier sprechen, stellen sie sich vor. Beim zweiten Mal sind sie ein gastfreundlicher Gastgeber. Beim dritten Mal und jedes Mal danach werden sie uns einfach sagen, dass sie zu beschäftigt sind, um gerade zu reden Anstatt den Dialog zu wiederholen, könnten wir diese Interaktion auch könnten wir diese Interaktion nach Abschluss des Dialogs durchführen, sodass dieser NPC nicht mehr interagierbar ist Wir können auch Zyklen von sich wiederholenden Dialogen erzeugen, indem den Wert nach der letzten Option auf eine niedrigere Zahl zurücksetzen eine niedrigere Zahl Jetzt sagt das Make jedes Mal etwas anderes , wenn dieselben drei Zeilen nacheinander wiederholt Anstatt für jeden MPC eine separate Variable zu erstellen, Sie erwägen, ein Array von ganzen Zahlen zu verwenden Wir müssen dieses Array so initialisieren , dass es für jeden MPC eine Null enthält Da ich drei NPCs habe, füge ich dem Array drei Nullen Dann kann jedem MPC in deinem Spiel eine Zahl zugewiesen werden , die bei Null beginnt und zur Indexierung des Arrays verwendet wird Wir können diesen Fehler einfacher und weniger anfällig machen indem wir eine Aufzählung, eine nummerierte Liste Ich möchte alle meine Aufzählungen aus meinem Projekt in einem einzigen Skript namens Enums speichern meinem Projekt in einem einzigen Skript Beginnend damit, ihm einen Klassennamen Enums zu geben. Es muss keine der Eigenschaften eines Knotens erben , da er nicht an einen angehängt wird Der einzige Inhalt dieses Skripts besteht darin, Aufzählungen zu deklarieren, die im gesamten Projekt verwendet werden sollen Unsere erste Nummer wird eine Liste aller NPCs im Spiel sein, Night, Mage Die Konvention für Aufzählungen besteht darin , Schlangengroßbuchstaben zu verwenden, manchmal auch als schreiende Schlange bezeichnet Das Mage-Dialogskript kann jetzt auf das Array zugreifen und es mit der Aufzählung indizieren F. Dies sind übliche Praktiken für NPC-Dialoge in Spielen, aber sie ermöglichen es dem Spieler nicht wirklich , im Spiel voranzukommen Nehmen wir die Tür als Beispiel für den Fortschritt und geben wir dem Spieler die Möglichkeit, die Tür während eines Interaktionsereignisses zu öffnen , aber nur, wenn er das Passwort kennt Das Passwort muss Spielercharakter vom Magier einem separaten Dialog mitgeteilt werden, bevor er es benutzen darf , um die Tür zu öffnen. In der Fortschrittsressource können wir eine exportierte boolesche Variable hinzufügen, die angibt ob der Spieler das Passwort kennt oder nicht, was natürlich standardmäßig auf False Boolesche Variablen, die zur Steuerung des Spielfortschritts verwendet werden, werden allgemein als Flaggen bezeichnet Wenn der Charakter mit dem Magier spricht, hat er die Möglichkeit ihn zu fragen, ob er den Gefangenen sehen möchte Bei Auswahl dieser Option teilt der Major dem Spieler das Passwort mit. An diesem Punkt können wir die Variable in der Fortschrittsressource auf true setzen , da der Spielercharakter jetzt das Passwort kennt. ein Skript an die Tür anhängen, können wir eine exportierte Variable hinzufügen, die angibt, ob die Tür gerade geöffnet ist und drei öffentliche Funktionen hinzufügen, nämlich überprüfen, ob die Tür geöffnet ist, die Tür öffnen und die Tür schließen Rückgabe eines booleschen Werts. Wir geben einfach den Wert der Variablen is open zurück, sodass andere Skripte ihren Wert leicht abrufen, aber nicht setzen können ihren Wert leicht abrufen, aber nicht setzen Kapselung anwenden. Außerdem deklariere ich eine Variable, die die Y-Position der Tür, wenn sie geschlossen ist, als Und setze den Wert während der Bereitschaftsfunktion entweder auf die aktuelle Y-Position oder die aktuelle Y-Position plus 4 Meter, basierend auf dem Wert von ist offen. Jede dieser Funktionen kann die Variable ist offen setzen und dann eine private Funktion aufrufen , um die Tür zu bewegen. Um eine Tür zu öffnen, verschiebe ich ihre Y-Position um 4 Meter nach unten und um sie zu schließen, setze ich ihre Position wieder auf den geschlossenen Wert zurück. Mit einer Tween-Variablen. Nachdem Sie überprüft haben, ob das Tween nicht bereits existiert und derzeit nicht ausgeführt wird, erstellen Sie ein neues Ich möchte, dass der Türknoten interaktiv bleibt, solange die Tür Ich bleibe in der gleichen Position und verbinde stattdessen nur die Türen mit mir öffne diese Szene und ignoriere die Warnung, da ich keine Änderungen vornehme Wir können sehen, dass sich der Netzknoten dieser Tür in der Hälfte der Wand befindet Ich verwende ihn als den Knoten, der getweetet wird , und zwischen seiner Position und seinem Wert. Da die Position die Eigenschaft ist, können wir auf die Y-Eigenschaft der Vektor-Drei-Struktur mit einem Doppelpunkt im Eigenschaftspfad zugreifen der Vektor-Drei-Struktur mit einem Doppelpunkt im , um innerhalb von 1 Sekunde an die neue Position zu gelangen von 1 Sekunde an die neue Position Das fertige Tween-Signal wird über die Funktionsaufrufen zurückgegeben , falls ein anderes Skript darauf warten möchte Das ist für diese Demonstration etwas übertrieben, aber dieses Skript ist jetzt flexibel genug, um Spiel sowohl zu öffnen als auch zu schließen ähnliche Türen überall in meinem Im Skript für das Türinteraktionsereignis benötigen wir einen Verweis auf den Wurzelknoten der Türen Der Einfachheit halber verwende ich einfach get parent. Wir können zuerst überprüfen, ob die Tür derzeit geöffnet ist. In diesem Fall können wir das Event beenden, um dem Spieler die Kontrolle zurückzugeben, und dann der Tür sagen, dass sie sich schließen und zurückkehren soll, um zu verhindern, dass dieses Skript noch einmal ausgeführt wird. Der Spieler muss nicht warten , bis sich die Tür schließt, sondern kann weiterspielen. Wenn die Tür geschlossen ist, können wir überprüfen, ob der Spieler das Passwort kennt oder nicht. Wenn der Spieler das Passwort noch nicht kennt. Wir können einen einfachen Dialog führen, in dem es darum geht , dass die Tür versiegelt wird und das Event beendet wird. Aber wenn der Spieler das Passwort kennt, lasse ich die Barbaren in der Reihe des Dialogs das Passwort sagen , das Event beenden und die Tür öffnen Ich möchte verhindern, dass der Spieler mit der Tür interagiert, während sie geöffnet oder geschlossen wird, falls der gleiche Knopf vorhanden ist In beiden Fällen setze ich die Kollisionsebene des Interaktionsknotens auf Null, um zu verhindern, dass der Interaktionsrekorder sie erkennt. Fügen Sie dann Gewichte hinzu und setzen Sie sie auf ihren ursprünglichen Wert zurück , nachdem die Tür vollständig geöffnet oder geschlossen hat. Wir können den Wert sehen, wenn wir mit der Maus über die Bitmaske fahren. Jede Ebene wird durch ein einzelnes Bit repräsentiert, entweder durch eine Null oder eine Eins im Speicher. Und jedes Bit ist nummeriert, beginnend bei Null. Schicht fünf ist Bit Nummer vier. Sein als Ganzzahl dargestellter Wert ist dann zwei hoch vier, was 16 ist. Wir können diesen Collider also reaktivieren indem wir seine Kollisionsebene wieder auf 16 setzen Wenn Sie mehrere Kollisionsebenen verwenden, wird durch Addieren ihrer Bitwerte der Integer-Wert der Bitmaske generiert Jede Ganzzahl kann auf diese Weise als Bitmaske verwendet werden. Dies ist eine äußerst effiziente Methode, um bis zu 32 boolesche Flags in einer einzigen Ganzzahl zu speichern um bis zu 32 boolesche Flags in einer einzigen Ganzzahl zu Die Tür muss mit on ready eingerichtet werden . Lass es uns ausprobieren. Wenn Sie zuerst versuchen, mit der Tür zu interagieren, ist die Tür versiegelt. Aber nachdem ich mit dem Magier gesprochen und das Passwort erneut mit der Tür interagiert habe, herausgefunden und erneut mit der Tür interagiert habe, spielt sich die Interaktion anders ab und die Tür öffnet sich. Sobald die Tür vollständig geöffnet ist, können wir erneut mit ihr interagieren, um sie zu schließen. Wir haben jetzt Fortschrittsflaggen, die es dem Spieler ermöglichen , mithilfe von Ereignissen im Spiel Fortschritte zu erzielen. In der nächsten Lektion ändern wir, worauf die Kamera bei Ereignissen schaut. Wir sehen uns in der nächsten Lektion. 8. Kamera: Hallo, Freunde. In der vorherigen Lektion haben wir es dem Spieler ermöglicht, im Spiel voranzukommen indem er bei Events Flaggen gesetzt und gelesen hat. In dieser Lektion fügen wir Event-Management-System eine Filmkamera hinzu Beginnen wir in der Spielszene, indem Eventmanager einen Kamera-Drei-D-Knoten hinzufügen Und legen Sie im Event-Manager-Skript einen Verweis darauf fest. Dann können wir in der Ebene sn am Beispiel des Maje-Dialog-Events einen weiteren Kamera-3-D-Node als untergeordnetes Element zum Interaktionsereignis hinzufügen als untergeordnetes Element zum Interaktionsereignis Dann bewegen Sie die Kamera hin und her und verwenden Sie den Schalter für die Kameravorschau, um die Kamera so zu positionieren oder zu drehen , dass sie unserer Meinung nach als Perspektive für unser Dialogereignis gut aussehen wird als Perspektive für unser Dialogereignis gut Wenn Sie mit dem Aussehen zufrieden sind, ändern Sie den Typ des Knotens Marker three D und benennen Sie ihn in einen passenderen Namen um Beibehaltung der transformierten Eigenschaften von Position und Drehung innerhalb der Szene. Wir können diese Markierung nun verwenden, um die Kinokamera während des Dialogs zu positionieren . der Kinokamera ein Drehbuch hinzufüge, lege ich es in den Events-Ordner Wir benötigen eine öffentliche Funktion um die Kamera auf eine Markierung zu bewegen, Position und Drehung der Kamera so einzustellen , dass sie der Markierung entsprechen, und diese zur aktuellen Kamera zu machen Da die Positionen und Rotationen von Kindern jedoch relativ zu ihren Eltern sind, müssen wir die globale Position und die globale Rotation verwenden , um sicherzustellen , dass wir die richtigen Werte erhalten Dann können wir im Event-Skript des Hauptdialogs einen Verweis auf diesen Markierungsknoten abrufen und den Eventmanager anweisen, die Kinokamera dorthin zu bewegen Wenn das Event endet, muss der Game Manager zurück zur Kamera des Spielers wechseln Im Game Manager-Skript benötigen wir einen Verweis auf die Hauptkamera des Spielers, damit wir, wenn Ereignisse beendet sind, die Spielerkamera zur aktuellen Kamera machen können , bevor der Spieler wieder mit dem Spielen beginnen kann. Lass es uns ausprobieren. Wenn man mit dem Magier spricht, bewegt sich die Kinokamera zur Markierung und übernimmt die Wenn das Event dann beendet ist, übernimmt die Kamera des Spielers wieder die Steuerung. Wir können den Übergang zwischen den Kameras auch ganz einfach ausblenden zwischen den Kameras auch ganz einfach dem Event-Manager-Skript eine Funktion hinzufügen, nennen wir sie Fade to Marker, akzeptieren Marker drei D und geben ein Signal zurück. Wir können warten, bis die Farbe schwarz wird, und dann den Marker an die Kinokamera senden Kehren Sie dann zum Ausblenden auf c zurück. Der Game Manager kann das Ein - und Ausblenden auch vornehmen, wenn Sie zurück zur Playerkamera wechseln Aber das würde nur Sinn machen, wenn das Event die Kinokamera verwendet Wir können dieses Verhalten auch optional machen , indem wir der Funktion einen optionalen booleschen Parameter hinzufügen und den Fade nur verwenden , wenn das Ereignis dies ausdrücklich verlangt Wir fügen dem Funktionsaufruf am Ende des Ereignisses den Wert true hinzu und warten, bis Fay am Anfang des Skripts eine Markierung Die Kamera wird nun ein- und ausgeblendet, wenn sie Beginn und am Ende des Events die Perspektive wechselt Wenn Ihre Ereignisse mehr als eine Markierung haben, möchten Sie sie möglicherweise unter einem übergeordneten Knoten sortieren Nennen wir es Kameramarken. Und nehmen Sie im Event-Skript einen Verweis darauf als eine Reihe seiner untergeordneten Elemente auf. Das Event-Skript kann die Kamera auffordern , zur Kameramarkierung Null, Eins, Zwei usw. zu wechseln , was eher einem Filmset ähnelt. Aber was ist, wenn wir wollen, dass die Kamera schwenkt? Fügen wir dem Kameraskript „Richtung schwenken“ weitere Funktionen hinzu, um die Kamera mithilfe eines Vektors zu bewegen, und „Pan to Marker“, um die Kamera schrittweise direkt an eine bestimmte Position zu bewegen . Beide akzeptieren eine Zeitdauer für das Schwenken und geben ein Signal zurück , um dem Ereignis mitzuteilen, wann sie beendet sind, falls wir es abwarten möchten. Um im Laufe der Zeit schrittweise etwas zu ändern, benötigen wir eine Tween-Variable Beide Funktionen können zu einer privaten Funktion zusammengefasst werden einer privaten Funktion zusammengefasst Nennen wir sie einfach Tween-Kamera, die das Zielziel und die Zeitdauer akzeptiert und dasselbe Signal zurückgibt Da Pan to Marker sein Ziel bereits kennt, wir diese Information einfach an die Tween-Kamerafunktion weiter greifen so auf die globale Position des Und die Funktion „Pan-Richtung“ kann ihr Zielziel berechnen , indem sie die Richtung zur aktuellen globalen Position Nachdem Sie überprüft haben, ob der Tween bereits existiert und ausgeführt wird, falls ja, beenden Sie ihn und erstellen Sie dann einen neuen Dann können wir die globale Position der Kamera so einstellen, dass sie über die angeforderte Dauer das Ziel Bei der Funktion „Pan to Marker“ wäre es auch sinnvoll, sowohl die Rotation als auch die Position der Marker anzupassen , aber vielleicht nicht jedes Mal Fügen wir einen optionalen booleschen Parameter hinzu, um dieses Verhalten zu ermöglichen Wir könnten die Tween-Kamerafunktion duplizieren um eine weitere mit Drehung hinzuzufügen, aber ich würde es vorziehen , die Drehung im booleschen Parameter zu dieser Funktion hinzuzufügen im booleschen Parameter zu dieser Funktion der Drehung den Standardwert Vektor 30 zu geben Wenn das Ereignis möchte, dass die Kamera der des Markers entspricht, dann sollten Sie auch die globale Drehung der Kamera so anpassen, dass sie der Zielrotation über die Dauer entspricht der Zielrotation über die Dauer entspricht Standardmäßig werden mehrere Tweens nacheinander ausgeführt, aber wir möchten, dass sie gleichzeitig auftreten aber wir möchten einen weiteren Funktionsaufruf hinzufügen erreichen, können wir hier parallel Wenn wir diese Argumenttypen von einem Marker drei D zu einem generischen Knoten drei D ändern , dann kann jeder Knoten drei D als Marker verwendet werden, einschließlich der Kamera des Spielers. Sie müssen dies auch als aktive Kamera festlegen , falls dies nicht bereits der Fall ist. Im Event-Manager-Skript können wir den Typ Markierung drei D auch in einen Knoten drei D ändern . Wenn wir einen Verweis auf den Kameraknoten des Spielers abrufen, wird er als privat markiert, sodass andere Skripte ihn nicht sehen Wir können dann eine Funktion hinzufügen, die die Kinokamera an die Position der Spielerkamera bewegt die Kinokamera an die Position der Spielerkamera Im Mage-Dialogskript. Anstatt Fade zu verwenden, versuchen wir, die Kinokamera auf die Position der Spielerkamera einzustellen und die Kamera während unseres Events vor der ersten Dialogzeile auf die Markierung zu schwenken unseres Events vor der ersten Dialogzeile auf die Schwenken Sie dann die Kamera nach oben und blenden Sie sie am Ende wieder zur Spielerkamera blenden Sie sie am Ende wieder zur Spielerkamera zurück. Lass es uns ausprobieren. Dieser Dialog sieht jetzt eher aus wie eine Zwischensequenz, in der sich die Kamera bewegt. Aber wir können noch einen Schritt weiter indem wir Kameraspuren erstellen , indem wir Kameraspuren erstellen, die die Kamera in einer gleichmäßigen Bewegung durch die Szene führen die Kamera in einer gleichmäßigen Bewegung durch die Szene Sie zunächst dem Interaktionsereignisknoten einen D-Knoten mit Pfad drei hinzu Interaktionsereignisknoten einen D-Knoten mit Dieser Knoten hat eine Eigenschaft, eine Curve-Three-D-Ressource. Wenn Sie darauf klicken, um ihn zu erweitern, enthält er eine Reihe von Punkten. Wenn ein Punkt hinzugefügt wird, enthält jeder Punkt einen Vektor mit drei Positionen. Beginnend mit dem ersten Punkt an der ursprünglichen Position der Markierung können wir dem Array weitere Punkte hinzufügen. Um die Kamera durch die Türen zu bewegen, dann zum Fenster der Wärter in die Gefängniszelle den anderen Punkteigenschaften handelt es sich um Anker, die der Berechnung von Punkten vor und hinter ihnen entlang der Kurve Gewicht verleihen der Berechnung von Punkten vor und hinter ihnen entlang der Der erste Punkt hat nur einen äußeren Anker, der letzte Punkt hat nur einen inneren Anker, aber jeder Punkt dazwischen hat beide diese Anker anpassen, wird die Kurve nach einer Bezier-Kurvenformel geglättet die Kurve nach einer Bezier-Kurvenformel Da wir nun einen Pfad haben dem die Kamera folgen soll, müssen wir dem Pfad einen weiteren Knoten hinzufügen Der Pfad folgt drei D-Knoten. Die zweite Eigenschaft des Pfadverfolgungsknotens, das Fortschrittsverhältnis, bewegt ihn prozentual entlang des Pfads . Pfadverfolgungsknoten wird ein Drei-D-Knoten mit Kamera hinzugefügt und Dem Pfadverfolgungsknoten wird ein Drei-D-Knoten mit Kamera hinzugefügt und seine ursprüngliche Drehung in Richtung des Magiers beibehalten. Wir können dann auf den Vorschau-Schalter klicken , um die Ansicht aus der Kameraperspektive Passen Sie dann den Fortschrittswert und beobachten Sie, wie sich die Kamera durch die Szene bewegt Wir können jetzt den D-Knoten der Kamera drei löschen. Um dies in unseren Skripten zu tun, müssen wir nur einen Verweis auf den Pfadverfolgungsknoten im Event-Skript abrufen . Ich werde den Dialog in einzelne Zeilen aufteilen , um ihn besser mit den Kamerabewegungen zu synchronisieren . Wir können dies auch als Markierung verwenden, um die Kamera zu positionieren , wenn wir möchten, bevor wir die Bewegung einleiten Dann können wir die Kamera anweisen, einem Pfad zu folgen, indem wir den Pfadfolge-Node zusammen mit der Zeitdauer als Argument übergeben zusammen mit der Zeitdauer Definieren wir diese Funktion im Kameraskript. Akzeptiert einen Pfad, dem man folgen soll und eine Zeitdauer als Parameter. Als Erstes müssen wir die Kamera wieder mit dem Pfadverfolgungsknoten verbinden dann ihre Position und Drehung entsprechend zurücksetzen. Wir machen all die üblichen Zwischenschritte und geben das Signal zurück, wenn wir fertig sind Anschließend können wir die Fortschrittseigenschaft des Follow-Knotens zusammenführen, um im Laufe der Zeit einen Wert von eins zu erreichen Und das zur aktuellen Kamera machen. Schließlich kann der Spielmanager die Kinokamera wieder dem Eventmanager zuordnen und gleichzeitig das Event bei Bedarf beenden L Lass es uns ausprobieren. Nachdem ich den Gefangenen erwähnt habe, fegt die Kamera durch die Szene, um ihn durch das Fenster zu betrachten Wenn Sie einschränken möchten, wie die Kamera dreht, während sie dem Pfad folgt, sie einfach darauf beschränken, sich entweder nur um die Y-Achse zu drehen oder gar nicht zu drehen Wir haben jetzt eine Kinokamera, die unsere einfachen Dialogereignisse in Zwischensequenzen umwandeln kann unsere einfachen Dialogereignisse in Zwischensequenzen umwandeln In der nächsten Lektion werden wir auch Charakteranimationen hinzufügen. Wir sehen uns in der nächsten Lektion. 9. Animation: Hallo Freunde. In der vorherigen Lektion haben wir dem Event-System eine Kinokamera hinzugefügt Und diese Lektion wird die Charaktere während unserer Veranstaltungen animieren die Charaktere während unserer Fangen wir mit einer Charakterszene an. Wenn Sie den Animationsbaumknoten auswählen, das Animationsbaumfenster unten im Editor das Animationsbaumfenster geöffnet. Dort wird die Zustandsmaschine angezeigt, die die Bewegungsmechanik der Charaktere steuert. Weitere Informationen zu den Grundlagen der Charakteranimation und Zustandsmaschinen finden Sie im Kurs Einführung in die Entwicklung von Three-D-Spielen. Um ein verwirrendes Geflecht von Zustandsübergängen zu vermeiden, können wir verschiedene Animationstypen in verschiedene Zustandsmaschinen aufteilen rechten Maustaste in einen leeren Bereich klicken, fügen wir diesem eine neue Zustandsmaschine hinzu Ermangelung eines besseren Namens nenne ich es Verschiedenes. mit dem Connect-Tool Fügen Sie mit dem Connect-Tool Verbindungen von der Fortbewegung zur neuen Zustandsmaschine und wieder zurück Wählen Sie mit dem Auswahlwerkzeug den Übergang von der Fortbewegung zur neuen Zustandsmaschine Erweitern Sie den Fortschrittsbereich und ändern Sie den Fortschrittsmodus von „Automatisch“ auf „Aktiviert“ diese Weise können wir die Animationen per Skript auslösen, anstatt zu die Animationen per Skript erwarten, dass der Animationsbaum den Übergang automatisch abwickelt, wie es bei der Bewegungsmechanik der Fall ist. Wenn Sie den anderen Übergang auswählen, erweitern Sie den Bereich „Wechseln“ und ändern Sie den Wechselmodus auf „Ende“, sodass alle Animationen in der neuen Zustandsmaschine beendet werden können, bevor Sie zur Fortbewegung zurückkehren Wenn Sie die neue Zustandsmaschine selbst auswählen, ändern Sie den Zustandsmaschinentyp von root auf gruppiert Die Bewegungsmechanik ist derzeit die Stammzustandsmaschine, und diese neue Zustandsmaschine wird ähnliche Animationen enthalten , die gruppiert werden , um die Organisation zu erleichtern. Klicken Sie dann auf das Stiftsymbol , um diese neue Zustandsmaschine zu bearbeiten. Wir können zum Stammverzeichnis der Zustandsmaschine zurückkehren, indem die Breadcrumb-Schaltflächen oben im Animationsbaum verwenden. In dieser Zustandsmaschine können wir alle Animationen hinzufügen, die sowohl mit der Ruheposition beginnen als auch enden sollen nur einmal abgespielt werden und nicht in einer Endlosschleife In diesem Asset-Paket entsprechen die Animationen zum Anfeuern, Interagieren und Aufnehmen dieser Beschreibung Damit die Zustandsmaschine wie erwartet funktioniert, muss die Anzahl der Übergänge vom Start an mit Anzahl der Übergänge übereinstimmen, die in die Zustandsmaschine eintreten Ebenso muss die Anzahl der Übergänge, die die Zustandsmaschine verlassen , der Anzahl der Übergänge entsprechen , die zum Endzustand führen Da es nur einen Übergang in und aus der Zustandsmaschine gibt, kann es nur einen Übergang von Anfang bis Ende eine Verbindung herstellt Wir benötigen einen Zwischenzustand dazwischen, den Zustand, der all diese Animationen sowohl startet als auch beendet , die Idle-Pose. Leider enthält dieses Asset-Paket keine Leerlauf-Pose, aber wir können sie problemlos erstellen. Wechseln Sie zum Animationsfenster am unteren Rand des Editors. Und wählen Sie die inaktive Animation aus dem Drop-down-Menü aus. Klicken Sie auf die Animationsschaltfläche neben dem Drop-down-Menü und wählen Sie dann Duplizieren aus Benennen Sie die neue Ruheposition der Animation um. Setzen Sie die Dauer der Animation der Ruheposition auf Null und deaktivieren Sie das Looping Zurück in der Animationsstruktur, der Statusmaschine mit verschiedenen Zuständen, können wir zwei Kopien der Animation für die Ruheposition hinzufügen Nennen wir sie Idle Post Start und Idle Pose End. Stellen Sie dann vom Start zur Ruheposition und von dort aus zu jedem anderen Zustand eine Verbindung her . Und jede davon mit der zweiten Ruheposition und schließlich mit dem Endzustand. die einzelnen Übergänge vom Start der Ruheposition aus auswählen, ändern Sie deren erweiterten Modus auf Aktiviert. Und die Übergänge zum Ende der Ruheposition können am Ende umgeschaltet werden. Jetzt entspricht die Anzahl der Übergänge in und aus der Zustandsmaschine der Anzahl der Übergänge von Anfang und Ende zu Ende. Es besteht keine Möglichkeit von Mehrdeutigkeiten, damit der Animationsbaum reibungslos durch den Animationsbaum navigieren kann Wir können eine Vorschau davon anzeigen, wie diese Animationen aussehen, indem wir auf die Play-Schaltfläche neben ihnen Und wir können den Übergängen in und aus der Zustandsmaschine eine kurze Überblendungsdauer hinzufügen Übergängen in und aus der Zustandsmaschine eine kurze Überblendungsdauer , um sie besser mit den Fortbewegungszuständen zu verbinden Wenn Sie mit der Zustandsmaschine zufrieden sind, können wir sie als Ressource im Projekt speichern Nachdem Sie die Animationen für die Idle-Posen der anderen Charaktere erstellt haben, kann diese Zustandsmaschine in ihre Animationsbaumknoten geladen werden ihre Animationsbaumknoten da sie alle dieselben Animationen haben. Im Zeichenskript können wir eine öffentliche Funktion hinzufügen, können wir eine öffentliche Funktion hinzufügen um den Übergang zu einer dieser Animationen auszulösen , indem wir einfach den Namen der Animation als Zeichenfolge übergeben. Wir müssen nur die State-Machine-Wiedergabe anweisen, zur Animation zu wechseln, indem wir den Namen der gruppierten Zustandsmaschine, die sie enthält, zusammen mit einem Trennzeichen an den Anfang setzen. Aber wir müssen manuell einschränken, dass dies nur vom Fortbewegungsstatus aus geschehen darf, indem zuerst den aktuellen Knoten der Zustandsmaschine überprüfen Wenn es sich bei dem aktuellen Knoten nicht um Locomotion handelt, sollten wir diese Anfrage ignorieren Dadurch wird verhindert, dass diese Animationen während des Sprungs gestartet werden Möglicherweise möchten wir auch nicht, dass sich der Charakter bewegen kann , während diese Animationen abgespielt werden. Fügen wir einen optionalen booleschen Parameter namens locked mit dem Standardwert true Und deklarieren Sie auch eine private Variable für das Skript, die angibt, ob das Zeichen gleichzeitig bewegt dieser Variablen nach dem Setzen ihres Werts einen Setter hinzufügen, Wenn wir dieser Variablen nach dem Setzen ihres Werts einen Setter hinzufügen, sollten wir auch den Wert der Eingaberichtung auf Null setzen, um das Zeichen zu stoppen, falls es sich bereits bewegt sollten wir auch den Wert der Eingaberichtung auf Null setzen, um das Zeichen zu stoppen, falls es sich bereits Dann können wir in jeder Funktion , die sich bewegt oder springt, eine bedingte Anweisung hinzufügen, die prüft ob sich das Zeichen bewegen kann, bevor wir es zulassen Wenn wir aufgefordert werden, eine Animation auszuführen die Animation die Bewegung blockiert, können wir die Variable can move auf False setzen und sie nach Abschluss der Animation wieder auf true Aber wir können nicht einfach auf das Signal zum Abschluss der Animation warten, da es ausgegeben wird, wenn die aktuelle Animation beendet ist, die inaktiv ist und nicht die , auf die wir warten wollen. den Befehl wait innerhalb einer While-Schleife platzieren und die Schleife einfach fortsetzen, können wir jedes Signal für die Beendigung der Animation wiederholt abwarten , bis das gewünschte Signal ausgegeben wird. Halten Sie die Strg- oder Befehlstaste gedrückt und klicken Sie auf das Signal. Wir können sehen, dass ein Argument mit dem Namen der Animation übergeben wird, die gerade beendet wurde. O. Wir müssen diesen Wert nur mit dem Animationsnamen vergleichen, , wenn er empfangen wird , die Warteschleife durchbricht und die Variable can move wieder auf true setzt Und um diesen Wert als Teil des Event-Management-Systems zu verwenden , sollten wir ein Rücksignal erhalten, nur für den Fall, dass wir darauf warten wollen Nennen wir diese Signal-Animation als abgeschlossen. Wir können das Signal ausgeben und zurückgeben wenn die Animation abgebrochen wurde, und ihm einen booleschen Parameter dafür geben, ob die Animationsanforderung erfolgreich war oder nicht Das Argument ist die Übergabe von „false“. Und am Ende der Funktion mit true. Definition des Signals und seines Parameters oben im Skript. Da unser Eventmanager bereits einen Verweis auf den Spielercharakter hat, ist es jetzt trivial, ihm zu sagen, dass er diese Animationen ausführen soll Im Skript zur Interaktion mit der Zellentür warten wir ab und interagieren mit der Animation, warten wir ab und interagieren mit bevor ein Dialog stattfindet Im Maj-Dialogskript benötigen wir einen Verweis auf den Hauptcharakter, benötigen wir einen Verweis auf den Hauptcharakter um Animationen von ihm anfordern zu können kann ganz einfach mit Add On Ready und Get Parent gemacht werden , da diese Interaktionsnotiz für den Magier Kindheit ist Wenn Sie mehrere Charaktere einbeziehen möchten, exportieren Sie einfach eine Variable für jedes Zeichen, das im Dialog enthalten ist Ich lasse den Magier beim Sprechen jubeln , indem ich das Schlüsselwort await ausklammere, aber so tue, als ob die Animation tatsächlich wütend ist Beachten Sie, dass wir den Charakteren auch andere Befehle wie Start, Sprung oder Gesichtsrichtung geben können andere Befehle wie Start, Sprung . Lass es uns ausprobieren. Wenn sie mit dem Magier sprechen, schlagen sie wütend herum, während sie den Spielercharakter im Dialog anschreien Wenn wir mit der Tür interagieren, streckt der Spielercharakter die Hand aus und berührt sie, bevor er den Rest des Events einleitet Wir haben jetzt die Möglichkeit, Charaktere während unserer Events zu animieren In der nächsten Lektion werden wir die Charaktere nach verschieben. Wir sehen uns in der nächsten Lektion. 10. Richtung: Hallo, Freunde. In der vorherigen Lektion haben wir dem Event-System Charakteranimationen hinzugefügt. In dieser Lektion werden wir den Charakteren sagen, dass sie zu zweit laufen und rennen sollen. Lassen Sie uns eine einfache Zwischensequenz einrichten. Wenn wir mit dem Magier sprechen, lassen wir ihn zurück zur Wand gehen , etwas aus dem Regal nehmen, zum Spieler zurückkehren und es ihm geben. Wie bei der Kamera können wir drei D-Knoten hinzufügen, können wir drei D-Knoten hinzufügen dem Charakter sagen , wohin er sich bewegen soll. Ähnlich wie Regieanweisungen. Wir können einen als untergeordnetes Element des Magiers hinzufügen, um seine genaue aktuelle Position einfach zu kopieren. Dann duplizieren Sie es und verschieben Sie das neue so, dass es neben den Regalen an der Wand steht. Achten Sie darauf, genügend Platz zu lassen, damit der Collider des Charakters nicht mit der Wand kollidiert , bevor er das Ziel erreicht Wenn du mehrere Markierungen in einem Event hast, wäre es hilfreich, sie unter einem übergeordneten Knoten zu sortieren Klicken Sie auf sie und ziehen Sie sie, um sie einem neuen Elternteil zuzuordnen. Wenn die Figur jedoch herumläuft, bewegen sie sich alle dorthin, da all diese Knoten dem Charakterknoten untergeordnet sind da all diese Knoten dem Charakterknoten untergeordnet Wir können die übergeordneten Knoten auswählen, die unsere Markierungen enthalten, den Transformationsbereich erweitern und auf den Schalter der obersten Ebene klicken, um zu verhindern, dass die Transformationseigenschaften vererbt werden Die Markierungen bleiben unbeweglich solange das Objekt herumläuft Dann können wir im Event-Skript einen Verweis auf diesen Knoten als Array seiner untergeordneten Knoten abrufen . Nach einer Dialogzeile können wir den Magier anweisen, zur ersten Charaktermarke zu gehen, interagieren, dann zur Charaktermarke Null zurückzukehren und erneut zu interagieren , bevor eine weitere Dialogzeile angezeigt wird. Im Zeichenskript können wir die Funktion hinzufügen, die dem Spieler sagt, dass er sich zu einer Markierung bewegen soll. Akzeptiert drei D als Markierung und eine zulässige Entfernung zum Ziel als Gleitkommazahl für Parameter Dadurch kann die Funktion beendet werden , wenn das Zeichen nahe genug an die Markierung herankommt nahe genug an die Markierung herankommt , ohne direkt darauf stehen zu müssen Geben wir ihr einen Standardwert von einem Viertelmeter. Geben Sie dann ein Signal zurück , wenn es fertig ist. Fügen wir ein Signal mit dem Namen destination reached hinzu, senden es aus und geben es am Ende der Funktion zurück. die aktuelle globale Position des Charakters vom Ziel subtrahieren , erhalten wir einen Vektor, der auf das Zeichen zeigt, einen Vektor mit einer Richtung und einer Entfernung Unsere Zeichensteuerelemente gehen von einer Vektorlänge von eins aus, da diese vom Eingabe-Singleton bereitgestellt wird Wenn wir diese Richtung verwenden, um ein Zeichen zu bewegen, müssen wir es zuerst normalisieren Länge des Vektors auf eins setzen Indem Sie einfach die Richtungsvariable setzen, bewegt der physikalische Prozess den Charakter dann. Wenn wir das alles in eine Wile-Schleife packen, können wir diesen Code weiter ausführen, solange das Zeichen weiter vom Ziel entfernt ist als die zulässige Entfernung Erwartung des nächsten Physik-Frames Dieser Code wird parallel zum Physikprozess ausgeführt , um den Charakter von dort, wo er sich gerade befindet, dorthin zu bewegen , wo er Wenn das Ziel erreicht ist, können wir ihre Richtung auf Vektor 30 setzen , um ihre Bewegung zu stoppen, aber der Charakter wird von hier aus immer noch langsamer vorwärts Wenn wir wollen, dass die Figur genauer auf der Markierung anhält, muss sie zuerst abbremsen, bevor sie sie erreicht. Wir können dies also in zwei Phasen vor und nach dem Punkt, an dem der Charakter zu bremsen beginnt, aufteilen und nach dem Punkt, an dem der , der als Bremsweg bezeichnet wird Wir können den Bremsweg berechnen, indem wir ihre aktuelle X-Z-Geschwindigkeit nehmen sie mit einer Geschwindigkeit von Null als Durchschnitt berechnen. Dies kann vereinfacht werden , indem wir sie durch zwei teilen und sie dann auch durch ihre Verzögerung dividieren Der Bremsweg ist umso länger, je schneller sich der Charakter bewegt, und hängt auch von der Geschwindigkeit der Verzögerung ab Bis der Charakter den Bremsweg erreicht hat, beschleunigt er bis zu seiner Höchstgeschwindigkeit Wenn sie den Bremsweg erreichen, werden sie langsamer und kommen mehr oder weniger direkt am Ziel vollständig zum Stillstand mehr oder weniger direkt am Ziel vollständig zum Stillstand weniger direkt am Ziel Wenn der zulässige Abstand vor dem Bremsweg erreicht wird , hält der Charakter trotzdem All dies kann mit einer Turn-Rey-Anweisung in einer Zeile Solange der Spielercharakter von vorne mit dem Magier interagiert , funktioniert das einwandfrei Wenn der Spielercharakter jedoch im Weg steht , wohin der Magier gehen möchte, kann dies dazu führen, dass der Magier sein Ziel nicht erreichen Während die Navigation einer statischen Umgebung ziemlich einfach ist, dynamische Pfadfindung um sich bewegende Hindernisse herum ist die dynamische Pfadfindung um sich bewegende Hindernisse herum ein schwer zu lösendes Problem. In vielen älteren Spielen gingen die Charaktere oft aneinander vorbei oder wurden für eine begrenzte Zeit geblockt und rasten dann als letztes Mittel an ihr Ziel. Keines davon sieht sehr gut aus. Die meisten modernen Spiele, einschließlich AA, werden sich stattdessen dafür entscheiden, ihre Zwischensequenzen in einer vollständig kontrollierten Umgebung ablaufen zu lassen und jegliche Möglichkeit einer Pfadversperrung auszuschließen Um dies zu erreichen, wird jede Zwischensequenz , in der Charaktere herumlaufen , zunächst schwarz verblassen Anschließend kann jede Figur in der Szene neu positioniert werden, falls erforderlich, bevor die Szene gestartet Wenn die Szene dann wieder eingeblendet wird, jede Bewegung sorgfältig choreografiert Wir können eine weitere Charaktermarkierung hinzufügen, um festzulegen, wo der Spielercharakter während dieser Interaktion stehen soll während dieser Interaktion stehen Aber wenn die oberste Ebene aktiviert ist, scheinen sich die Charaktermarkierungen zum Ursprung der Szene bewegt zu haben, scheinen sich die Charaktermarkierungen zum Ursprung der Szene bewegt zu haben, behalten aber weiterhin ihre globale Position wie zuvor Das macht das Hinzufügen weiterer Markierungen schwierig. Lassen Sie uns den Schalter auf oberster Ebene ausschalten und die Transformationsposition bearbeiten, um eine Aktualisierung zu erzwingen, setzen wir sie dann auf Null zurück Jetzt erscheint sie an der richtigen Position. Fügen wir noch einen hinzu und verschieben wir ihn dorthin, wo der Barbar stehen sollte Wir stellen seine Rotation so ein, dass sie dem Zeitalter entspricht. Schalten Sie dann die oberste Ebene wieder ein. Im Zeichenskript benötigen wir eine Funktion, die den Charakter nicht an eine Markierung bindet, sondern einfach seine Position und eventuell die Drehung direkt darauf festlegt eventuell die Drehung direkt darauf Akzeptiert einen Knoten drei D als Parameter und einen optionalen Parameter, um die Y-Rotation mit dem Standardwert true abzugleichen die Y-Rotation mit dem Standardwert true Wir müssen kein Signal zurückgeben, da dies sofort geschehen wird. die globale Position des Charakters so ein, Sie die globale Position des Charakters so ein, dass sie übereinstimmt, und falls sie der Drehung entspricht, stellen Sie auch die Y-Rotation des Rigs entsprechend Wenn die Zwischensequenz beginnt, wir zuerst schwarz. Dann positioniere den Spielercharakter auf der zweiten Charaktermarke, sodass er auch seiner Rotation entspricht, bevor du wieder einblendst und den Rest des Events fortsetzt Selbst wenn wir bewusst dem Major im Weg stehen, wird die Zwischensequenz nun schwarz, um dies zu korrigieren, bevor wir das Event kontrollierter spielen , um mögliche Probleme zu vermeiden T L Wir machen die Funktion zum Laufen des Charakters noch flexibler , indem wir die Option hinzufügen, den Charakter laufen zu lassen. Hinzufügen eines booleschen Parameters namens running mit dem Standardwert false Wir können dem Charakter sagen, dass er am Anfang der Funktion laufen und am Ende der Funktion weiterlaufen soll, wenn dieser Parameter auf true gesetzt ist Wir können auch eine weitere Funktion hinzufügen, die es dem Charakter ermöglicht , einem Pfad mit mehreren Punkten statt nur einem zu folgen . Beginnend mit derselben Funktionsdefinition wie Move to Maker, benennen wir sie in follow path um. Ändern Sie den ersten Parameter in path und entfernen Sie den Typ. Wir gehen einfach davon aus, dass es sich um ein Array von Knoten drei D handelt, ohne es zu erzwingen Senden Sie dann das Signal „ Ziel erreicht“ aus und geben Sie es zurück. Deklarieren einer neuen Variablen für den aktuellen Punkt auf dem Pfad, auf den wir zusteuern , der bei Null beginnt Solange diese Zahl kleiner als die Größe des Arrays ist , sollten wir abwarten, bis wir zu dieser Markierung wechseln Und wir können die gleichen zulässigen Entfernungs - und Laufwerte weitergeben die gleichen zulässigen Entfernungs - und Laufwerte In der Kerker-Szene habe ich eine Markierung angebracht, eine Markierung angebracht zu der der Barbar gehen kann, nachdem er die Tür geöffnet hat, und drei Markierungen, die einen Weg bilden, auf dem der Schurke Da sich der Türinteraktionsknoten nicht bewegt, müssen Sie sich auch keine Sorgen machen, dass sich die Markierungen Die Interaktion mit der Zellentür benötigt dann einen Verweis auf diese Markierungen sowie auf den Schurkencharakter Während sich die Tür öffnet, kann der Barbar aus dem Weg gehen, bis die Markierung Null erreicht Dann wird sich der Schurke beim Verlassen der Gefängniszelle bedanken beim Verlassen der Dann füge ich mehr zulässige Entfernungsnachsicht und Ich lasse den Spieler wieder die Kontrolle haben, sobald er mit der Dialogbox fertig ist, sodass er nicht untätig herumsitzen muss, während der Schurke davonläuft. Lass es uns ausprobieren. mit der Zelle interagiert, öffnet sich die Tür und der Barbar geht zur Seite Dann bedankt sich der Schurke und flieht. Wir haben jetzt Charaktere, die bei Veranstaltungen laufen und rennen können bei Veranstaltungen laufen und rennen Und die nächste Lektion wird den modularen Aufbau unserer Veranstaltungen verbessern . Wir sehen uns in der nächsten Lektion. 11. Modularität: Hallo Freunde. In der vorherigen Lektion haben wir Charaktere bei Veranstaltungen herumlaufen und herumlaufen lassen. In dieser Lektion werden wir mit einigen Verbesserungen an den Veranstaltungsskripten abschließen . In diesem Kurs haben wir eine Vielzahl verschiedener Veranstaltungen konzipiert. Einige werden ausgelöst, wenn der Spieler einen bestimmten Bereich betritt, andere, wenn er eine Taste drückt. Wenn wir uns diese beiden Drehbücher ansehen, können wir beginnen, die Ähnlichkeit der Run-Event-Funktion mit so etwas wie einem Drehbuch zu erkennen, das Charakteren und Kameras an einem Filmset Anweisungen gibt und Kameras an einem Filmset Sie können sich vorstellen, ein ganzes Spiel zu machen. Es wird Hunderte oder möglicherweise Tausende dieser Skripte geben , möglicherweise von mehreren Personen geschrieben wurden. Wir möchten, dass sie so einfach wie möglich zu schreiben und zu bearbeiten sind , um den Zeitaufwand für ihre Erstellung zu reduzieren , und dass sie standardisiert sind, um potenzielle Fehler zu reduzieren. Beginnen wir damit, dem Event Manager-Skript eine Klassennamendeklaration hinzuzufügen . Dann gibt die Engine in unseren Event-Skripten, die den Typ des Event-Managers angeben, die den Typ des Event-Managers angeben, nun Vorschläge zur automatischen Vervollständigung aus, wenn auf Variablen oder Funktionen innerhalb des Event-Managers zugegriffen wird auf Variablen oder Funktionen innerhalb des Event-Managers zugegriffen innerhalb des Event-Managers Eine nützliche Funktion, um Fehler in jedem Skript zu reduzieren , das sie verwendet Als Nächstes wäre es nützlich, die Art und Weise, wie ein Ereignis ausgelöst wird, von der Art und Weise, wie es abgelaufen ist, zu trennen . Lassen Sie uns ein neues Skript im Event-Ordner erstellen. Obwohl Godot eigentlich keine Implementierung einer abstrakten Klasse hat, können wir trotzdem so tun, als wäre dies eine abstrakte Klasse, eine, die niemals in irgendeiner Weise instanziiert, sondern nur vererbt werden soll in irgendeiner Weise instanziiert Wir haben von Aa drei D geerbt und ihr einen Klassennamen Interaktionsereignis Wenn die Interaktionsmethode in diese Klasse verschoben wird, jedes Interaktionsereignisskript kann jedes Interaktionsereignisskript im Spiel dann vom Interaktionsereignis erben , um die Interaktionsfunktion durch Vererbung zu verbergen die Interaktionsfunktion durch Vererbung Wir können auch den Code der Kollisionsebene bereinigen, indem geerbte Methoden mit entsprechenden Namen aufrufen Wie set interactable, wobei true oder false als Argument übergeben Dann kann die Interaktionsereignisklasse die Details darüber verbergen, wie dies erreicht wird, und es für alle interagierbaren Ereignisse im Spiel standardisieren es für alle interagierbaren Die Kollisionsebene wird auf 16 gesetzt, wenn sie interagierbar ist, oder auf Null, wenn sie nicht interagierbar ist. Es wäre eine gute Idee, von interaction event weiter zu erben, um eine gemeinsame Klasse zu erstellen , die auf jede ähnliche Interaktion in Ihrem Spiel angewendet werden kann , z. B. ein Skript für alle Türen oder ein Skript für alle oder ein Skript für Die einzigen Unterschiede zwischen ihren ähnlichen Interaktionen sind exportierte Variablen oder Verweise auf andere Knoten Viele Ereignisse in Spielen werden nur unter bestimmten Bedingungen ausgelöst, und viele werden irrelevant, nachdem sie einmal passiert sind. Jedes unserer Skripte für Interaktionsereignisse kann die Interaktionsmethode einfach überschreiben, um Bedingungen hinzuzufügen . Dabei wird gegebenenfalls der Fortschritt des Spielers auf Flaggen überprüft, bevor die Oberklassendefinition von interact aufgerufen wird, um das Ereignis zu starten Okay. Dieselbe Flagge wird innerhalb der Veranstaltung gesetzt. Wir können dieses Ereignis auch uninteragierbar machen , um zu verhindern, dass dasselbe Ereignis zweimal passiert Eine weitere beliebte Option ist es, die Ready-Methode zu verwenden , um zu überprüfen, ob die Bedingungen für dieses Ereignis erfüllt sind , und es so einzustellen, dass es interagierbar ist oder nicht, wenn es zum ersten Mal ins Spiel geladen wird interagierbar ist oder nicht, wenn es zum ersten Mal Dies ist häufig immer dann der Fall, wenn Auslösen eines Ereignisses erfordert, den Level zu verlassen und wieder in ihn zurückzukehren, um ihn zurückzusetzen, bevor beispielsweise mit einem NBC gesprochen Die Bedingungen für das Ereignis werden nur beim ersten Laden überprüft Lassen Sie uns das Interaktionsereignis-Skript duplizieren und außerdem ein Proximity-Event-Skript erstellen. Den Klassennamen entsprechend ändern. Wir können die Interact-Methode durch einen eingegebenen Body ersetzen den Body als Drei-D-Parameter akzeptieren. Diese Kollision löst das Ereignis aus, aber das vom Körper eingegebene Signal ist nicht von Natur aus miteinander verbunden In der Ready-Funktion können wir das Signal manuell mit der aufrufbaren Methode verbinden Lassen Sie uns auch die Kollisionsmaske so einstellen , dass sie den Spieler erkennt . Das ist Ebene neun, Bit acht, zwei hoch acht ist 256 Jetzt kann jedes Event-Skript vom Näherungsereignis erben, und auslösenden Bedingungen sowie Kollisionsmaskierung werden automatisch behandelt In diesem Projekt habe ich allen Charakteren dieselbe Kollisionsebene zugewiesen, sodass jeder von ihnen Näherungsereignisse auslöst Öffnen der Projekteinstellungen, unter Ebenennamen, drei D-Physiken. Fügen wir eine separate Ebene für NPCs hinzu. Dann können wir in jeder NPC-Szene ihre Kollisionsebene von Spieler zu NPC ändern und sie beide maskieren lassen Jetzt wird nur noch der Spielercharakter durch Näherungsereignisse erkannt Lassen Sie uns auch eine andere Art von Ereignis erstellen, eines, das überhaupt nicht vom Spieler ausgelöst wird, sondern durch andere Skripte ausgelöst werden kann. Der Spielmanager wird wahrscheinlich ein Intro-Event starten , wenn das Spiel zum ersten Mal geladen wird Ein Level möchte möglicherweise auch Ereignisse auslösen, wenn der Spieler es betritt, oder Ereignisse möchten möglicherweise andere Ereignisse auslösen erstellen ein neues Skript im Events-Ordner, nennen wir es Scripted Event Dieses Mal erbt es von Node, da es keine Verhaltensweisen der Aa-Drei-D-Knotenklasse benötigt der Aa-Drei-D-Knotenklasse Da ein skriptbasiertes Ereignis nicht ausgelöst werden muss, besteht der einzige Zweck des Skripts darin, sicherzustellen, dass es eine Run-Event-Funktion gibt, und außerdem ein Signal bereitzustellen, das ausgegeben wird, wenn das Ereignis beendet ist kann ausgegeben und zurückgegeben werden Jedes Skript, das von dieser Klasse erbt, kann jetzt Super-Dot-Run-Ereignis zurückgeben, um dieses Verhalten zu automatisieren Das Hinzufügen einer Variablen zur sicheren Datei des Players, nennen wir sie Intro Played Ablean, was natürlich standardmäßig auf Falls setzt Lassen Sie uns ein Intro-Event erstellen, das nur einmal ausgelöst wird , wenn das Spiel zum ersten Mal geladen wird Der Einfachheit halber lasse ich es einfach einblenden, da der aktuelle Status von Fate schwarz ist, wenn das Spiel zum ersten Mal geladen Dann sag Hallo Welt und setze die Flagge auf wahr. Geben Sie dann das Spot Run-Ereignis zurück, das das fertige Signal ausgibt und zurückgibt Und sag dem Game Manager auch, dass er das Event beenden soll. der Spielszene eine neue Notiz hinzu , um das beschriebene Ereignis abzuhalten Der Spielmanager kann mithilfe von Add On Ready einen Verweis darauf abrufen mithilfe von Add On Ready einen Verweis darauf In der Ready-Funktion. Wir können diese Flagge jetzt überprüfen. Starte dann das Intro-Event und warte auf das fertige Signal. Wenn das Flag auf true gesetzt wurde , wird es übersprungen Die Szene läuft, das Intro-Event ps. Wenn der Spieler das Spiel speichert und erneut lädt, wird das Intro-Skript-Event kein zweites Mal ausgelöst Ich werde das demonstrieren, indem ich die Variable in der sa-Datei standardmäßig die Variable in der sa-Datei Fügen wir einen weiteren Knoten hinzu, der ein sekundäres Ereignis enthält, eines, das durch ein primäres Ereignis ausgelöst wird diesem Knoten ein Skript hinzu, das von einem skriptbasierten Ereignis erbt Es wird nur ein sekundäres Ereignis angezeigt und das Superpunkt-Run-Ereignis wird zurückgegeben Jedes Event-Skript im Spiel kann jetzt auf die Ausführung dieses sekundären Events warten und es wird ausgeführt, bevor es zu dem Event zurückkehrt, das es ausgelöst hat. Dies kann helfen, überlange Ereignisse in größere Abschnitte aufzuteilen , verzweigte Erzählungen in separate Skripte aufzuteilen oder dasselbe Ereignis wiederzuverwenden, um es in mehreren Kontexten zu Wir verfügen jetzt über ein sehr umfangreiches Dialog- und Eventmanagementsystem sich komplexe, verzweigte Erzählungen und überzeugende Zwischensequenzen erstellen lassen und den Spielern die Wahl lassen können, wie sie im Spiel vorankommen komplexe, verzweigte Erzählungen und überzeugende Zwischensequenzen erstellen lassen und den Spielern die Wahl lassen können, überzeugende Zwischensequenzen erstellen lassen und den Spielern die Wahl lassen möchten Dialog- und Eventmanagementsystem , mit dem sich komplexe, verzweigte Erzählungen und überzeugende Zwischensequenzen erstellen lassen und den Spielern die Wahl lassen können, wie sie im Spiel vorankommen möchten. Das System ist auch so optimiert, dass die Erstellung der Event-Skripte relativ einfach ist 12. Was kommt als Nächstes?: Willkommen zu meinem Kurs über Inventar und Geschäfte in Gado. Dieser Kurs ist eine Fortsetzung des Dialogs und der Ereignisse in Gado, kann aber verfolgt und auf jedes Projekt angewendet werden , bei dem es darum geht, Gegenstände aufzusammeln, zu einem Inventar hinzuzufügen, Gegenstände aus einem Inventarmenü fallen zu lassen, zu verwenden oder auszurüsten und Gegenstände mit einem MPC Du bist herzlich eingeladen, unserem Discord-Server beizutreten , um mit deinen Kollegen an diesem Kurs zu arbeiten In diesem Kurs werden wir uns mit verschiedenen Methoden befassen, um Gegenstände einzusammeln, Inventardaten der Spieler zu verwalten, ihr Inventar auf der Benutzeroberfläche in einem Menü anzuzeigen, es dem Spieler zu ermöglichen, auf unterschiedliche Weise mit seinem Inventar zu interagieren , und Gegenstände mit NPCs zu tauschen Wenn du fertig bist, hast du ein einfaches Inventarsystem für dein Spiel , das in seiner Darstellung und Funktion leicht anpassbar ist in seiner Darstellung und Funktion Sie werden auch nützliche Fähigkeiten erlernen um mit der Gada-Game-Engine zu arbeiten und Ihre Projekte so zu organisieren und zu gestalten, organisieren und zu gestalten dass sie skalierbarer sind Sie werden lernen, wie man mit dem GD-Skript programmiert, wobei alles ausführlich erklärt wird Wir werden objektorientierte Designprinzipien in unseren Skripten, Vererbung, Kapselung, Abstraktion und Polymorphie anwenden in unseren Skripten, Vererbung, Kapselung, , um sie für ein Projekt jeder Größe organisiert, anpassbar und wiederverwendbar zu halten für ein Projekt jeder Größe organisiert, anpassbar und wiederverwendbar Alle Projektdateien sind auch auf GitHub verfügbar, falls Sie das Projekt so überprüfen möchten, wie es nach Abschluss jeder Lektion war Diese Videos wurden mit Geoversion 4.2 0.2 aufgenommen. Das Projekt beginnt mit Inhalten aus K Kits, Charakteren- und Dungeon-Remaster-Paketen Basic Guy-Paket von Penzilla und Icons von Shakahi und Alle können dort kostenlos heruntergeladen werden. Soundeffekte von Valensbyer sind ebenfalls enthalten und auf freesound.org verfügbar