Master Godot 4: Erstellen Sie ein Survivors-Roguelike mit GDScript | Chris Tutorials | Skillshare

Playback-Geschwindigkeit


1.0x


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

Master Godot 4: Erstellen Sie ein Survivors-Roguelike mit GDScript

teacher avatar Chris Tutorials, 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 in den Kurs

      1:43

    • 2.

      Godot-Projekt einrichten

      6:38

    • 3.

      Grafik, Sound und Plugins ~ Importieren und Installieren

      8:46

    • 4.

      Spielerbewegung von oben nach unten

      34:39

    • 5.

      Animationen aus Spritesheets abspielen

      9:51

    • 6.

      Spieler-State-Maschine

      18:49

    • 7.

      Spielereingabe als Komponente

      13:08

    • 8.

      Animationen mit Signalen wechseln

      9:17

    • 9.

      Umdrehen eines 2D-Charakters

      13:41

    • 10.

      Kartenebenen für Gras und Schmutzfliesen

      16:38

    • 11.

      Platzieren von Bäumen als Karten-Requisiten

      15:16

    • 12.

      Stumpfe hinzufügen und Y-Sortierung beheben

      9:41

    • 13.

      Projektile mit einem Timer erzeugen

      14:54

    • 14.

      Projektile in Abschussrichtung bewegen

      6:25

    • 15.

      Einrichten von Feinden und Hitboxen

      16:55

    • 16.

      Füge Feinden mit Hitboxen und Statistiken Schaden zu

      9:14

    • 17.

      Todeszustand, wenn der Feind 0 PS erreicht

      13:59

    • 18.

      Dreh- und Zielprojektile bei Waffenauslastung

      5:43

    • 19.

      Soundeffekte und Musik hinzufügen

      7:21

    • 20.

      Kampfsystem Singleton

      5:48

    • 21.

      Animieren von schwimmendem Kampftext

      18:26

    • 22.

      Feindbewegungen mit Spielerverfolgung in Godot 4

      16:53

    • 23.

      Erzeugen von Feinden auf einer Zeitkurve

      15:36

    • 24.

      Off-Screen-Generierung mit berechnetem Offset

      19:25

    • 25.

      Zufällige Gegnerspawnung mit Gewichts- und Zeitbedingungen

      15:11

    • 26.

      Einrichtung von Player Hurtbox und Enemy Hitbox

      7:09

    • 27.

      Spielerunbesiegbarkeits-Timer und benutzerdefinierte Statistikdefinitionen

      10:45

    • 28.

      Implementieren periodischen Schadens für gegnerische Hitboxen

      4:35

    • 29.

      Spielerniederlage

      7:40

    • 30.

      Testen und Verbessern des Verhaltens bei Spielerniederlagen

      5:06

    • 31.

      Erstellen einer Pickup2D-Szene

      6:00

    • 32.

      Implementieren von Experience Pickup System mit Vererbung

      4:42

    • 33.

      Einrichten von Collector2D und Korrigieren von Playeranimationen

      5:24

    • 34.

      Erstellen von Feindabwurfmechanismen und Größenänderung von Pickups

      11:32

    • 35.

      Zufällige Ablegpositionen für Elemente erzeugen

      4:45

    • 36.

      Implementieren eines Pickup-Schwerkraftbereichs

      10:31

    • 37.

      Erstellen einer Player-Benutzeroberfläche mit HP- und EXP-Fortschrittsbalken

      11:15

    • 38.

      Implementieren eines statistikbasierten Benutzeroberflächensystems mit Signalen

      10:38

    • 39.

      Skripting dynamischer HP- und EXP-Anzeigen für die Player-Benutzeroberfläche

      16:06

    • 40.

      Debuggen und Optimieren von Benutzeroberfläche und Pickup-Skripten

      5:11

    • 41.

      Levelingsystem mit Erfahrung und Statistikfortschritt

      18:39

    • 42.

      Einrichten von XP-Schwellenwerten und Signalverbindungen für Level-Up-Belohnungen

      9:47

    • 43.

      Erstellen des Layouts der Level Up-Benutzeroberfläche und des animierten Texts

      8:39

    • 44.

      Entwerfen der Benutzeroberfläche für die Prämienauswahl und endgültige Anpassungen

      8:35

    • 45.

      Erstellen eines Waffenleveling-Systems für Spiel-Upgrades

      9:55

    • 46.

      Waffengegenstände zum Aufstufen der Waffenkraft

      13:24

    • 47.

      Erstellen eines gewichteten Gegenstandsauswahlsystems für Stufenaufstiegsbelohnungen

      14:30

    • 48.

      Kodieren der Prämienauswahl mit Signalausbreitung

      18:35

    • 49.

      Anwenden von Statistiken auf Waffenstufen auf Projektil-Spawning und -Instanzen

      10:03

    • 50.

      Aufbau einer rotierenden Scythe-Waffe

      10:21

    • 51.

      Erstellen einer Benutzeroberfläche für die Waffenanzeige für das Spielinventar

      19:40

    • 52.

      Verbinden von Signalen und Konfigurieren von Waffen UI für dynamische Anzeige

      19:31

    • 53.

      Erstellen von Statistik-Boosting-Elementen für Spieler-Upgrades

      11:14

    • 54.

      Implementieren von HP Boost Pickups und Level Up UI-Korrekturen

      10:33

    • 55.

      Erstellen eines Heiltrankaufnehmers für feindliche Tropfen

      5:23

    • 56.

      Implementieren von Camera Shake für Spielerschlag- und Todeseffekte

      10:14

    • 57.

      Erstellen eines Game Over Screen mit Hauptmenünavigation

      8:29

    • 58.

      High-Score-Verfolgung und Benutzeroberflächenanzeige für Feindniederlagen und Überlebenszeit

      17:15

    • 59.

      Speichern und Laden von Highscores mit JSON

      13:54

    • 60.

      Entwerfen eines Hauptmenüs mit High-Score-Display und Spielstart-Funktion

      11:22

    • 61.

      Skriptüberlebende Skripte polieren ~ Gameplay-Verbesserungen und Debugging

      16:34

  • --
  • 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.

143

Teilnehmer:innen

1

Projekt

Über diesen Kurs

Möchtest du deinen eigenen actiongeladenen Roguelite-Auto-Kämpfer bauen, auch wenn du neu im Programmieren bist?

Dieser einsteigerfreundliche Kurs führt Sie Schritt für Schritt durch die Erstellung eines kompletten 2D-Spiels – Script Survivors – mit Godot 4 und GDScript, der leistungsstarken und anfängerfreundlichen Skriptsprache von Godot. Ohne Vorkenntnisse im Programmieren oder in der Spieleentwicklung lernen Sie durch die Praxis und bauen von Grund auf einen ausgefeilten Prototypen!

Das wirst du lernen:

  • Kenntnisse der GDScript-Grundlagen und Best Practices: Schreiben Sie sauberen, wiederverwendbaren Code mit korrekten Namenskonventionen (z. B. snake_case), exportieren Sie Variablen für einfache Optimierungen und erstellen Sie selbstdokumentierende Skripte mit Kommentaren zur Wartbarkeit.

  • Entwickeln Sie grundlegende Gameplay-Mechaniken: Implementieren Sie automatisch angreifende Waffen (wie Speere und Sicheln), ein System zur Erzeugung von Gegnern mit anpassbaren Schwierigkeitsgraden, sammeln Sie Erfahrung (EXP) und ein dynamisches Spielerleveling-System mit beeindruckenden Verbesserungen.

  • Nutzen Sie das Szenen- und Knotensystem von Godot: Organisieren Sie Ihr Spiel mithilfe von Szenen für Modularität (z. B. Spieler, Gegner und Weltszenen), Knoten für Spielobjekte (CharacterBody2D, Sprite2D) und Timern für präzise Ereignisplanung.

  • Erstellen Sie ansprechende Kampfsysteme: Entwerfen Sie Gesundheits- und Schadensmechanismen, einschließlich Kollisionsformen für präzise Interaktionen, Unbesiegbarkeitsrahmen und Waffenverbesserungen für mehrere Ziele für ein zufriedenstellendes Gameplay.

  • Hinzufügen von Polnisch mit Benutzeroberfläche und Speichersystemen: Erstellen Sie intuitive Benutzeroberflächen (z. B. High-Score-Anzeigen, Level-Up-Bildschirme) mit Steuerknoten und implementieren Sie ein JSON-basiertes Speicher-/Ladesystem, um die High-Scores für besiegte Feinde und die Überlebenszeit zu verfolgen.

  • Verwenden Sie State Machines für intelligentere Logik: Verwenden Sie das Limbo AI-Plug-in, um Charakter- und Feindverhalten zu verwalten (z. B. Leerlauf-, Lauf-, Angriffszustände), komplexe Logik zu vereinfachen und Sie auf erweiterte KI-Muster vorzubereiten.

  • Anwendung echter Spielentwicklungsmuster: Erlernen Sie übertragbare Fähigkeiten wie Kapselung (z. B. GameManager- und SaveLoad-Skripte), Ressourcenmanagement (z. B. PlayerContext) und Projektorganisation für die Skalierbarkeit auf größere Projekte.

Am Ende dieses Kurses werden Sie über Folgendes verfügen:

  • Erhalte ein vollständig spielbares 2D-Actionspiel mit Feinden, Upgrades und einem Hauptmenü, das du in deinem Portfolio präsentieren kannst.

  • Navigieren Sie sicher im Editor von Godot – vom Projektmanager bis zum Inspektor – und verwenden Sie Tools wie den AnimationPlayer und Atlas-Texturen für pixelgenaue visuelle Elemente

  • Machen Sie sich mit einer starken Grundlage in Godot 4, GDScript und Workflows für die Spieleentwicklung ausgerüstet, um Ihre eigenen Spiele zu erstellen und neue Projekte problemlos anzugehen.

Warum dieser Kurs?

  • Anfängerfreundlich: Beginnt mit den Grundlagen und bietet klare Erklärungen zur Benutzeroberfläche von Godot, der GDScript-Syntax und der Konzepte für die Spielentwicklung, um einen reibungslosen Lernprozess zu gewährleisten.

  • Praktisches Lernen: Erstelle "Script Survivors", einen kompletten Prototyp mit Pixel-Art, Chiptune-Musik und Soundeffekten, der anhand praktischer Beispiele unterstützt wird.

Praxiserfahrungen: Lernen Sie professionelle Techniken wie State Machines, JSON-Serialisierung und modulares Design kennen, um sich auf größere Dev (oder Entwicklungs-) Projekte vorzubereiten.

Stürzen Sie sich jetzt ein und basteln Sie süchtig machende Actionspiele, die die Spieler immer wieder darauf zurückkommen lassen!

Triff deine:n Kursleiter:in

Teacher Profile Image

Chris Tutorials

Game Developer

Kursleiter:in

I believe the best way to learn technology--and programming in particular--is through video-based learning. My role is to provide clear, hands-on video tutorials that guide you step-by-step, but ultimately, it's up to you to engage actively, absorb the concepts, and practice consistently. This approach helps you become a more confident and skilled developer.

I specialize in Godot game development using GDScript and C#, breaking down complex topics into manageable lessons that empower you to build your own projects from the ground up.

If you want to experience my teaching style before enrolling, check out my free tutorials on my YouTube channel, Chris' Tutorials. I look forward to helping you grow as a programmer and creator!

Vollständiges Profil ansehen

Level: All Levels

Kursbewertung

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

Warum lohnt sich eine Mitgliedschaft bei Skillshare?

Nimm an prämierten Skillshare Original-Kursen teil

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

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

Lerne von überall aus

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

Transkripte

1. Einführung in den Kurs: Hallo, alle zusammen, Chris, hier. Und in diesem Video habe ich etwas wirklich Cooles. Ich freue mich darauf, es mit euch allen zu teilen. Es ist mein neuer GidoGame-Entwicklungskurs zur Entwicklung eines Spiels wie bei Survivor Wir haben also eine Menge Inhalt drin. Ich meine, es sind über 60 Lektionen und fast 12 Stunden Video. Es ist mit Abstand der längste und vollständigste Kurs zur Spieleentwicklung, den ich je veröffentlicht habe. Wenn Sie also jemals darüber nachgedacht , Ihr eigenes lustiges Survivors Light-Spiel zu entwickeln , werden wir genau das tun. Wir werden es Schritt für Schritt aufbauen, von Grund auf neu. Wir werden die GidoEngine Version 4.4 verwenden, von der Sie wahrscheinlich bereits wissen , dass sie kostenlos und Open Source ist Also werden wir alles im GD-Skript codieren. Welches ist die Sprache, die speziell für den Gadot-Editor Es ist anfängerfreundlich, leicht zu lesen und eng in die Ado-Engine integriert Es funktioniert also hervorragend, um Spielprototypen wie diesen Egal, ob Sie neu in der Spieleentwicklung sind oder schon ein bisschen programmiert haben und dieser Kurs ist genau das Richtige für Sie Ihre Fähigkeiten mit einem neuen interessanten Projekt festigen möchten, ich denke, dieser Kurs ist genau das Richtige für Wir fangen einfach an und machen uns mit grundlegenden Dingen wie der Charakterbewegung von oben nach unten vertraut mit grundlegenden Dingen wie der Charakterbewegung von oben nach unten Dann werden wir wirklich anfangen, es hochzufahren einige wirklich komplexe Konzepte zu entwickeln Du wirst Charakterstatistiken, Levelsysteme und die Abholung von Gegenständen einbauen . Wir werden sogar ein Spawnsystem einrichten , das all deine Feinde außerhalb des Bildschirms positioniert , sodass sie den Spieler von allen Seiten anschwärmen können Kurz gesagt, wir werden das Godos Two-D-Szenensystem wirklich in die Hand nehmen Das wird alles andere abdecken, von Projektilen bis hin zur Erstellung ausgefeilter Am Ende des Kurses wirst du im Hintergrund einen voll spielbaren Prototyp des Spiels im Stil von Survivors haben einen voll spielbaren Prototyp des Spiels im Stil von Survivors und über all das Wissen verfügen, das du benötigst, um daraus ein größeres Projekt zu machen Also, was sagst du? Bist du bereit, diese Spielideen in etwas Reales umzusetzen? Komm und nimm an dem Kurs teil und lass uns gemeinsam etwas ziemlich Unglaubliches bauen. 2. Godot-Projekt einrichten: Hallo zusammen, Chris hier, in diesem Video beginnen wir mit dem ersten Schritt unseres Survivors Like - und GD Script-Projekts, indem wir die GDOengine herunterladen Falls ihr es noch nicht wisst, Gadot ist eine kostenlose Open-Source-Game-Engine eigenen Hauptsprache, GD Script, die speziell für Gdo geschrieben wurde eine kostenlose Open-Source-Game-Engine mit einer eigenen Hauptsprache, GD Script, die speziell für Gdo geschrieben wurde und die wir für die Programmierung des Kurses verwenden werden Es ist eine Skriptsprache. Sie können natürlich auch andere Sprachen in Gdo verwenden, wie C Sharp, das über eine starke integrierte Unterstützung mit einer Mnoversion von Gudo verfügt Unterstützung mit einer Mnoversion Die meisten Tutorials, die Sie finden, werden in GDScript sein , da GD Script schnell zu erlernen ist Es hat eine wirklich gute Integration mit dem Editor EUI. Es ist einfach zu bedienen und Sie müssen Ihre Skripte nicht jedes Mal kompilieren , wenn Sie Änderungen daran vornehmen möchten Was die Einfachheit angeht, insbesondere für kleine Projekte, hat GD Script viel zu bieten. Wenn ich mir also die Gado-Website ansehe, werde ich die aktuelle Release-Version von Gado 4.4 0.1 verwenden von Gado 4.4 Insbesondere werde ich die Nicht-Mono-Version herunterladen , was bedeutet, dass sie keine C Sharp-Unterstützung bietet, da die Version, die nur GD Script enthält, den Export ins Internet ermöglicht Wenn Sie jedoch Gado Mono verwenden, wird diese Funktion nicht unterstützt Gadot 4.5 ist also bereits in der Pipeline, und es kommen ein paar Funktionen heraus , die ich für ziemlich cool halte Aber weil wir versuchen, diesen Kurs für Anfänger auf mittlerem Niveau zu beschränken, möchte ich niemanden mit all diesen Konzepten überfordern niemanden mit all diesen Also lasst uns weitermachen und auf Herunterladen klicken und 4.4 0.1 holen, und wir wollen die blaue Version hier haben. Es ist nicht Mono. Das wird nur für GD Script sein. Wenn du C Sharp haben wolltest, kannst du.net herunterladen. Das werden wir für diese Version des Projekts nicht benötigen. Ich könnte später eine C Sharp-Version des Kurses erstellen , wenn es Sinn macht. Wir werden sehen, wie es läuft. Also wirst du das speichern wollen, es installieren und dann den GadoEditor öffnen Sobald Sie es geöffnet haben, sollten Sie sich an den Projektmanager wenden , der Ihnen eine Liste Ihrer aktuellen Sie haben hier wahrscheinlich nicht viel. Es könnte ein paar Demos geben. Aber was wir tun wollen, ist unser neues Projekt zu erstellen Lassen Sie uns also ein neues Projekt erstellen, und Sie können diesem einen beliebigen Namen geben. Ich werde es Script Survivors nennen, den subtilen Namen, ich weiß, weil es ein GD-Skript und es ein Survivor-Stil Also werde ich das in mein Tutorial-Verzeichnis aufnehmen, das ich speziell für diese Art von Langform-Tutorials eingerichtet habe das ich speziell für diese Art von Langform-Tutorials eingerichtet diese Art von Langform-Tutorials Lassen Sie uns das also als aktuellen Ordner festlegen, und wir sollten hier so etwas wie den Projektnamen und den Pfad zum vollständigen Projekt sehen . Weil ich Script Survivors A zu einem einzigen Wort gemacht habe, wurde hier kein Trennzeichen eingefügt. Also verwende ich einfach einen Gedankenstrich als Standardtrennzeichen für Leerzeichen. Und wir werden den Renderer im mobilen Modus haben wollen. Dies ist ein Pixelkunst-Kurs, also brauchen wir den Ford-Renderer wirklich aus keinem Grund, und wir werden einfach weitermachen und damit kreativ Sobald Ihr Projekt gestartet ist, sollten Sie hier den Three-D-Viewport sehen Eines der coolen Dinge an Gadot ist, dass es zwei völlig separate Workflows für zwei D und drei D hat , aber es unterstützt beide Im Gegensatz zu Unity sind sie völlig separate Einheiten. Es handelt sich also nicht darum, zwei D in einem Drei-D-System vorzutäuschen. Es sind tatsächlich zwei D. Und wenn Sie in diesem Szenenfenster auf der linken Seite nachschauen, werden Sie sehen, dass es hier wirklich vier Arten von Knoten gibt , zwei D-Szenen, drei D-Szenen, Benutzeroberfläche Und wenn wir dann auf einen anderen Knoten klicken, gibt es hier den Knoten der Basisklasse , der keine 2D3D-Komponenten enthält Es ist also nirgends eine Position, du würdest es für Dinge wie Systeme, die Verarbeitung von Hintergrundinformationen verwenden , nicht für Objekte in der Spielwelt Für alles, was sich in der Spielwelt , werden wir generell eine Zwei-D-Szene verwenden. Das wird hier also ein blaues Knotensymbol sein , genau wie der Unterschied. Und dann sind die Benutzeroberflächen die Kontrollknoten. Das ist grün markiert, alles, was eine Schaltfläche auf dem Bildschirm, schwebender Kampftext, Popup-Fenster auf der Benutzeroberfläche sein könnte , Beispiel wenn wir Belohnungen für das auswählen was du für einen Levelaufstieg bekommen kannst Das sind alles Benutzeroberflächenknoten. Also werde ich im Laufe der Zeit natürlich mehr darüber erklären, was ein Knoten eigentlich ist. Lassen Sie uns zunächst etwas ausführlicher auf die Oberfläche eingehen. Wir haben also das Dateisystem in der unteren linken Ecke. Dort werden Sie all Ihre Dateien in Gdo haben , einschließlich aller importierten Assets, Ihrer SEN-Dateien , wo Sie einen oder mehrere Knoten nehmen und diese in einer Szene speichern , von der Sie überall in Ihrem Spiel Kopien erstellen können Es ist also im Grunde eine Vorlage, die Sie wiederverwenden können. Und dann auch andere Gdo - und Nicht-Gudo-Dateien wie Ressourcen Also im Viewport hier haben Sie hier Ihren X, Y-Zugriff. Ein Unterscheidungspunkt nach unten ist eigentlich die positive Richtung der Y-Achse Wenn Sie also von einer Bewegung nach oben sprechen, möchten Sie einen negativen Y-Wert haben, und wenn Sie sich auf dem Bildschirm nach unten bewegen möchten, sprechen Sie von einem positiven Y-Wert Rechts ist positiv X und links ist negativ X. Das wird also wirklich relevant sein, wenn wir unsere Charaktere auf dem Bildschirm bewegen. Du solltest sicherstellen, dass sie sich in die richtige Richtung bewegen und dass du auch die Eingabe für die richtige Richtung erhältst. Wenn Sie sich den Punkt mit 1.200 Pixeln genau ansehen, werden Sie zumindest bei mir die Grenzen unserer Benutzeroberfläche erkennen Die Benutzeroberfläche befindet sich also normalerweise auf einer eigenen, separaten Canvas-Ebene Es ist also eine völlig andere Sache die Two-D-Spielwelt selbst. Man könnte sich die Benutzeroberfläche so vorstellen , dass sie quasi über der Kamera liegt, während sie die Two-D-Welt betrachtet. Wenn sich also die Kamera bewegt, bewegen sich auch alle UI-Elemente. Aber die Objekte der Spielwelt bewegen sich im Allgemeinen nicht mit der Kamera. Wenn du also die Kamera bewegst, bleibt die Benutzeroberfläche an ihrem Platz und alles, was sich darunter befindet, die Charaktere, die Feinde, die bewegen sich nicht mit der Kamera. Und das ist einer der größten Unterscheidungsfaktoren zwischen den beiden D-Knoten und den Kontrollknoten der Benutzeroberfläche Alles, was ein UI-Element ist, ist ein Kontrollknoten in Gadot. Auf der rechten Seite haben wir den Inspektor , mit dem alle Eigenschaften Ihrer Knoten definiert werden alle Eigenschaften Ihrer Knoten Wenn Sie Skripte schreiben, können Sie ihnen ein AT-Export-Tag geben, das sie innerhalb des Inspektors als editierbar kennzeichnet innerhalb des Inspektors als editierbar Das ist wirklich wichtig. Davon werden wir eine Menge machen. Also wirst du das hier bearbeiten. Natürlich gibt es auch andere Fenster , die unterschiedliche Bedeutung haben. Ich werde diese auch in den späteren Videos behandeln. Im nächsten Video werden wir uns also mit unserem Projekt befassen. Wir importieren alle benötigten Kunstobjekte, einschließlich Audio, Musik, Kunst und Schriften. Und dann gibt es noch ein paar Plugins, die meiner Meinung nach für das Projekt äußerst nützlich wären kostenlos heruntergeladen und verwendet werden. Also werden wir das alles im zweiten Video behandeln. 3. Grafik, Sound und Plugins ~ Importieren und Installieren: In diesem Video werden wir also mit der Einrichtung unseres Projekts fortfahren, indem wir alle Ressourcen, Audio- und Plug-ins in die Projekte integrieren, sodass wir mit der Arbeit beginnen können. Also drüben auf PaysPN habe ich alle Links zu den Ressourcen, die wir für den Kurs benötigen, alles, was ich in dem Pre-Recording-Projekt für Drehbuchüberlebende verwendet habe für Drehbuchüberlebende Wenn du also dem Link hier oben folgst , werde ich ihn vergrößern Sie können im Grunde einfach zu jedem dieser Links gehen und benötigen nur die kostenlosen Versionen der einzelnen Assets. Ich muss es auf diese Weise teilen, um die Regel zu respektieren, die für viele dieser Assets gilt, dass es keine Weiterverbreitung gibt, aber du musst im Grunde nur den Links zu den einzelnen Shop-Seiten folgen und dir die kostenlose Version holen Zunächst einmal hat Pixel Crawler unser charakterbasiertes Modell, mit dem wir einige Waffen und Feinde einrichten Es ist wirklich der Kern dieses Tutorials, also ist es das, worauf wir einen Großteil der Alpha basieren Also als nächstes die Fantasy-Ikonen von Raven. Für UI-Elemente, Crimson Fantasy-Benutzeroberfläche. Die Schriftart werde ich m5x7 verwenden. Aber ehrlich gesagt können Sie einfach die Pixel-Art-Schriftart auswählen, die Ihrer Meinung nach gut aussieht Es gibt auch viel auf Itch Dot IO. Für einige grundlegende Soundeffekte im Spiel gibt Leo RPG Essentials SFX Und was die Musik angeht, The Red Hearts Prepared to Dev von Tall Beard ist absolut perfekte Chiptune-Musik für den Stil des Survivors Light-Spiels Es funktioniert tatsächlich sehr, sehr gut. Okay, Sie laden also alle ZIP-Dateien und können dann rechten Maustaste in das Dateisystem klicken einen neuen Ordner für Kunst erstellen. Ich werde das gesamte Bildmaterial hier reinstellen. Und dann klicken Sie mit der rechten Maustaste, erstellen Sie einen neuen Ordner für Audio, alles, was unter Soundeffekte oder Musik steht , werde ich dort einfügen Und um es dann schnell in Windows File Explorer oder ähnlichem zu öffnen, wenn Sie Mac oder Linux verwenden, klicken Sie mit der rechten Maustaste und wählen Sie Öffnen und Dateimanager. Okay. Und dann willst du einfach alle Dateien in diesen Kunstordner extrahieren. Hier haben wir also die Crimson Fantasy-GUI, wir haben die Fantasy-Icons und dann das kostenlose Pixel-Crawler-Paket Die einzige Ausnahme ist, dass es für die Fantasy-Icons etwa drei oder vier verschiedene Versionen davon gibt Ich habe gerade die kompletten Spritesheets benutzt. Diese sind in Gadot am einfachsten zu bearbeiten, da Sie eine Atlas-Texturressource erstellen und dann einfach das Symbol auswählen können, das Sie dafür auswählen möchten Für jedes der Elemente, denen Sie ein Symbol zuweisen werden, finde ich es einfach viel einfacher, auf diese Weise zu arbeiten Und auch bei Gadot dauert es sehr lange, bis es tatsächlich in die Engine geladen wird, wenn jedes Symbol separat importiert wird, was bei diesem Paket eine Option wird, was bei diesem Paket eine tatsächlich in die Engine geladen Wenn Sie also Ihre Bilder in eine Datei wie diese gepackt haben , ist das einfach viel effizienter Ich denke, das ist der richtige Weg. Abgesehen davon glaube ich, dass ich gerade das gesamte Verzeichnis reingebracht habe. Ich ändere nicht die Dateinamen oder ähnliches. Normalerweise würden Sie in Gadot Schlangenbuchstaben für Ihre Verzeichnisordnernamen verwenden, aber ich denke, es ist einfach am einfachsten, einfach das zu verwenden, was die Künstler hier zur Verfügung gestellt haben, und einfach damit weiterzumachen Es sollte also keine Probleme oder ähnliches verursachen. Nur vielleicht ein bisschen optimiert, aber das ist völlig in Ordnung. Und dann für den Ton der Soundeffekte, wenn du den Reißverschluss öffnest, kommen wir einfach so. Und die Musik, ich habe nur die drei Red Hearts Box Jump gemacht, das ist der erste Musiktitel Du kannst eigentlich einfach den Musiktitel auswählen , den du für dein Spiellevel verwenden möchtest, aber ich finde, dieser funktioniert wirklich, wirklich gut Weißt du, lass uns einfach weitermachen und für eine Minute eine Vorschau ansehen. Ja, also absoluter Killertrack für Spiele im Survivor-Stil, finde ich Also, sobald Sie alles importiert haben, fügen Sie es in Ihre Dateien ein. Wenn Sie das Gado-Fenster erneut öffnen, sollten Sie sehen, dass alles ordnungsgemäß in diese Ordner importiert wurde, und dann sollte es hier auf der linken Seite angezeigt Daher erhalten Sie möglicherweise einige Fehlermeldungen, wenn Sie Dinge zum ersten Mal importieren Sie können einfach bestätigen, dass die Dateien da sind, und das ist hier das Wichtigste. Ich denke, diese Nachrichten können irgendwie ignoriert werden. Drop Stable hat nicht einmal etwas mit diesem Projekt zu tun Es könnte mit dem Caching auf meinem Computer zusammenhängen. Aber was wichtig ist, ist, dass wir die Dateien hier haben . Sie können auf sie doppelklicken. Sie können sehen, dass es erkannt wird, wie die Musik dort und die Soundeffekte hier. Es sieht also so aus, als ob es uns gut geht. Also mach weiter und lösche das Logo. Also brauchen wir zwei Plugins für den Kurs. Erstens, ich denke, es ist einfach eine enorme Lebensqualität , wenn man hier durch das Dateisystem navigiert Es heißt Ordner zusammenklappen, weil Sie vielleicht feststellen, dass es beim Öffnen einer Reihe von Ordnern wie diesem wirklich nicht einfach ist, es beim Öffnen einer Reihe von Ordnern wie diesem wirklich nicht einfach ist sie alle zu reduzieren oder wieder zusammenzuklappen , sodass Sie Ihr gesamtes Dateisystem hier in einem Fenster sehen können Ihr gesamtes Dateisystem hier in einem Fenster Sie möchten also zur Asset Lib hier oben gehen und dann nach Collapse suchen. Klicken Sie also auf die Suchleiste und geben Sie Collapse ein. Und dann wollen wir hier Ordner zusammenklappen. Also lade das herunter. Installiere es Okay, ich sage, erfolgreich installiert. Jetzt wollen wir oben links zu Project, zu den Projekteinstellungen gehen und hier zum Plugins-Tab gehen. Wählen Sie aktiviert aus und klicken Sie auf Schließen. Und das macht dieses kleine Symbol hier drüben, mit dem Sie alles zusammenklappen können, und Sie können alle Ordner haben zum Stammverzeichnis zurückkehren. Nichts ist erweitert und es ist viel einfacher, damit im Dateisystem zu navigieren. Ich denke, das ist einfach ein wirklich praktischer Button. Es sollte in Gadot Basic sein, ehrlich gesagt. Das andere ist also ein viel aufwändigeres Plug-In, und wir werden es für Zustandsmaschinen in Gadot verwenden . Es wird auch für Verhaltensbäume verwendet, aber weil die KI sehr einfach und ein Survivor-Spiel ist, werden wir hier nur bei Zustandsmaschinen bleiben Es ist nicht nötig, es mit einem Verhaltensbaum komplexer zu machen mit einem Verhaltensbaum komplexer Wir suchen also nach Limbo AI, und weil ich in 4.4 bin, werde ich natürlich Limbo AI 4.4 verwenden Möglicherweise stellen Sie fest, dass es derzeit zumindest noch keine Version 4.5 gibt, weil, naja, ich meine, 4.5 noch in Dev ist . Es kann also funktionieren, wenn Sie sich für die Dv-Version entscheiden oder Sie könnten auf einige Probleme stoßen Es wird wahrscheinlich funktionieren, aber weißt du, es könnte hier oder da ein Bug sein Also, weißt du, ein weiterer Grund, bei der stabilen Version von Gado zu bleiben Also lasst uns das herunterladen und das wird unser State Machine-Plug-In sein . Wir können es installieren. Es wird etwas länger dauern, weil das ein ziemlich großes Plug-In ist. Ich werde diese Nachrichten erneut ignorieren. Das könnte tatsächlich passieren weil der Projektname derselbe ist, obwohl das Verzeichnis anders ist, also ändere ich einfach den Projektnamen, damit das Zeug nicht mehr angezeigt Hoffentlich wird das behoben. Also ändere ich einfach den Namen und gebe ihm dort den Namen GD-Skript. Ist es ein zusätzliches Etikett? Lassen Sie uns schließen, dass ich die Nachrichten lösche und das Projekt einfach neu lade, solange ich im Voraus bin und ich werde einfach sehen, ob es Probleme gibt wenn ich das Projekt neu lade Nein, okay, es scheint gut zu sein. Okay. Wenn wir also die Projekteinstellungen überprüfen und du zu Plugins gehst, wirst du feststellen, dass Limbo AI hier nicht angezeigt Limbo AI ist eigentlich in C plus Plus geschrieben, das könnte der Grund sein, warum es nicht speziell als Cado-Plug-In angezeigt wird Ich kann mir vorstellen , dass er das getan hat, um die Code-Effizienz zu maximieren , da CplusPlus schneller ist als C Sharp Aber ja, so ist es einfach. Um zu bestätigen, dass Limbo AI funktioniert, können wir hier oben links einfach schnell eine neue TD-Szene erstellen hier oben links einfach schnell eine neue TD-Szene Und dann klicken Sie hier mit der rechten Maustaste auf den Wurzelknoten, den Knoten zwei D, fügen Sie einen untergeordneten Knoten und suchen Sie einfach nach State Sie sollten den Limbo-Status und den BT-Status sehen. Solange du diese Klassen von Limbo AI siehst, weißt du , dass das Plugin korrekt installiert ist Um es noch einmal zusammenzufassen: Wir sollten hier ein Audio unserer Soundeffekte über fünf Ordner haben , mindestens eine Audiospur Und die Grafik, wir sollten Crimson Fantasy GUI haben , Raven Fantasy-Symbole, und ich nehme nur den kompletten Spritesheet-Ordner und dann Pixel Crawler für unseren Hauptcharakter, unsere Hintergrund-Requisiten und Feinde, quasi das wichtigste Grafik-Asset für die Kursreihe Und dann eine Schrift. Also habe ich m5x7 als Punkt-TTF-Schrift mitgebracht. Ich denke, andere Typen könnten auch funktionieren, aber aus Konsistenzgründen ist es wahrscheinlich am besten, einfach bei demselben zu bleiben demselben zu Und dann haben wir Add-Ons, Collape-Ordner und Limbo AIA Das sollten also alle externen Dateien sein, die wir für diesen Kurs mitbringen müssen Alles andere werden GD-Skripte sein, die wir schreiben, oder Szenen, die wir einrichten, oder andere Gadot-Dateien, die wir ebenfalls erstellen, wie Ressourcen, die in einer Datei gespeichert werden können Das wird es also für dieses Video sein. Als Nächstes beginnen wir damit, unseren Spielcharakter mit zwei D von oben nach unten zu erstellen und dem Charakter einige grundlegende Bewegungssteuerungen hinzuzufügen, damit er sich auf dem Bildschirm bewegen kann. 4. Spielerbewegung von oben nach unten: In diesem Tutorial werden wir also die Charakterbewegung von oben nach unten für unsere Hauptspieler-Charakterszene implementieren Charakterbewegung von oben nach unten für unsere Hauptspieler-Charakterszene Aber bevor wir darauf eingehen, möchte ich darauf hinweisen, dass wir den Demo-Ordner aus Limbo AI löschen können den Demo-Ordner aus Limbo AI löschen , der automatisch mit dem Plug-In importiert wird . Wenn du die Demo durchgehen oder sie dort behalten möchtest, kannst du das gerne tun Dies beinhaltet Beispiele zur Verwendung von Limbo AI, aber ich werde dir diese Schritte speziell für die State Machine auf Video zeigen diese Schritte speziell für die State Machine Das brauchen wir also nicht wirklich für unser Projekt. Ich werde das entfernen. Okay, und jetzt können wir loslegen. Wir wollen also mit einer Zwei-D-Szene in der oberen linken Ecke beginnen , also werde ich auf Root-Node-Zwei-D-Szene erstellen klicken. Das wird uns also einen Basisknoten zwei D geben. Nun, die Wurzel unseres Charakters, im Allgemeinen, wollen wir einen Charakterkörper zwei D sein, was ein Typ von Knoten zwei D ist. Also können wir mit der rechten Maustaste auf unseren Knoten zwei D klicken und Typ ändern, und dann geben wir Charakter ein. Wir finden den zweiten Charakter D. Beachten Sie, dass aus der Physik den zweiten Körper D erbt , der ein Kollisionsobjekt ist Welches ist ein Typ von Knoten zwei D. Es gibt also eine ganze Reihe von Klassen oder Objekttypen, von denen der Charakterkörper erbt, und er erhält alle Eigenschaften aller Klassen, die ihm vorausgegangen sind Das bedeutet also, dass alles, was ein Physikkörper zwei D kann, auch ein Charakterkörper zwei D tun kann Also drücken wir hier auf Wechsel zu Körper zwei D. Sobald Sie das tun, erscheint dieses kleine gelbe Dreieck, das darauf hinweist, dass das Kollisionsobjekt keine Form hat. Also müssen wir mit der rechten Maustaste klicken und einen untergeordneten Knoten hinzufügen , der eine Kollisionsform zwei D sein wird, und ich zoome hier einfach auf die Mitte 0,00 heran. Du wirst noch nichts sehen, weil wir noch kein Sprite hinzugefügt Aber lassen Sie uns damit beginnen, auf Form und den Inspektor auf der rechten Seite zu klicken und eine neue Kreisform zu Also kommen wir vielleicht zurück, um das zu bearbeiten und seine Größe zu reduzieren, aber zuerst brauchen wir das Sprite , um wirklich zu sehen, womit wir arbeiten Nehmen wir also den Wurzelknoten und benennen ihn um, indem wir F zwei drücken Und ich nenne es einfach Player. Du könntest es auch Spielercharakter oder Spielercharakterkörper 2 D nennen , was auch immer für dich Sinn macht. Und dann speichern wir diese Szene, die im Grunde die Rootszene und alle untergeordneten Knoten ist , in einer Datei, einer Punkt-TACN-Szenendatei in unserem Projekt Wenn wir also Strg S drücken, um zu speichern, dann in die obere rechte Ecke klicken, um einen neuen Ordner zu erstellen Und geben wir ihm einen Namen. Ich mache Buchstaben, ich mache Kleinbuchstaben, was normalerweise der Standardname von Gadol ist, Snake Case Also, wenn du Leerzeichen brauchst, würdest du Unterstriche und dann so etwas hinzufügen Also lass uns Charaktere machen. Und dann erstelle ich bei Charakteren einen Ordner für den Spieler, nur weil ich im Voraus weiß, es eine Reihe von Skripten geben wird, und dann können wir sie alle in demselben Unterverzeichnis kombinieren demselben Unterverzeichnis Also werde ich einen neuen Ordner erstellen. Spieler. Und sagen wir okay. Wir haben also Player Dot TSC und wir werden das in diesem Verzeichnis oder Ordner speichern Also speichere die Szene dort. In Godot besteht Ihr Projekt also im Wesentlichen aus Szenen innerhalb von Szenen Möglicherweise haben Sie also eine Haupt-Gameplay-Szene. Wir haben das gesamte System-Setup, und darunter könntest du die Spielweltszene laden, das ist die 2-D-Karte und die Objekte, die sich bevölkern sollen , und innerhalb dieser 2-D-Welt hättest du natürlich deine Spielerszene, die Szenen für deine Feinde, deine Orks, deine Skelette usw. Wenn Ihre Szene also in einer Datei gespeichert wird, ist es wirklich einfach, dies zu instanziieren, da im Grunde genommen die gespeicherten Daten genommen und eine Kopie davon geladen und in Ihre Szene eingefügt werden. Also wirklich schnell, ich könnte das tatsächlich demonstrieren. Wenn wir auf diese neue Registerkarte klicken, erstellen wir eine neue Szenenschaltfläche. Wir können hier eine neue Zwei-D-Szene hinzufügen. Nennen wir das die Welt. Also drücke ich F zwei, um es umzubenennen, und das wird einfach Welt sein. Wir können es als Standardknoten zwei D beibehalten. Wir brauchen eigentlich nichts anderes als eine Position auf dem Bildschirm. Drücken wir also Strg S, um diese Szene zu speichern. Ich gehe zum Stammverzeichnis und wir können World Dot TSN einfach hier drin speichern Okay, jetzt wollen wir der Welt eine Kopie unseres Players hinzufügen Welt eine Kopie unseres Players Wir können also einfach die Spielerszene in die Welthierarchie im Szenen-Tab oben links ziehen in die Welthierarchie . Also ziehst du den Spielerpunkt TSN einfach hierher unter Welt. Und jetzt gibt es eine Kopie des Spielers in der Spielwelt Du weißt also, dass es da ist, weil du mit der Maus darüber fahren kannst. Ich sage hier Spieler. Ihr seht das Symbol für den zweiten Körper von Charakter D und ihr könnt die Kollisionsform sehen, die wir definiert haben. Also, es gibt noch kein Sprite. Das fügen wir sofort hinzu. Also klicke ich auf Kontrolliere uns, um die Welt zu retten. Wir gehen rüber zum Spieler. Ich klicke mit der rechten Maustaste auf Player und füge einen untergeordneten Knoten hinzu, nach dem wir nach einem Sprite suchen Also Sprite zwei D. Es gibt auch einen animierten Sprite-Two-D-Knoten, und beide können so ziemlich für die gleichen Zwecke verwendet werden Sie haben die Dinge ein bisschen anders eingerichtet. Ich würde sagen, für Spielercharaktere ist es tatsächlich einfacher, mit Sprite Two D zu arbeiten und dann die Eigenschaften zu definieren, die Sie für die Animation auf dem Animationsplayer benötigen Animation auf dem Animationsplayer nächsten Video werden wir uns näher mit der Animation eines Sprites befassen Fügen wir also einen Sprite-Zwei-D-Knoten hinzu. Und im Moment wollen wir eine Textur laden Wenn wir hier die Textur laden , werden wir kein einziges Sprite-Bild festlegen Wir werden tatsächlich ein Spritesheet einrichten. Also holen wir uns unser Spritesheet aus dem Kunstverzeichnis. Im Pixel-Crawler-Paket haben wir, glaube ich, Entitäten, Charaktere, Körper A und Animationen Also fangen wir einfach mit dem Idol an. Also für diesen Charakter bekommst du ein Spritesheet mit einer Kehrseite und einer nach oben Wenn du zwei D-Spiele von oben nach unten machst, kannst du das Spritesheet an der Seite einfach umdrehen Von links nach rechts, was bedeutet, dass Sie kein viertes Spritesheet für links und rechts erstellen müssen viertes Spritesheet für links und , da Sie dasselbe Spritesheet einfach wiederverwenden können, und es funktioniert genauso Es spart Ihnen eine Menge Zeit, es auf diese Weise zu animieren. Wir wollen also, dass Idle herunterfährt, damit wir den Charakter, den wir gerade betrachten, tatsächlich sehen können den Charakter, den wir gerade betrachten, tatsächlich sehen Also laden wir das hier rein. Also das ist ein Basis-Charakter-Sprite. Die Idee hier ist also, dass Sie Kleidung als zusätzliches Sprite hinzufügen und alle Anpassungen daran vornehmen könnten, aber die Animationen im Kern bleiben dieselben, da Sie den endgültigen Charakter für grundsätzlich unterschiedliche Stile und Looks entwickeln würden für grundsätzlich unterschiedliche Stile Okay, also ein paar Dinge fallen wahrscheinlich auf. Zunächst einmal hat der Charakter offensichtlich keine Kleidung. Das ist also ein Basis-Charakter-Sprite. Die Idee ist, dass Sie zusätzliche Kleidungs-Sprites nehmen und diese zusätzlich zu Ihrer Basisanimation für den endgültigen Charakter hinzufügen würden zusätzliche Kleidungs-Sprites nehmen und diese zusätzlich zu Ihrer Basisanimation für den endgültigen Charakter hinzufügen , vielleicht so etwas wie einen Zaubererhut oder Und die Idee ist, dass du Sprites austauschen kannst , um deinen endgültigen Charakter fertigzustellen Aber für die Basisanimationen sind sie hier im kostenlosen Paket enthalten, und du würdest sie einfach von dort aus aufbauen Also werden wir nur für das Tutorial damit arbeiten. Die anderen beiden offensichtlichen Probleme sind, naja, erstens, wir haben vier Kopien des Charakters, die gleichzeitig auf dem Bildschirm angezeigt werden. Also wollen wir dafür sorgen, dass nur einer erscheint. Und das machen wir, indem wir hier zum Animations-Tab wechseln und die H-Frames auf die Anzahl der Sprites ändern, die in diesem horizontalen Spritesheet angezeigt werden Also ändere ich einfach H-Frames auf vier. Und jetzt wird nur die Nullposition des Frames angezeigt, das ist das erste Sprite in dieser Leerlaufanimation Das dritte Problem ist , dass es für die Pixelgrafiken sehr verschwommen Wir können das also in unserem gesamten Projekt beheben , indem wir zu den Projekteinstellungen gehen , und wir möchten nach unten scrollen, bis wir, glaube ich, es ist Renderer Nein, Texturen. Das Rendern und dann die Textur, der Standard-Texturfilter hier linear , ist also besser geeignet, wenn Sie, glaube ich, Dinge wie Vektorgrafiken machen glaube ich, Dinge wie Vektorgrafiken Aber bei Pixelgrafiken, die pixelgenau sein müssen, sollten Sie den Wert auf „ Am nächsten“ ändern. Und sobald Sie das getan haben, wird im Grunde jedes Pixel scharf gerendert angezeigt, wie Sie es jedes Pixel scharf gerendert angezeigt, von einem Pixel-Art-Spiel erwarten würden Und so ziemlich für das Projekt ist das alles, was Sie tun müssen, um es für ein bestimmtes Pixel-Art-Format einzurichten für ein bestimmtes Pixel-Art-Format Nun, der Charakter und die Kollisionsform sind hier gerade etwas seltsam. Im Allgemeinen möchten Sie bei Top-Down-Spielen, dass die Kollisionsform irgendwo um die Füße des Charakters herum liegt. Deshalb möchte ich, dass meine Szenen immer noch auf 00 zentriert sind, damit ich im Grunde die genaue Position kenne , an der der Charakter in der Spielwelt dargestellt wird in der Spielwelt dargestellt und der Offset wäre nicht seltsam oder so. Was wir hier also eigentlich machen wollen, ist Offset, nicht die Basisszene. Wir wollen das bei Null, Null belassen , aber beim Sprite-Knoten Wenn du also das Sprite Two D auswählst und W drückst, um in den Bewegungsmodus zu wechseln, kannst du mit der linken Maustaste klicken und es gedrückt halten und nach oben ziehen Wenn du es irgendwie an der Y-Achse ausrichten möchtest , kannst du die Umschalttaste gedrückt halten, wodurch du verhindern kannst, dass es nach links geht, es sei denn, du gehst wirklich weit Und wir wollen das nur so lange ziehen, bis die Füße des Charakters im Grunde genau da sind. Und dann wollen wir, dass die Kollisionsform den Fußbereich des Charakters darstellt, weil der Charakter dort mit anderen Objekten kollidieren darf mit anderen Objekten kollidieren Es macht also Sinn , dass die Position dort wäre, wo die Charaktere tatsächlich in der Two-D-Spielwelt stehen Ähm, sich an die Perspektive von zwei D zu gewöhnen , ist ein bisschen gewöhnungsbedürftig, weil sie ein bisschen weniger offensichtlich ist, schätze ich, als an drei D, wo einfach eher wie im echten Leben wäre. Hier müssen wir nur die Illusion erwecken, dass unsere Charaktere tatsächlich genau dort stehen, obwohl der Charakter von hier nach hier geht, das ist der Bereich, in dem der Charakter tatsächlich steht Also können wir das dort speichern. Das sollte gut sein. Nur als Referenz, das waren 4,12 Pixel Ich werde das eigentlich einfach auf vier runden, nur als kleine Präferenz, um zu versuchen, alles auf pixelgenaue Größen zu beschränken Für ein Pix-Art-Spiel wird es wahrscheinlich keine große Sache sein und irgendwelche Probleme bereiten, aber, du weißt schon, nur für den Fall Wenn wir jetzt zurück zu unserer Weltszene klicken, werden wir sehen, dass unser Charakter tatsächlich in der Spielwelt steht Und wenn wir die Welt spielen wollen, würden wir die Play-Taste hier drüben drücken, die die aktuelle Szene der Welt abspielt. Und wir werden den sehr, sehr kleinen Charakter in der oberen linken Ecke sehen können . Es ist eigentlich fast unmöglich, das zu sehen. Das nächste, was wir wahrscheinlich wollen, ist eine Kamera hinzuzufügen. Also klicken wir mit der rechten Maustaste auf die Welt, fügen einen untergeordneten Knoten hinzu, machen wir eine Kamera zwei D. Und obwohl die Welt automatisch eine Standardkamera erstellt, auch wenn Sie keinen Kameraknoten hinzugefügt haben, Sie, wenn Sie eine Kamera richtig können Sie, wenn Sie eine Kamera richtig definieren, den Zoom einstellen, was für Pixart sehr praktisch ist , weil wir über die Arbeit mit 48 mal 32 Pixel-Zeichen sprechen, etwas Also wollen wir den Zoom nehmen und das wahrscheinlich auf etwa drei oder vier erhöhen, bis wir die Kamera sehen können D ist jetzt auch auf dem Nullpunkt zentriert, anstatt hier eher diese Standard-Leinwandbox zu sein Wir können tatsächlich sehen, dass die Kamera diese rosafarbene Linie ist. Und wenn wir die Szene jetzt laufen lassen, sollte unser Charakter zentriert und viel größer und sichtbarer sein. Also, wenn du willst, kannst du das auf eine Vier erhöhen. Ich denke, drei sind vorerst ziemlich gut. Ich ändere es später , wenn wir müssen. Aber solange du den Charakter sehen kannst , denke ich, dass es dir gut geht. Eine weitere Sache, wenn wir das Spiel spielen. Ich glaube, ich möchte, dass das viel sichtbarer ist. Also lasst uns jetzt das Fenster vergrößern, damit wir für eine größere Bildschirmgröße designen können , sodass ihr, wisst ihr, wenn wir unsere Vorschauen machen, besser sehen könnt, was vor sich geht Gehen wir also zu den Projekteinstellungen und ich nehme die Fensteranzeige und ändere sie in etwas viel Größeres Also ich denke, so etwas wie 1980 von 180 wäre gut. Ich meine, das hängt davon ab, wie hoch Ihre Auflösung für Ihren Bildschirm ist. Für mich wird das ungefähr so sein. Okay, ich werde es von meinem Bildschirm aus versuchen. Ich arbeite hier an einem ziemlich großen, extra weißen Monitor, also ein bisschen Versuch bei Irrtum. Ich denke, das wird gut funktionieren, denn dann kann ich hier immer noch den Uh-Of-Knopf sehen. Also Hauptszene abspielen, Pause machen und aktuell laufende Projekt-Buttons beenden, übrigens. Ich würde sagen, solange du das sehen kannst , ist das in Ordnung. Also mit unserem Spiel Canvas, so groß, möchte ich wahrscheinlich auch den Zoom erhöhen. Du kannst die Eigenschaften tatsächlich bearbeiten , während die Spiele laufen. Also kann ich einfach diesen Zoom nehmen und ihn auf vier ändern. Tippen wir wieder hinein und Sie können sehen, dass die Größe sofort aktualisiert wurde. Also, wenn das groß genug für dich ist, kannst du es behalten oder wir können es bis zu fünf machen. Weißt du, vielleicht mache ich da tatsächlich einen 5,0-Zoom. Im Moment habt ihr tatsächlich darauf gewartet. Kommen wir zum eigentlichen Code. Also müssen wir ein Skript erstellen, das Körper des Charakters um D erweitert und das an den Spieler anhängt. Wir können das alles auf einmal erledigen, indem wir auf die linke Maustaste des Spielers klicken und dann einfach auf „ Ein neues oder vorhandenes Skript an den ausgewählten Knoten anhängen “ klicken. Und wir werden das einfach das Player Dot GD-Skript nennen . Und wir werden das Template Body Two D Basic Movement Script eigentlich nicht verwenden . Das heißt, ähm, wenn ich mich an mehr für Plattformer erinnere , weil es Sprünge hinzufügt und ehrlich gesagt, wir können es viel besser schreiben wir also auf Create und das bringt uns direkt in den Skript-Editor. Für den Moment behalte ich es einfach als eingebetteten Skript-Editor. Sie können aber auch hier auf diese Schaltfläche klicken und sie schweben lassen, wenn Sie mit dem Skript-Editor in den Vollbildmodus wechseln möchten . Das kann praktisch sein, wenn Sie kann praktisch sein, wenn Sie sich wirklich mit GD-Script-Codierung beschäftigen. Aber hier wird dieses Skript ziemlich schnell und einfach sein, also nicht wirklich nötig. Gehen wir also nach oben. Okay, wir können also sehen, dass unser Skript den Hauptteil von Charakter zwei D erweitert . Das bedeutet , dass unser Skript die Basisklasse von Zeichenkörper zwei D hat. Okay, wenn wir den Mauszeiger über den erweiterten Zeichenkörper zwei D bewegen, können Sie sehen, wie die Klassenhierarchie hier von Körper zwei D bis hin zu einem Gadot-Basisobjekt reicht können Sie sehen, wie die Klassenhierarchie hier von Körper zwei D bis hin zu einem Gadot-Basisobjekt Das bedeutet nur, dass alles, was unterwegs ist, die Fähigkeiten jeder dieser verschiedenen Klassen erbt jeder dieser verschiedenen Klassen Ein Charakterkörper TD kann also tatsächlich viel bewirken. Wir werden wirklich nur ein bisschen davon brauchen. Denken Sie also daran, dass alles, was dort aufgeführt ist, jede dieser Klassen, denen Sie springen können, indem Sie auf ihre Namen klicken, wenn Sie mehr über sie lesen möchten zu denen Sie springen können, indem Sie auf ihre Namen klicken, wenn Sie mehr über sie lesen möchten , auch Charakter Body Two D kann. Das alles durchzulesen wäre im Moment eine Menge Dokumentation, über die man gut Bescheid wissen sollte. Es ist gut, im weiteren Verlauf nachzulesen, aber im Moment etwas überwältigend . Also lass uns an unserem Kurs arbeiten. Wir möchten ihr einen Klassennamen geben, damit dieses Skript von anderen Skripten aus leicht anhand des Namens referenziert werden kann von anderen Skripten aus leicht anhand des Namens referenziert werden , indem wir zum Anfang der Zeile gehen. Und dann Enter drücken. Gehen wir zur ersten Zeile und geben den Klassennamen Player ein. Und jetzt haben wir dieses Skript als das Spielerskript definiert. Das ist also im Grunde ein globales Symbol wir jetzt in unserem Projekt nachschlagen und verwenden können , indem wir einfach auf Spieler verweisen , die genau so eingegeben wurden, mit Großschreibung Ihr werdet im weiteren Verlauf des Kurses sehen, dass das extrem nützlich ist, besonders für so etwas wie ein Spielerskript, auf das viele andere Klassen noch eingehen dass das extrem nützlich ist, besonders für so etwas wie ein Spielerskript, das viele andere Klassen müssen Lasst uns also an der physikalischen Prozessfunktion für den Charakter arbeiten . Geben wir also FU NC für die Funktion ein und dann den Unterstrich. Und Sie werden sehen, dass dieses Menü automatisch mit den Methoden gefüllt wird, die innerhalb der übergeordneten Klassen definiert sind innerhalb der übergeordneten Klassen definiert Dies sind im Grunde Funktionen, die wir überschreiben und Code hinzufügen können überschreiben und Code hinzufügen , sodass er tatsächlich etwas tut oder ändert, was die Basisklasse ursprünglich getan hat Wir wollen also, dass hier ein physikalischer Prozess abläuft. Wenn Sie den physikalischen Prozess finden und die Eingabetaste drücken , erhalten wir hier die vollständige Funktionsdefinition für den Namen hier, unterstreichen Sie den physikalischen Prozess Okay, hier haben wir den Namen unserer Funktion. Der Unterstrich hier zeigt an, dass sie privat sein soll und nicht von anderen Skripten aus aufgerufen werden soll und dass sie nur innerhalb dieses Skripts enthalten oder gekapselt sein soll Das Delta ist hier der Name unseres Parameters, und Float ist der Typ unseres Parameters Im GD-Skript müssen Sie Ihre Funktionen nicht wirklich eingeben. Wenn Sie es also wollen, können Sie diesen Doppelpunkt als Float entfernen und ihn einfach Delta nennen. Was ist jetzt Delta? Nun, das wäre am Ende was das Halsband beschlossen hat, in diese Funktion zu übertragen, die in diesem Fall im Grunde nichts daran hindert, etwas anderes als ein Float zu sein. Man würde so ziemlich erwarten, dass es ein Float ist. In diesem Fall ist es also viel besser, seinen Typ tatsächlich mit einem Doppelpunkt zu deklarieren und dann hier Float zu platzieren. Also ich kann das nur empfehlen. Und dann hier auch ein optionaler Bestandteil der Funktionsdeklaration. Wir haben diesen Pfeil, der ein Strich neben der Nulltaste ist. Okay, und dann haben wir hier auf der rechten Seite den Return-Pfeil, der auf den Rückgabetyp Leere zeigt . Void bedeutet, dass es kein Zurück gibt. Sie erwarten nicht, dass es tatsächlich etwas zurückgibt , das Sie in anderen Funktionen verwenden würden. Um das manuell einzugeben, würden Sie einen Bindestrich und dann ein benotetes Und das ist Ihr Rückgabepfeil, der auf den Rückgabetyp zeigt. Okay, also wenn wir das eingeben, enthält unsere Funktion natürlich nichts. Sie können eine Funktion dazu bringen, nichts zu tun, indem Pass-Kleinbuchstaben eingeben, also das ist dort ein reserviertes Schlüsselwort Aber ohne das, wenn ich das rückgängig mache, wirst du unten diesen Fehler sehen, der besagt, dass nach der Funktionsdeklaration ein Endantenblock erwartet wird, was bedeutet, dass hier etwas drin sein sollte, nachdem die Funktion deklariert was bedeutet, dass hier etwas drin sein sollte , nachdem die Funktion Und Sie können diese Liste hier erweitern , um alle Fehler in Ihrem aktuellen Skript zu sehen. Dort befindet ein ziemlich praktisches kleines Fenster Also gut, wenn du kopieren und einfügen musst, du kannst einfach alles auswählen und kopieren. Und Sie können das in jede andere Anwendung einfügen , die Sie verwenden. Vielleicht machst du einen Bugreport oder etwas Ähnliches. Okay, also endlich können wir tatsächlich anfangen, Funktionscode zu schreiben. Ich weiß, dass ich ein bisschen langsam vorankomme. Ich versuche, es hier zugänglich zu halten, besonders in den früheren Videos, das wird besonders in den früheren Videos, das wird im Laufe des Kurses definitiv viel intensiver werden. Zuallererst wollen wir für unseren physikalischen Prozess, dass sich der Charakter bewegt, was bedeutet, dass wir eine Geschwindigkeit und eine Richtung brauchen , in die sich der Charakter bewegen wird. Also müssen wir irgendwo angeben, wie schnell sich unser Charakter bewegt. Also könnten wir es direkt in der Funktion deklarieren. Aber eigentlich möchte ich jetzt eine Exportvariable erstellen, mit der wir die Geschwindigkeit im Editor ganz einfach ändern können die Geschwindigkeit im Editor ganz einfach ändern indem wir einfach hier rechts rübergehen und dann die gewünschte Geschwindigkeit eingeben. Und das können wir auch während des Spiels ändern. Geben wir also die Geschwindigkeit von Export var und geben ihr den Typ Float. Lassen Sie uns das also zuerst langsam durchgehen. Bei Export gibt es ein Schlüsselwort, das deklariert, dass es im Inspektor bearbeitet werden kann Okay, und dann bedeutet var hier variabel. Geschwindigkeit ist der Name der Variablen. Doppelpunkt definiert hier den Typ, und dann ist Float der Typ. Also können wir diese Geschwindigkeit annehmen. Lassen Sie uns hier „Pass“ für den Physikprozess schreiben und dann „Control“ drücken, um ihn zu speichern. Und du wirst sehen, dass hier und oben rechts die Geschwindigkeit für das Player-Skript angezeigt hier und oben rechts die Geschwindigkeit für das Player-Skript Vergewissere dich, dass du den Player-Knoten ausgewählt hast, dann wirst du ihn sehen können Jetzt können Sie auch sehen, dass die Standardeinstellung 0,0 ist. Das ist also der Standardwert für Float. Sie wollen dem wahrscheinlich aus Geschwindigkeitsgründen eine reelle Zahl zuweisen. Also nehme ich das und sage gleich, gehen wir mit 100,0 und drücken Strg S. Jetzt der Standardwert hier automatisch geladen , weil wir keinen benutzerdefinierten Wert festgelegt haben Wenn Sie einen benutzerdefinierten Wert festlegen, indem Sie hier klicken, sagen wir 150 und drücken die Eingabetaste, jetzt ist die Geschwindigkeit Wenn wir hier den Standardwert auf 200 ändern und innerhalb des Skripts auf Speichern klicken, werden Sie feststellen, dass der benutzerdefinierte Wert immer noch den Standardwert von 200 überschreibt Ich kann hier auf die Reset-Taste drücken , um ihn auf den Standard zurückzusetzen, also sind es jetzt 200 Jetzt möchte ich, dass die Skriptgeschwindigkeit 100 beträgt. Ich glaube, das hatte ich für das Standardprojekt. Wir können das später jederzeit ändern und die Geschwindigkeit Ihrer Spieler jederzeit auf das einstellen , womit Sie sich wohl fühlen. Das ist komplett. Und so können wir unsere vom Editor definierte Eigenschaft innerhalb des Skripts verwenden. Exportvariablen sind also wirklich nützlich, um sie leichter zugänglich zu machen die Details bearbeiten können, wie unser Skript bearbeiten würde , ohne dass Sie etwas darüber wissen müssen , wie der Code tatsächlich funktioniert Okay, wir haben also unsere Geschwindigkeit. Wir können jetzt einen physikalischen Prozess schreiben. Okay, schauen wir uns das mal an. Ich werde zuerst die Eingaberichtung ermitteln. Okay, für den Moment wollen wir eine Richtungsvariable deklarieren, also var direction. Und Sie werden sehen, dass ich das in die Funktion eintippe. Das macht es also zu einer lokalen Variablen für die Funktion, was bedeutet, dass sie gelöscht wird , sobald die Funktionen erledigt sind. Es wird nur innerhalb der Funktion verwendet, es sei denn wir geben es als unseren Rückgabetyp zurück. Es ist also im Grunde temporär. Und wir werden das der Eingabe gleichsetzen . Jetzt weiß ich, dass ich das I groß schreibe, weil das ein Klassenname ist , auf den wir verweisen Die Eingabeklasse ist also , man könnte sie sich als globale Klasse vorstellen Sie können überall auf sie zugreifen, wenn Sie möchten, dass sie etwas für Sie tun. Und wir werden die Import-Klasse verwenden , um einen Vektor zu erhalten. Ein Vektor wird also eine X- und eine Y-Komponente haben, ein Vektor eher zwei. Es gibt auch Vektor drei für drei D-Spiele, wodurch die Z-Achse hinzugefügt wird. Aber bei zwei D-Spielen gibt es nur X und ein Y, wodurch das bloße Entfernen dieser dritten Achse das Verständnis und die Arbeit mit zwei D-Spielen etwas einfacher macht . Also wollen wir hier das negative X ermitteln. Sie können die Parameter sehen , die diese Funktion definiert, und es gibt hier tatsächlich einige zusätzliche Parameter wie Dead Zone, die wir nicht benötigen. Aber die vier, die wir brauchen, sind negatives X, positives X, negatives Y und positives Y. also, in einem der beiden vorherigen Videos Ich glaube also, in einem der beiden vorherigen Videos habe ich das angesprochen, aber negativ X und Gadot bleibt auf dem Bildschirm Also wollen wir Input für links. Jetzt können Sie sehen, wie es mit einigen vordefinierten Aktionszeichenfolgennamen aufgefüllt einigen vordefinierten Aktionszeichenfolgennamen Wissen Sie, es ist übrigens ein Zeichenkettenname, weil vor der Zeichenfolge ein Und-Zeichen steht , was Anführungszeichen sind, und dann der eigentliche Name hier, der in Anführungszeichen eigentliche Name hier, Aber das sind alles Standard-UI-Aktionen, und es ist keine gute Idee, diese tatsächlich zu In dem Sinne, dass du deinen Charakter kontrollierst, weil sie standardmäßig bereits die Benutzeroberfläche kontrollieren. Gehen wir also zu den Projekteinstellungen. Also projizieren Sie die Projekteinstellungen oben links, Eingabeübersicht, und wir geben eine neue Aktion ein. Ich tippe links ein und klicke dann auf Hinzufügen. Also unsere linke Aktion, ich werde hier auf Ereignis hinzufügen klicken, und ich verwende gerne WASD-Tasten Das ist ziemlich normal für viele Spiele. Also werde ich hier einfach A eingeben wo es heißt, auf Eingaben und eine Regel zu warten. Weisen Sie es automatisch dem A-Schlüssel, physischen Schlüssel oder einem Unicode-Schlüssel zu. Also im Grunde A auf Ihrer Tastatur. Sie können jetzt auf Okay klicken. Und jetzt wird das Verschieben nach links A zugewiesen. Und das wollen wir auch für oben, unten und rechts tun. Geben Sie also rechts ein, fügen Sie hinzu und dann klicken wir hier, um den Schlüssel zuzuweisen, Ereignis hinzufügen, und drücken D für rechts. Klicken Sie auf Okay. Lass uns jetzt aufstellen. Klicken Sie auf Ereignis hinzufügen, drücken Sie W für hoch, fügen Sie eine Aktion hinzu, nach unten, klicken Sie auf Ereignis hinzufügen, S für runter, und da ist unsere Bewegungseingabe. Kidob übernimmt also automatisch die Umwandlung dieser Tastendrücke in eigentliche Aktion , die wir in der Eingabe-Vektorfunktionsspalte der Klasse G verwenden können Eingabe-Vektorfunktionsspalte der Klasse G Wir wollen hier also die Namen der Aktionen eingeben, die wir gerade eingegeben Also können wir das Zitat hier links machen. Und Sie werden sehen, dass es tatsächlich automatisch aufgefüllt wird, und Sie können hier einfach die Eingabetaste drücken, um es für negatives X zu bestätigen , für positives X, wir wollen richtig Sie können hier auch sehen, dass es einfach irgendwie aufgetaucht ist, sodass wir einfach darauf doppelklicken können Dann das dritte negative Y, wir können es eintippen oder in der Liste suchen. Also runter. Und dann das positive Y, oh, das habe ich tatsächlich verwechselt. Negatives Y ist hoch, positives Y ist runter. Also werde ich hier unten das positive Y hinzufügen und dann hier drüben werde ich einfach die Zahl löschen und aufwärts eingeben. Also ich bin mir ziemlich sicher , dass das stimmt. Wir werden es definitiv in einer Minute herausfinden, sobald wir den Test gespielt haben. Wir wollen die Eingaberichtung nehmen, und wenn sie nicht Null ist, dann wollen wir weitermachen. Wenn es also Null ist, wollen wir einfach aufhören , unseren Charakter zu bewegen. Du kannst das also tun, indem du sagst, ob Richtung. Das prüft also im Grunde schon, ob die Richtung dem Vektor Null entspricht oder nicht. Wenn Richtung also bedeutet, dass sie nicht Null ist, dann können wir die Geschwindigkeit unseres Charakters nehmen. Nun, woher haben wir die Geschwindigkeitseigenschaft? Nun, unser Klassiker steht : Körper zwei D, und Geschwindigkeit ist eine Eigenschaft von Körper zwei D. Wenn ich also mit der rechten Maustaste auf den zweiten Charakterkörper D klicken und zum Suchsymbol gehen würde, kann ich hier nach unten scrollen und sehen, dass die Geschwindigkeit genau hier in der Liste der Eigenschaften auftaucht Alle Eigenschaften oder Methoden, also Funktionen innerhalb einer Klasse, die zu einer übergeordneten Klasse gehören, werden also von dieser erbenden Klasse vererbt und können von ihr verwendet werden . Innerhalb eines Spielers können wir also die Geschwindigkeit nehmen und sie so einstellen, dass wir die Richtung mal die Geschwindigkeit haben wollen Jetzt werden Sie diese Delta-Komponente hier sehen. Dies ist die Zeit zwischen den Frames. Wir müssen sie hier nicht dem speziellen Bewegungsstil zuweisen , den wir verwenden, nämlich Verschieben und Schieben. , gibt es noch eine Bewegung und Kollision an Delta vorbeifahren würden ich mich recht erinnere, gibt es noch eine Bewegung und Kollision, bei der Sie beim Aufruf dieser Funktion Es ist also ein bisschen seltsam, dass das Delta hier automatisch berücksichtigt wird, aber so funktioniert es einfach Also jede Taste, die zur Bewegung gedrückt wird, wird gedrückt. Wir werden die Geschwindigkeit der Richtung multipliziert mit der Geschwindigkeit zuordnen . Danach hier unten können wir uns bewegen und rutschen. Also, was würde jetzt passieren? Eigentlich wäre es einfacher, es einfach zu zeigen. Drücken wir auf Play und wir haben noch keine Hauptszene ausgewählt. Wählen wir also die Weltszene als unsere Hauptszene aus. Ich gehe hier einfach in den Verzeichnissen nach oben und wähle Welt. Doppelklicken Sie. Wir haben einen Charakter. Und wenn ich eine Bewegungstaste drücke und loslasse, wirst du sehen, dass das unseren Charakter nicht stoppt. Es rutscht einfach weiter, was für eine Art Lichtmechanik verwendet werden könnte Aber für normale Bewegungen wollen wir hier eigentlich eine se-Anweisung als Nachfolge zu unserem I. hinzufügen . Also se und dann stellen Sie sicher, dass Sie den Doppelpunkt am Ende setzen Das deklariert also im Grunde, was folgt, als Block für die Funktion, den Code weiter auszuführen Und wir wollen die Geschwindigkeit nehmen. Wir wollen das in Richtung Serrel reduzieren . Geschwindigkeit entspricht Vektor zwei. Also erstellen wir hier tatsächlich einen neuen Vektor zwei, und wir setzen hier Klammern Sie können sehen, dass die dritte Art der Vektorkonstruktion einen X- und einen Y-Wert benötigt Drücken Sie also in den Klammern die Eingabetaste. Das wird also die erste Klammer von der zweiten trennen und macht es sehr deutlich, hier die X-Logik und dann die Y-Logik direkt darunter einzugeben hier die X-Logik und dann die Y-Logik Wir wollen uns also in Richtung des Geschwindigkeitspunkts X auf Null bewegen. Und das machen wir einfach mit der aktuellen Geschwindigkeit. Das bedeutet also im Grunde, dass wir die Geschwindigkeit sofort auf Null senken, sobald wir loslassen . Es gibt viele verschiedene Möglichkeiten, dies zu tun. Sie können es mit der Zeit schrittweise verringern lassen, wenn Sie eine LARP-Funktion verwenden Aber das ist wahrscheinlich am einfachsten. Also machen wir einfach damit weiter. Gehen Sie zu. Und dann wollen wir in der zweiten Zeile den Y-Wert für die neue Geschwindigkeit ermitteln. Gehen wir also in Richtung des aktuellen Geschwindigkeitspunkts Y, so dass er sich bei der Geschwindigkeitsänderung oder dem Delta der Geschwindigkeit dem Nullpunkt nähert . Also speichern wir das dort, und das bedeutet, dass es unsere aktuelle Geschwindigkeit nimmt, die, sagen wir, bei voller Geschwindigkeit nach rechts hochfahren könnte, und wir werden bei voller Geschwindigkeit nach rechts hochfahren könnte, sie um die volle Geschwindigkeit senken, was bedeutet, dass sie sofort auf Null sinkt . Wir nähern uns Null. Sobald wir also unsere Eingabetasten loslassen, hört unser Charakter auf, sich zu bewegen, ist das Endergebnis von. Zähle das tatsächlich. Um also einen Kommentar zu deklarieren, wenn Sie das tun möchten, fügen Sie einen Hashtag und dann die Beschreibung hinzu. So können Sie Ihre Kommentare generell in der Zeile lassen , wenn Sie möchten. Heutzutage ziehe ich sie tatsächlich so an den Anfang der Funktion, also drücke X und dann Strg V , um sie einzufügen. Und wenn du möchtest, dass dieser Text in der automatisch generierten Dokumentation für deine Klasse auftaucht , dann kannst du zwei Ampersand Und speichere es, und dann wird es zur Dokumentation der Spielerklasse hinzugefügt es zur Dokumentation der Spielerklasse Und wir können auf diese Dokumentation zugreifen, indem wir hier auf Suchhilfe klicken. Wir suchen nach Player, unserer benutzerdefinierten Klasse, klicken auf Öffnen und Sie können den Namen unserer Eigenschaften sehen , der sich in diesem Fall nur auf eine Variable bezieht, die als Teil der Klasse local existiert. In diesem Fall könnten wir uns einfach auf eine Variable beziehen, bei der es sich um einen lokalen Status handelt der innerhalb der Klasse existiert, und nicht auf eine lokale Variable einer Funktion. Sie können diese also nach Bedarf bearbeiten und daraus lesen. In anderen Programmiersprachen Dinge wie Felder oder sind Dinge wie Felder oder Eigenschaften viel klarer definiert. Aber ich denke, im Allgemeinen sind Ihre Eigenschaft und Ihre Variable bei den meisten grundlegenden GD-Skriptfunktionen dasselbe. Sie würden nicht so etwas wie ein unterstützendes privates Feld deklarieren , wie Sie es in C Sharp tun würden. Ich würde aber sagen, in den meisten Fällen, weil, wissen Sie, es immer noch einige Gründe dafür geben würde , das zu tun , um Ihr öffentliches Eigentum privat zu unterstützen. Hier seht ihr die Methode hier und wenn wir die Methodenbeschreibungen runterscrollen. Also physikalischer Prozess. Sobald wir unsere Bewegungstasten loslassen, hört unser Charakter auf, sich zu bewegen. Das Coolste am GD-Skript ist also , dass es sich im Wesentlichen selbst um die Generierung von Dokumentationen handelt Solange Sie die Kommentare mit den doppelten Und-Zeichen dort platzieren , wo sie hingehören sollen, können Sie ein Feld oder eine Eigenschaft kommentieren Sie können eine Methode kommentieren. Und das ist wirklich hilfreich. Es macht es anderen leicht , Ihren Code grundsätzlich zu verstehen, ohne das gesamte Skript von oben nach unten lesen zu müssen. Sie könnten hier also tatsächlich dasselbe mit Geschwindigkeit tun. Also zwei Ampersand und sage die Basisbewegung, die Basis, die Basisbewegungsgeschwindigkeit, des Spielercharakters Drücken Sie S und speichern Sie, und dann können Sie sehen, dass unsere Dokumentation immer noch hier im Skriptfenster geöffnet ist hier im Skriptfenster Wenn ich also auf Player klicke, siehst du, oh, jetzt hat unsere Geschwindigkeitseigenschaft eine Beschreibung, die leicht zu lesen ist. Das ist also wirklich praktisch. Behalte das im Hinterkopf. Und jetzt können wir weitermachen und auf Play klicken. Also werden wir unseren Charakter in WASD verschieben. Jetzt werden wir sehen, dass der Charakter aufhört, sich zu bewegen, sobald wir den Import beenden Charakter aufhört, sich zu bewegen, sobald wir den Das ist eher das, was man von einem Charakter erwarten würde , der sich auf etwas Normalem wie Gras oder Stein oder was auch immer bewegt , also auf Dingen, die Reibung haben sollten, nicht Eis. Und das ist im Grunde die Grundbewegung , die wir für den Rest des Spiels verwenden werden. Nun, die Charaktere sind offensichtlich nicht animiert. Wir haben keine Laufanimationen. Es zeigt noch nicht in die Richtung, in die es sollte. Das sind alles Dinge, die wir in Zukunft in zukünftigen Videos behandeln werden. Eine letzte Sache, die ich zu einer letzten Sache hinzufügen möchte, die ich für diesen Charakter hinzufügen möchte, nun, wir sind den Dingen voraus, ist, nur eine weitere Eigenschaft für den Anzeigenamen hinzuzufügen. Also werde ich tatsächlich einen Export für eine var, einen Anzeigenamen, hinzufügen . Und das wird ein Typ-Zeichenkettenname sein. Und wir werden das gleich Ampersan setzen, was auch immer Sie wollen . Sie können es einfach zum Player machen und die Steuerung drücken Für unseren Player können wir jetzt sehen, dass die Eigens 5. Animationen aus Spritesheets abspielen: So wie die Dinge jetzt sind, kann sich unser Charakter technisch gesehen bewegen, aber das Sprite hat keinerlei Animation Wir wollen also, dass unser Charakter animiert, wenn er Idole ausführt, und natürlich auch die Todesanimation, wenn wir das Spiel verlieren Okay, das Erste, was wir tun werden, ist das Spritesheet Wenn du im Pixel Crawler-Paket nachschaust, können wir uns das Idol-Spritesheet für die Nacht schnappen, oder du kannst den Schurken oder den Zauberer benutzen, wenn du das Also schnappe ich mir das und bringe es her. Und das sind im Grunde zur Seite gerichtete Sprites. Du wirst feststellen, dass es bei diesem Charakter weder ein Hoch noch ein Ab Das hat allerdings ein paar Vorteile . Zunächst einmal, wenn Sie nur eine Richtung animieren und sie dann umdrehen, was der Standard-Survivor tatsächlich tut Es ist viel einfacher , Charaktere zu erstellen, weil Sie nur eine Richtung animieren müssen Und zweitens kannst du Animationsbäume komplett überspringen und dich einfach auf einen Animations-Player und eine Zustandsmaschine konzentrieren , die die Logik steuert dein Charakter zwischen Zuständen wie , mit der dein Charakter zwischen Zuständen wie Inaktiv wechselt. Aus diesen Gründen wechseln wir hier eigentlich einfach zum Night Idol Sprite Du könntest das Idol ziemlich synonym verwenden. Du könntest später das Rogue-Spritesheet benutzen, wie genau dort, oder auch das Zauberer-Sheet wie genau dort, oder auch das Zauberer-Sheet Beides wird also einwandfrei funktionieren, und es gibt bereits das Setup für drei Charakterklassen. Aber am Anfang ging es eher um einen Ritter mit Speeren Anfang ging es eher um einen Ritter mit Also wie ein Charakter Agroun heißt, passt dieser rüstige Charakter irgendwie dazu, und er wird Speere werfen können Also, wir haben unser Spritesheet hier. Wir wollen daraus eine ungenutzte Animation machen. Die He-Frames wurden hier bereits eingerichtet, aber dafür benötigen wir einen echten Animationsplayer . Klicken Sie also mit der rechten Maustaste auf den Player-Knoten und fügen Sie einen untergeordneten Knoten hinzu. Suchen Sie nach dem Animation-Player. Füge das hinzu. Wenn Sie also den Animation-Player haben, sich das Animationsfenster hier unten. Sie können hier klicken, wenn Sie es noch benötigen. Und wir wollen zur Animation und dann zu Nu gehen und den Namen der Animation eingeben. Wir beginnen also mit der Idle-Animation, also geben wir einfach Idle ein. Und wir können einen Eigenschaften-Track hinzufügen. Also werden wir uns einige dieser Eigenschaften vom Sprite Two D holen , nämlich die Textur. Also doppelklicken Sie darauf Wir klicken mit der rechten Maustaste auf Property Track, fügen H-Frames und dann Property Track, Sprite, zwei D. V-Frames. Schließlich benötigen wir vorerst zumindest die Frame-Nummer selbst. Also füge einen Frame als Eigenschaft hinzu. Jetzt können wir also diesen Zoom nehmen und unser Spritesheet ein wenig vergrößern Zuerst möchte ich die Schnappschusszeit hier unten nehmen, wo 0,033 3 Sekunden stehen, und sie auf 0,1 ändern, was bedeutet, dass wir in Intervallen von 0,1 Sekunden oder einer Zehntelsekunde arbeiten werden Intervallen von 0,1 Sekunden oder einer Zehntelsekunde Dann aktiviere dieses Ausrichten am Timeline-Cursor. Jetzt können Sie einfach hier auf die 0,1-Sekunden-Intervalle klicken , was die Arbeit erheblich erleichtert Sie haben vielleicht auf diesem hellen Blatt gesehen , dass es vier Animationsframes gibt. Wir werden diese also alle 0,1 Sekunden wiederholen , also viermal 0,1 Wir wollen eine 0,4 Sekunden lange Animation. Also hier auf der rechten Seite, geben Sie 0,4 ein und dann dieses Ding, das aussieht, als würden Pfeile ineinander übergehen. Animationsschleife, du willst darauf klicken , damit unsere Animation in einer Schleife läuft Jetzt gibt es in unserer Animationszeitleiste keine Keyframes. Wir möchten auf jeden Fall zu Beginn der Animation für all diese Eigenschaften einen Keyframe festlegen Beginn der Animation für all diese Eigenschaften einen Keyframe der Animation für all Klicken Sie also mit der rechten Maustaste auf Taste einfügen. Wenn Sie hier mit der linken Maustaste klicken, werden Sie feststellen, dass der Wert für die Textur bereits für diese nächtliche Leerlaufanimation voreingestellt ist . Ist dies nicht der Fall, sollten Sie es auf das Spritesheet im Leerlauf ändern Von hier aus können Sie es per Drag-and-Drop und dort ablegen Dieser Keyframe bedeutet also, dass zu Beginn unserer Animation nach 0,0 Sekunden, wenn diese Animation abgespielt wird, Sekunden, wenn diese Animation abgespielt wird, die Textur auf unserem Sprite auf diesen Wert gesetzt wird, was bedeutet, dass wir das Spritesheet austauschen, sobald die Animation beginnt wir das Spritesheet austauschen, sobald die Nun, H-Frames, wir wollen auch mit der rechten Maustaste klicken und die Serta-Taste drücken. Jetzt haben wir unseren Wert hier bereits als vier in diesen hellen zwei D vordefiniert . Sie können also sehen, dass, wenn Sie die Serta-Taste drücken, Wert, auf den sie gerade eingestellt ist, als Schlüsselbildpunkt auf der Animations-Timeline hinzugefügt wird als Schlüsselbildpunkt auf der Animations-Timeline Und wenn diese Keyframes aufeinandertreffen, bedeutet das, dass der aktuelle Wert genau dieser Wert ist Für unser Pix-Art-Spiel werden wir fast immer den diskreten Modus hier ganz rechts verwenden Du kannst diese drei Punkte sehen. Das bedeutet, dass sich der Wert erst ändert , wenn er den Key-Frame-Punkt erreicht. In einem Spiel, das eher einem Drei-D-Spiel ähnelt, könnten Sie eine kontinuierliche Animation durchführen, was bedeutet, dass die Animation schrittweise zwischen den Werten der Keyframes hin Wenn Sie also so etwas wie einen Positions-Keyframe haben, animiert dieser die Position zwischen der Startposition Null und der Endposition von 100 im Laufe der während diese Animationszeitleiste fortschreitet Ein Großteil der Animationen in Spielen besteht also eigentlich nur darin, die Werte der Eigenschaften Ihres Objekts im Laufe der Zeit zu ändern die Werte der Eigenschaften Ihres Objekts im Laufe der Zeit zu Okay, wenn wir mit V-Frames weitermachen, können wir mit der rechten Maustaste klicken, um einen Schlüssel einzufügen. Sie werden sehen, dass der Wert hier, wenn wir mit der linken Maustaste auf den Keyframe klicken, bereits auf eins gesetzt ist . Das ist es, was wir wollen Wenn wir uns noch einmal das Idol-Sprite-Sheet ansehen, hat es vier H-Frames, horizontale Frames und einen vertikalen Frame in Bezug auf Zeilen und Spalten Deshalb haben wir vier für H-Frames und einen für V-Frames Wir müssen hier nicht viele Anpassungen vornehmen. Wir müssen nur sicherstellen, dass es zu Beginn auf diese Werte eingestellt ist, damit unsere Animation korrekt abgespielt wird. Was wir nun tatsächlich tun müssen, ist unsere vier Animationsframes hier einzufügen. Klicken Sie also mit der rechten Maustaste auf den ersten Frame und drücken Sie Insert Key. Du wirst das für Frame sehen, es zeigt dir tatsächlich eine Vorschau des Sprites Es wird sehr hilfreich sein, aber du kannst auch mit der linken Maustaste darauf klicken und sehen, dass es auf den Wert Null gesetzt ist Jetzt wollen wir auf 0,1 springen. Falls Sie noch nicht die Option „Ausrichten auf den Timeline-Cursor anwenden“ ausgewählt haben, können Sie das hier tun Das macht es viel einfacher, zu 0.1 zu wechseln. Ich denke, Sie können den Wert auch manuell eingeben , wenn Sie in die Timeline springen möchten. Normalerweise schnappe ich aber einfach mit dem Mauszeiger. Klicken Sie dann mit der rechten Maustaste auf den Rahmenabschnitt, die Rahmenzeile und drücken Sie die Taste „Einfügen“. Jetzt bekommst du eine Linie , die dazwischen verläuft. Diese Linie bedeutet, dass sich der Wert zwischen hier und hier nicht ändert. Es ist nur eine Fortsetzung desselben Werts. Also wollen wir hier klicken und das in eins ändern, und das bedeutet, dass jetzt der zweite Animationsframe abgespielt wird. Da das Blatt Bright wie ein Array von Werten ist, beginnt es bei Null, nicht bei Eins. Im Allgemeinen würde es beim Programmieren so funktionieren. Eins ist also tatsächlich der zweite Animationsframe und Null ist tatsächlich der erste Animationsframe. Klicken wir mit der rechten Maustaste auf 0,2, fügen einen Key ein, klicken auf den Key-Frame-Punkt, ändern dann den Wert auf zwei und gehen dann hier auf 0,3. Klicken Sie mit der rechten Maustaste auf Schlüssel einfügen. Klicken Sie hier, ändern Sie es auf drei. Jetzt sollten Sie keine Linien mehr sehen , die zwischen diesen Frames verlaufen. Wir können hier zum Start gehen, auf Play klicken und da ist unsere Animation für den Charakter. Jetzt noch einmal, weil wir nur linke und rechte Animationen machen, müssen wir hier nur ein Idol, eine Todesanimation und eine Run-Animation machen hier nur ein Idol, eine Todesanimation und eine Run-Animation Und dann steuern wir das Umdrehen des Charakters auf eine andere Charakters auf eine andere Art und Weise. Das zeige ich dir später Also ein viel einfacheres Setup und es ist viel einfacher, neue Charaktere hinzuzufügen , wenn du das willst. Lassen Sie uns diese Animation also tatsächlich duplizieren , denn vieles davon werden wir tatsächlich wiederverwenden. Wir werden nur vielleicht den He-Frame-Wert und die Textur ändern . Und je nachdem, wie viele Run-Frames es gibt, können wir die Frames auch hier ändern. Aber lass es uns duplizieren, indem wir hier auf Animation klicken und duplizieren und dann Run machen. Okay, jetzt wollen wir auf Textur klicken und das Run-Sprite-Sheet per Drag & Drop hierher ziehen. Wir können sehen, dass es sechs Animationsframes hat. Das bedeutet also, dass wir den H-Frames-Wert hier auf sechs ändern müssen . Wir wollen die Animationsdauer auf 0,6 ändern , weil wir jetzt an sechs Frames arbeiten, nicht an vier. Und dann wollen wir zu 0,4 Sekunden übergehen und den fünften Animationsframe hinzufügen. Fügen Sie also den Schlüssel ein, klicken Sie hier, ändern Sie den Wert für das fünfte Bild auf vier und fahren Sie dann mit 0,5 Sekunden fort. Klicken Sie mit der rechten Maustaste hier, fügen Sie die Taste ein, klicken Sie links auf den Keyframe, ändern Sie den Wert 4-5 und drücken Sie auf Play Und da ist unsere runde Animation. Das Duplizieren spart also viel Zeit. Okay, lassen Sie uns jetzt die Todesanimation hinzufügen , während wir noch dabei sind. Also lasst uns den Tod duplizieren und hinzufügen. Und dann wollen wir die Textur hier natürlich ändern, um das Todesblatt der Nacht zu ersetzen. Ziehen Sie also das Todesblatt per Drag & in den Keyframe-Inspektor Ich kann hier zählen. Es gibt sechs Frames. Also lass uns klicken. Eigentlich müssen wir nichts weiter ändern, weil wir es einfach von ungefähr duplizieren. Wir können einfach auf Play klicken. Aber du kannst sehen, dass es sich wiederholt. Charaktere tun das also normalerweise nicht. Also wollen wir Loop tatsächlich deaktivieren , indem wir hier zweimal klicken. Dadurch wird es so gemacht, dass die Animation hin und her läuft. Es geht quasi bis zum Ende und dann zurück zum Anfang. Das wäre nützlicher für so etwas wie eine bewegliche Plattform. Wir möchten ein zweites Mal klicken, um das Looping vollständig auszuschalten Gehen Sie also zu 0.0, klicken Sie auf Play, und die Animation sollte hier am Ende aufhören Und wenn die Todesanimation später fertig ist, müssen wir nur noch so etwas wie ein Game Over für unseren Charakter eingeben, und das war's dann. Okay, also welche Animation wird tatsächlich abgespielt, wenn wir das Spiel starten? Nun, lass uns auf Play klicken und es herausfinden. Okay, Sie können also sehen, dass die inaktive Animation da ist, aber sie spielt eigentlich keine der Animationen ab. Äh, wir haben eine Animation nicht auf Autoplay on Start eingestellt eine Animation nicht auf Autoplay on Start Unsere Animationen werden irgendwann mit einer sogenannten Zustandsmaschine gesteuert werden Darauf werden wir im nächsten Video näher eingehen. Lass uns auf den Animation-Player klicken und die Animation hier, die wir uns ansehen, von Tod auf Laufen ändern . Und wir klicken hier auf diese kleine Schaltfläche Autoplay on Load Klicken Sie also auf Abspielen und jetzt werden Sie sehen , dass unabhängig davon , ob sich unser Charakter bewegt oder nicht, er die Laufanimation abspielt Beachten Sie, dass die Richtung auch nicht automatisch umgekehrt wird. Das wird ein einfaches Skript sein, das wir später ebenfalls hinzufügen. Aber wir haben drei Animationen für unseren Charakter, und wir haben die Möglichkeit, zwischen ihnen zu wechseln , indem wir sie beim Namen nennen. Im nächsten Video erstellen wir die Zustandsmaschine mit einem Bewegungsstatus, zwischen Leerlauf und Ausführen umschalten kann. 6. Spieler-State-Maschine: Okay, unser Charakter hat einen Animationsspieler und die Fähigkeit , die Run-Animation abzuspielen, aber wir wollen zwischen Idol- und Run-Animationen wechseln , je nachdem ob es eine Tasteneingabe für unseren Charakter gibt oder nicht Lassen Sie uns das also mit einer Zustandsmaschine kontrollieren. Wenn Sie sich zu Beginn des Kurses erinnern, haben wir Limbo AI hinzugefügt. Dabei haben wir Limbo AI hinzugefügt handelt es sich um eine Zustandsmaschine und Verhaltensbaumsystem, das Sie in Gado sofort verwenden können. Das erspart Ihnen eine Menge Arbeit, da Sie es nicht manuell erledigen müssen Ich werde mich für den Kurs an Zustandsmaschinen halten. Ich denke, sie sind in Zukunft nur ein bisschen einfacher zu handhaben und viel besser für einfache Setups wie diese Und das ist, um ehrlich zu sein, ein sehr einfaches Setup. Klicken wir also mit der rechten Maustaste auf den Spieler an der Basis an einem untergeordneten Knoten. Und wir werden nach dem Schlüsselwort Limbo suchen. Sie werden hier also sehen, dass Limbo HSM für Hierarchical State Machine steht Wie im Stammknoten hier wird die Zustandsmaschine selbst die Zustände kontrollieren, die Limbo-Zustände, und sie wird in der Lage sein, zwischen ihnen zu wechseln , wenn wir Übergänge zwischen diesen Zuständen hinzufügen Lassen Sie uns also das Limbo HSM erstellen. Und dann klicke ich hier mit der rechten Maustaste und wir fügen unseren ersten State Add Child-Node hinzu Also wollen wir einen Limbo-Zustand und schaffen ihn einfach. Die Hierarchie ist also die Root-State-Maschine, und zwischen all den Zuständen können wir wechseln Und jeder dieser Zustände wird unterschiedlichen Code ausführen, je nachdem in welchem Zustand sich der Charakter befindet. Für diesen Kurs werden wir wirklich nur einen Bewegungsstatus und einen Todeszustand haben. So einfach. Aber immer noch wichtig , weil wir wissen wollen , wann unser Charakter in den Todeszustand wechseln sollte, und der Bewegungsstatus wird Animationen im Leerlauf und im Bewegungsmodus steuern. Technisch gesehen könntest du den Leerlauf trennen und in ihren eigenen Status wechseln, aber sie werden im Grunde denselben Code ausführen , denn egal, ob der Charakter im Leerlauf befindet oder sich bewegt, er kann sich immer noch frei bewegen Es kommt nur darauf an , welche Animation abgespielt wird Und ich glaube nicht , dass das unbedingt einen völlig getrennten Staat rechtfertigt Klicken wir also mit der rechten Maustaste auf Limbo HSM und ich werde ein Skript anhängen Das wird, sagen wir, Player Underscore HSM heißen. Es ist also die hierarchische Zustandsmaschine des Spielers. Lass uns das erstellen. Und dann hier oben wollen wir ihm natürlich den Klassennamen geben, Spieler HSM Allgemein gesagt, wie ich hier im Dateisystem zeigen werde, wenn wir HSM suchen, was auch immer Sie als Schlangenbuchstaben für den Dateinamen angeben, möchten Sie auch den Klassennamen hier oben haben , aber das möchten Sie auch den Klassennamen hier oben haben, aber das ist natürlich groß geschrieben und Sie lassen die Leerzeichen aus, weil das hier oben ein Typsymbol ist Es ist eine sehr gute Idee, diesen Namen und den Skriptnamen synchron zu halten diesen Namen und den Skriptnamen synchron Das Spieler-HSM wird uns also helfen , den Körper des Spielercharakters durch die Zustände zu kontrollieren Körper des Spielercharakters durch die , die auf dem Limbo HSM existieren Also wollen wir uns den Spieler schnappen und ihn zum Agenten machen, den die Zustandsmaschine Okay, also zuerst wollen wir für unseren Spieler HSM einen Verweis auf den Spieler , den unsere Zustandsmaschine verwalten wird Machen wir also einen Export Var Player vom Typ Player. Und wenn wir den Klassennamen für das Body-Skript unseres Charakters als Spieler definiert haben Body-Skript unseres Charakters , sollte das funktionieren. Und Sie können im Inspektor hier auf der rechten Seite sehen , dass es aufgetaucht ist. Also, wenn du willst, kannst du auf Zuweisen klicken und es sofort dem Spieler zuweisen. Das bedeutet, dass unsere hierarchische Zustandsmaschine für Spieler jetzt einen Verweis auf den Spieler hat Wir wollen also sicherstellen, dass dieses Skript auf Rady die Zustandsmaschine einrichtet, indem es sie mit dem Spieler als Agenten initialisiert Lassen Sie uns also eine Funktion erstellen, Rady unterstreichen und der Rückgabetyp wird ungültig ist so ziemlich immer für fertige Funktionen, weil das eine Standard-Node-Funktion ist , die für die Einrichtung Ihres Nodes gedacht ist, wie in einem dieser Knoten hier auf der linken Seite, etwas, das innerhalb Ihrer Szene existiert , nachdem all ihre Eigenschaften definiert wurden Die Ready-Funktion führt also den Code aus, sodass, wenn das Objekt fertig ist, einige letzte Einrichtungsschritte ausgeführt werden also sehr häufig verwendet bevor das Objekt wirklich in der Szene ausgeführt wird, aber die wesentlichen letzten Einrichtungsschritte erledigt Während wir damit weitermachen, werde ich auch einige neue Konzepte vorstellen. Also zuerst die Assert-Aussage. Geben wir also assert ein. Das bedeutet also, dass Sie eine Bedingung bestehen und erwarten, dass sie als wahr bewertet wird. In diesem Fall wollen wir also überprüfen, ob der Player tatsächlich im Inspektor eingestellt wurde. Wann immer du hier eine Exportvariable festlegst, bist du im Grunde darauf angewiesen der Designer oder wer auch immer das Spielprojekt eingerichtet hat, diese Felder tatsächlich ausfüllt, und es ist sehr einfach eines davon zu definieren, vor allem, wenn du viele Skripte hast, die mit diesen Exportvariablen herumlaufen . Sie sind sehr praktisch um Dinge im Inspektor einzurichten, aber sie sind anfällig für Benutzerfehler. Wir können also einfach behaupten, dass der Spieler nicht Null ist. Jetzt siehst du, ich mache ein Ausrufezeichen und dann ein Gleichheitszeichen. Das Ausrufezeichen bedeutet, dass Sie alles, was Sie testen möchten , umkehren Wenn also Spieler gleich Null ist, was eigentlich zwei Gleichheitszeichen wie dieses wären, dann würden Sie überprüfen , ob der Wenn Sie jedoch ein Ausrufezeichen und ein Gleichheitszeichen verwenden, dann sagen Sie, dass der Spieler es nicht ist , und wann immer Sie eine Aussage machen, haben Sie die Möglichkeit , auch eine optionale Fehlermeldung weiterzugeben eine optionale Was soll es also demjenigen sagen, der das Skript ausführt , wenn diese Bedingung nicht erfüllt Also in diesem Fall würde ich wollen, dass so etwas wie Spieleragent auf dem HSM eingestellt Also hierarchische Zustandsmaschine. Also ich stelle es hier oben auf und erwähne sehr deutlich, dass es sich um eine hierarchische Zustandsmaschine handelt eine hierarchische Zustandsmaschine handelt Wenn Sie also jemals Fragen dazu haben, warum HSM so ist, nun, es ist genau da oben, also lassen Sie uns das in Aktion zeigen Wenn ich die Szene starte, wird es keinen Fehler geben, weil wir den Player-Node als Referenz in der Exportvariablen für einen Player festgelegt haben den Player-Node als Referenz in der Exportvariablen für einen Player Aber wenn ich den Player hier deaktiviere und wir ihn ausführen, erhältst du sofort eine Fehlermeldung Es wird heißen, dass die Behauptung fehlgeschlagen ist. Der Spieleragent muss auf dem HSM eingestellt sein. Die Behauptung ist also nur eine Überprüfung, um sicherzustellen , dass das, was Sie für wahr halten, auch wahr ist Schreiben von Aussagen gegen eine Bedingung ist also die allgemeine Idee des Testens innerhalb der Programmierung im Allgemeinen. Um weiter zu gehen, würden Sie Unit-Tests oder Integrationstests mit einem Test-Framework wie GD Unit oder GUT Godot Unit Testing schreiben einem Test-Framework wie GD Unit oder GUT Godot Unit Testing Das würde definitiv den Rahmen dieser Kursreihe sprengen , aber es ist etwas, das Sie nachschlagen sollten, wenn Sie später Zeit haben , denn wenn Sie Tests schreiben, stellen Sie sicher, dass Ihr Code auch wirklich gut geschrieben ist, und das kann auf stellen Sie sicher, dass Ihr Code auch wirklich gut geschrieben ist, lange Sicht hilfreich sein Bugs frühzeitig erkennen. Lassen Sie uns damit weitermachen. Wir werden nur diese kleinen Assert-Aussagen wie diese verwenden . Sie können sehen, wie es funktioniert. Wenn die Bedingung fehlschlägt, erhalten wir eine Nachricht, die uns darüber informiert, dass, oh, wir vergessen haben, etwas einzustellen , was wir hätten einstellen sollen. Es ist also eigentlich ziemlich praktisch. wir also sicher , dass wir in Limbo HSM erneut den Spieler zuweisen Und dann lassen Sie uns das HSM selbst einrichten. Also werde ich das tatsächlich zu einer separaten Funktion machen , weil das ein paar verschiedene Dinge tun wird Lassen Sie uns also hier unten eine weitere Funktion erstellen, Funktion. Und wenn ich Funktion sage, meine ich wirklich FU und C, sag einfach. Underscore hat HSM eingerichtet, und dann hatten die Klammern, der Abbiegepfeil und das Leerzeichen ein zusätzliches Leerzeichen Was wir also auf der Zustandsmaschine aufrufen wollen , ist Initialisierung, und wir müssen einen Agenten übergeben Wie ich bereits erwähnt habe, ist der Agent in diesem Fall der Spieler, der den Spieler weiterleitet, und dann müssen wir Setup HSM aufrufen Innerhalb der Bereitschaftsfunktion. Unterstreichen Sie also Setup HSM. Okay, um das durchzugehen, ich mache es zu einer privaten Funktion mit dem Unterstrich hier, was bedeutet, dass wir das nur innerhalb dieses Player-HSM-Skripts ausführen sollten innerhalb dieses Player-HSM-Skripts Die Initialisierung erledigt das gesamte Hintergrund-Setup für die Zustandsmaschine und sorgt dafür, dass sie mit dem Spieler als Agenten funktioniert Die andere Sache, die wir hier tun müssen ist den Anfangsstatus festzulegen Welchen Status werden wir also zuerst ausführen? Lassen Sie uns auch den Limbo HSM-Knoten in Player-HSM umbenennen. Ich möchte das auch mit dem angehängten Skript synchronisieren Also Spieler HSM hier. Entspricht Spieler HSM innerhalb des Szenenfensters. Und dann der Limbo-Status hier, wir nennen das den Verschiebestatus und fügen ihm dann ein neues Skript auch ein Vorteil , wenn Sie ihn umbenennen , bevor Sie das Skript anhängen. Wenn Sie mit der rechten Maustaste auf den Status klicken und dann das Skript anhängen, werden Sie feststellen, dass der Name des Skripts standardmäßig auch dem Namen des Knotens entspricht Es ist also generell eine gute Idee, diese drei Dinge zu synchronisieren , um die Dinge zu organisieren Und wir speichern das vorerst einfach standardmäßig im Player-Ordner vorerst einfach standardmäßig und lassen es uns von Limbo State erben Erstellen. Okay, also ich nenne das Move State, Klassenname Move State. Wir könnten das tatsächlich auch für den Feind wiederverwenden . Da sie alle im Wesentlichen dasselbe Animations-Setup verwenden werden . Also im Bewegungsstatus benötigen wir die Namen von zwei Animationen, nämlich unserer Animation im Leerlauf und unserer Bewegungsanimation, die gerade ausgeführt wird. Also werde ich Export für Idl-Anim sagen und wir werden diesem Einstellungstyp einen Zeichenkettennamen Und wir werden den Standardwert auf Idle setzen. Nun, das Und-Zeichen hier einzufügen , um daraus einen Zeichenkettennamen zu machen, ist eigentlich optional Wenn es hier als Stringname deklariert , wird die Variable automatisch konvertiert Es ist also optional, wenn du das als Ah machen willst, also lass uns export var machen. Ich nenne es einfach Run-Animation , weil es in diesem Projekt standardmäßig so heißt , und wir machen das Gleiche wie Ampersand Wenn Sie hier ein paar Kommentare einfügen zwei Hashtags, werden die Kommentare im Inspektor angezeigt Wenn ich also zum Inspektor gehe und den Mauszeiger über die inaktive Animation bewege, können Sie sehen, dass die Kommentare dort automatisch angezeigt werden, was sehr praktisch ist Sie können auch sehen, wie die Eigenschaft als Zeichenkettenname mit dem Standardwert idle oder run für definiert ist als Zeichenkettenname mit dem Standardwert idle oder run für definiert . Aus diesem Grund möchten wir sicherstellen, dass unsere Namen übereinstimmen, indem wir im Animation-Player überprüfen dass unsere Namen übereinstimmen, indem wir im Animation-Player Sie können also sehen, dass ich ein Idol in Kleinbuchstaben gemacht habe, ein Run in Kleinbuchstaben Bei der Verwendung dieser Zeichenketten wird zwischen Groß- und Kleinschreibung unterschieden. Stellen Sie also sicher, dass es hier und hier übereinstimmt, was auch immer es im Animations-Player für Leerlauf und Ausführung angezeigt wird. Okay, also werde ich hier mit der rechten Maustaste auf den Namen Limbo State klicken und das Symbol nachschlagen Und Sie werden sehen, dass es eine Reihe von speziellen Methoden gibt , mit denen dieser Knoten betreten, verlassen, einrichten und auch aktualisieren Das sind also landesspezifische Methoden. Sie klingen irgendwie ähnlich. So, wie Sie es auf einem Standard-Gadot-Knoten hätten. Der Unterschied besteht jedoch darin , dass diese nur ausgeführt , wenn die Zustandsmaschine diesen Status tatsächlich verwendet Die Zustandsmaschine führt jeweils nur den Code eines der Zustände aus, und die anderen Staaten sitzen im Grunde einfach passiv da, bis die Zustandsmaschine festgestellt hat, dass es Zeit ist, in einen anderen Zustand überzugehen Das heißt, du kannst im Grunde vier Codesätze schreiben und es wird jeweils nur einer ausgeführt, und das ist sehr praktisch, um zu verhindern, dass unnötige Dinge passieren, während dein Charakter nicht tun sollte Zum Beispiel sollte ein Charakter nicht angreifen, wenn der Charakter nur läuft und es keine Angriffseingabe gibt. Daher lässt du nicht zu, dass dieser Code ausgeführt wird, indem du ihn mit einer Zustandsmaschine verwaltest. Okay, wir wollen also mit dieser Enter-Funktion beginnen. Das virtuelle Schlüsselwort für diese Funktionen bedeutet , dass es zwar eine Standardimplementierung für die Funktion gibt , wir aber unseren eigenen benutzerdefinierten Code schreiben können, völlig ändert, was er tut, wenn diese Funktionen tatsächlich ausgeführt werden. Schauen wir uns das Move-State-Skript und wir werden die Funktion underscore Enter ausführen Was soll also passieren, wenn der Move-Status in die Zustandsmaschine übergeht Wir wollen also den Animations-Player nehmen und seine Animation entweder auf Leerlauf setzen oder laufen lassen je nachdem, ob sich der Charakter bewegt oder nicht. Okay, jetzt zu unserem Bewegungsstatus, wie bekommen wir einen Verweis auf den Animations-Player? Die Idee ist also, dass es für unseren Agenten nur einen Animationsspieler geben wird, den Animationsspieler des Spielers. Es gibt mehrere Möglichkeiten, wie Sie diese Referenz tatsächlich in Ihr Move State-Skript einfügen können. Ich werde einfach versuchen, den zu zeigen , der mir spontan einfällt. Ich denke, das wäre hier am praktischsten. Wenn wir also zum Player HSM gehen, können wir eine Referenz zum Animation-Player exportieren Also machen wir das beim Export Var Animation Player und dann Colon Animation Player Okay, ein Kommentar, um klarzustellen, dass dies der Animation-Player des Players ist , und dann weisen wir ihn im Inspektor zu. Nun, der Grund, warum ich das in diesem Skript mache nicht in den Drehbüchern für Kinder, wie in den Staaten, ist, dass ich hier nur eine exportierte Referenz haben will, und dann verwenden wir sie, um den Animation-Player aus unseren Zustandsskripten zu bekommen . Wenn wir also in das Move-State-Skript springen, könnte ich einfach sehr schnell die Referenz abrufen, die das Player-HSM hier oben hat, indem ich etwas wie Get Parent und dann Dot Animation Player mache Get Parent und dann Dot Animation Player Das ist also wirklich alles, was Sie dort tun müssten. Und jetzt können wir das einer lokalen Variablen zuweisen , wenn wir wollen. Eine andere Option wäre, dass wir eine Methode haben könnten, die das immer bekommt, oder wir könnten es hier lokal zwischenspeichern. Also müssen wir nur diesen Wert hier nehmen und ihn dann einer lokalen Variablen zuweisen. Also var, ich sage Underscore Animation Player, was vom Typ Animation-Player ist Dann könnte es auf Enter stehen, aber ich werde es später auf Setup ändern Wir machen den Underscore Animation Player. Gleich, Elternteil werden. Ja. Sie können sehen, dass es automatisch vervollständigt wird. Dort wurde der Funktionsname Das sollte deine komplette Zeile hier sein. Sie jetzt die Eingabetaste drücken, wird der Animation-Player dem Animation-Player der Eltern zugewiesen der Animation-Player dem Animation-Player . Das macht es also etwas einfacher, als für jedes dieser Zustandsskripte eine Exportvariablenreferenz verwenden zu müssen . Die Zustandsskripte hängen stattdessen nur davon ab dass das übergeordnete Element einen Verweis auf den Animations-Player hat, was ich für fair halte, da ein Player-HSM steuert sowieso die Animationen auf dem Player Ich denke also, dass das Setup in diesem Fall Sinn macht. Anstatt auf Enter zu drücken, das jedes Mal aufgerufen wird der Charakter den Status betritt, werde ich die Setup-Funktion implementieren. Funktion, Unterstrich Setup und dann automatische Vervollständigung, die den Wert void zurückgibt Wir nehmen diese Zeile und stellen sie hier so auf. Das Setup läuft also nur einmal, wenn die State Machine initialisiert wird Im Grunde müssen wir den Animations-Player also nicht jedes Mal aufrufen, wenn wir den Status aufrufen, sondern nur ein festgelegtes Was wir nun bei Enter erreichen wollen, ist, dass wir die richtige Animation abspielen. Im Moment haben wir also nicht die richtige Methode, die Animation zu bestimmen, weil unser Code dafür tatsächlich im Player-Skript gefangen ist, wobei diese Richtung auf eine lokale Variable gesetzt ist. Also müssen wir das später herausziehen, damit es vollständig funktioniert. Aber was wir jetzt tun können, ist Animation-Player mit Punkt abspielen zu lassen und sagen wir einfach, fangen wir mit der Animation im Leerlauf an. Nein, ich füge hier die Variable ein, einen Verweis auf die Animation im Leerlauf , der in den Namen der Zeichenfolge aufgelöst wird. Es wird also ein Zeichenkettenname erwartet, aber es fällt uns nicht schwer, ihn hier unten einzugeben. Wir wollen sicherstellen, dass es die Variable ist , damit wir immer noch die Möglichkeit haben sie im Inspektor zu ändern, falls das Sinn macht. Im Allgemeinen gilt: Wenn Sie etwas ändern möchten, das ist eine Zeichenfolge, möchten Sie es in eine Art von Variable umwandeln, anstatt es jedes Mal, wenn Sie im selben Skript darauf verweisen, hart einzugeben . Manchmal, wenn die Nachricht nur einmal an einer bestimmten Stelle verwendet werden soll, ist es völlig in Ordnung die Zeichenfolge Ihres Codes stattdessen in Ihren Funktionscode einzugeben. Das kann auch in Ordnung sein. Okay, es wird also die Animation im Leerlauf abspielen, sobald der Verschiebestatus beginnt. das zu testen, wollen wir nun den automatischen Lauf im Animation-Player ausschalten . Oder vielleicht tun wir das auch nicht. Lass uns das Spiel beenden und es so laufen lassen, wie es ist, und es sollte eigentlich in die Leerlaufanimation übergehen , dachte ich zumindest. Versuchen wir also hier, die automatische Wiedergabe beim Laden auszuschalten. Jetzt, ohne Autoplay beim Laden, sollte es meiner Meinung nach nichts abspielen Und so haben wir immer noch das Problem dass es so aussieht, als würde der Status nicht eintreten, weil die Animation nicht abgespielt Was wir also tun können, um das zu beweisen , ist, zurück in den Skripteditor zu gehen. Und ich werde hier einen Breakpoint setzen , indem ich mit der linken Maustaste links neben der Zeilennummer im Skript klicke. Und das bedeutet , dass, wenn es auf diese Codezeile trifft, es kaputt geht und wir sehen können, was im Debuker passiert Also werde ich auf Play klicken und es wird dort nicht angezeigt, was bedeutet, dass der Status nie wirklich eingegeben wurde was bedeutet, dass der Status . Es ist nicht aktiv. Das bedeutet, dass wir zum HSM-Skript zurückkehren und sicherstellen müssen , dass der Bewegungsstatus zu Beginn des Spiels tatsächlich aktiv ist Beginn des Spiels tatsächlich aktiv Gehen wir also zum Spieler HSM über. Und ich glaube, was ich hier vergessen habe, war, Set auf dem Player HSM selbst als aktiv zu bezeichnen Set auf dem Player HSM selbst als aktiv Also wollen wir active auf true setzen. Wir haben initialisiert, wodurch das Setup ausgeführt wird, aber wir haben es nicht aktiviert, wodurch die Zustandsmaschine tatsächlich gestartet wird Wenn wir jetzt also auf Play drücken, drücken wir Move-Status die Enter-Zeile Das beweist also, dass der Bewegungsstatus tatsächlich von der Zustandsmaschine erkannt wird . Um etwas detaillierter zu werden, können Sie sich den Stack-Trace unten ansehen, und Sie können, wenn Sie aufmerksam lesen, sehen, dass die Funktion Move State Enter ausgeführt wurde, und sie lief, nachdem das Setup HSM ausgeführt wurde, und Sie können tatsächlich hier klicken und zu der Codezeile springen, die dazu geführt hat, dass Enter im Verschiebungsstatus ausgeführt Weitere Informationen finden Sie hier unter set Active true, wodurch die Eingabetaste für den ersten Status aufgerufen wird, der ausgeführt wird Und das alles geschah, wenn Sie in der unteren Zeile auf Ready Setup HSM klicken der unteren Zeile auf Ready Setup HSM So kann man im Grunde sehen, was dazu geführt hat, dass Enter aufgerufen wurde. Es war also die Bereitschaftsfunktion auf dem HSM, die sogenannte Setup-HSM, die mit dem Aufruf von set active und dann set active den Move-Status zum Laufen brachte Wenn Sie es noch nicht getan haben, können Sie diesen Breakpoint deaktivieren und Sie können hier nach unten klicken, um fortzufahren, oder F 12 auf der Tastatur drücken, und Sie können sehen, dass der Ruhezustand ausgeführt wird Wenn Sie den Status in „Ausführen“ ändern möchten, also „Ausführen “ nehmen und „Leerlauf-Animation abspielen“ durch „Run-Animation abspielen“ ersetzen , klicken Sie auf „Abspielen Und jetzt können Sie sehen , dass die Run-Animation abgespielt wird, wenn der Status wechselt. Im nächsten Video konzentrieren wir uns also darauf, den Bewegungsstatus mit Spielereingaben zu steuern den Bewegungsstatus mit Spielereingaben , um sicherzustellen, dass wir die richtige Animation zur richtigen Zeit abspielen . 7. Spielereingabe als Komponente: unserem Bewegungsstatus wird die Animation für unseren Charakter auf dem Animations-Player abgespielt , aber im Moment hat er nicht den Code, um zu wissen, wann zur Run-Animation gewechselt werden muss, wenn es tatsächlich Spielereingaben gibt. Um das zu handhaben, können wir, wenn wir uns das Spielerskript ansehen, sehen, dass hier die Richtung für den Spieler ermittelt wird , und wir machen das mit einer lokalen Variablen für die Richtung. Das funktioniert also für diese physikalische Prozessfunktion, aber dann können wir die Eingaberichtung nirgendwo anders als hier verwenden . Also würden wir das auf eine Art Eigenschaftsvariable übertragen wollen , auf die von anderen Skripten zugegriffen werden kann. Nun könnten wir hier so etwas wie die VR-Richtung von Vektor zwei machen und dann genau hier ändern, und dann genau hier ändern um die Richtung der lokalen Variablen festzulegen. Und das wäre wahrscheinlich die einfachste Option. Zusammen. Ich denke jedoch, wenn wir diesen Weg weitergehen und den gesamten Input in das Körperskript des Spielercharakters einfügen gesamten Input in das würden, dann würden wir wirklich eine Trennung von Bedenken durchbrechen. Körperskript des Spielercharakters geht es also hauptsächlich nur darum, den Spieler zu bewegen. Wenn wir die gesamte Eingabefunktionalität hinzufügen und die Eingaben aller Spieler einholen, dann wird das Skript jetzt zwei oder drei oder sogar mehr Zwecke erfüllen zwei oder drei oder sogar mehr Zwecke während wir das Spielerskript immer weiter überladen Also werde ich versuchen, dies in ein separates Node-Skript zu bringen ein separates Node-Skript , das unser Spielerskript weiterhin verwenden kann, aber wir können auch, sagen wir, auf unsere Status verweisen, um alle Eingaben für unseren Spielercharakter zu verarbeiten alle Eingaben für unseren Spielercharakter Klicken wir also mit der rechten Maustaste auf den Player-Node und ich füge einen untergeordneten Node hinzu. Geben wir hier den Knoten ein. Das wird also nur eine einfache Knotenklasse sein, create. Und ich möchte das so umbenennen, dass es Spielereingabe ist. Lassen Sie uns ein Skript daran anhängen. Rechtsklick Skript anhängen, Spielereingabe. Und wir können ihm den Klassennamen und die Spielereingabe geben, sodass er einfach in einer Exportvariablen referenziert werden kann . Jetzt müssen wir das aus unserem Player-Skript übernehmen, und ich werde einfach C steuern, und ich werde einfach C steuern, es in die Spielereingabe einfügen, damit ich es dort platzieren kann. Aber wo wir eigentlich die Richtung herausfinden wollen ist innerhalb der Eingabemethode. Im Moment führt der Physikprozess also im Spielerskript Physikprozess also im Spielerskript jeden physikalischen Verarbeitungsframe unseres Spiels aus, was standardmäßig etwa 60 Mal pro Sekunde der Fall ist. Wir drücken die Tasten wahrscheinlich nicht 60 Mal pro Sekunde, das ist also eine Menge unnötiger Get Vector-Aufrufe und für einen Spielercharakter wäre das wahrscheinlich nicht so wichtig. Aber im Allgemeinen denke ich, dass es im Player-Skript etwas besser sein könnte , die Richtungseingabe innerhalb der Eingabemethode Underscore der Funktion zu handhaben innerhalb der Eingabemethode Underscore der Funktion Funktion unterstreicht also die Eingabe, im Grunde genommen wird jedes Mal, wenn ein Eingabeereignis an das Spiel gesendet wird, diese Methode durchlaufen und prüfen , ob es einen Code gibt, auf den es reagieren kann Und die Art und Weise, wie wir überprüfen, ob das Ereignis für uns tatsächlich relevant ist, besteht darin , den Namen der Aktion auf dem Ereignis selbst zu überprüfen Namen der Aktion auf dem Ereignis selbst Also geben wir es ein, und ich werde eine neue Methode erstellen, falls Underscore Bewegungsaktion ist Und wir werden das Ereignis an diese Funktion übergeben. Dann werden wir ein paar Sachen machen. Andernfalls werden wir einfach bestehen und noch nichts tun. Was ist die Aktionsfunktion I Movement? Normalerweise schützen wir uns nur vor anderen Arten von Aktionen, und wir wollen die Eingabe nur verarbeiten , wenn es sich bei der Aktion um eine Bewegungsaktion handelt Wir sagen also, Funktion ist Bewegungsaktion. Vom Typ Ereignis, Eingabeereignis. Und dann wird das einen booleschen Wert zurückgeben. Ein boolescher Wert ist also ein wahrer falscher Wert. Ist es eine Bewegungsaktion? Wahr oder falsch? Also das wird ungefähr so aussehen. Ereignis zurück, das eine Aktion ist, und wir werden diese Namen für den Moment einfach kopieren und einfügen. Okay, wir können hier sehen, dass ich dieselbe Zeichenfolge wiederhole , die hier oben steht. Also generell würde ich versuchen, diese in eine eigene separate Variable zu bringen. Aber wir könnten ja, warum machen wir das nicht sofort? Und dann zeige ich dir einen Schritt wir sogar noch weiter gehen können. Lassen Sie uns hier eine Variable platzieren, Var left action oder sagen wir einfach, var left ist vom Typ Zeichenkettenname, und sie wird genau hier diesem Wert entsprechen . Also lassen Sie uns mit Control C das kopieren, es hier einfügen und dann wähle ich es wieder aus. Ich drücke Strg R, um zu suchen und zu ersetzen, und ich werde es durch links ersetzen. Wenn Sie dieses Tool jetzt verwenden, ersetzt es das, was Sie aktuell ausgewählt haben. Also möchte ich das durch den linken Namen ersetzen , also werde ich auf Ersetzen klicken. Nun, die zweite, zu der es automatisch springt oder vielleicht auch nicht, Äh, genau hier, wir wollen das Ampersand-Anführungszeichen links behalten Ampersand-Anführungszeichen Klicken wir also auf Nächstes Spiel und wir werden hier unten herausfinden, dass wir das durch links ersetzen wollen , also klicken Und das wird im Grunde genommen alles sein. Wir sollten uns wahrscheinlich auch jetzt einfach um diese Fehlermeldung kümmern . Also werde ich diese ferne Richtung angeben, und wir werden uns in einer Minute darum kümmern , das richtig zuzuweisen Okay, damit ich die Fehlermeldung gelöscht habe, kannst du dir das Skript für den Moment speichern Im Moment gibt die Bewegungsaktion also zurück, ob es sich bei der Aktion um die linke Aktion handelt. Stimmt der Name der Aktion auf dem Event also mit dem Namen auf der linken Seite überein? Jetzt haben wir drei weitere Aktionen, also müssen wir hier drei weitere Bedingungen überprüfen. Lassen Sie uns das schnell herausbringen. Ich wähle dieses Steuerelement X um es auszuschneiden, tippe es richtig ein. Gehen Sie hier runter, erstellen Sie eine neue Variable var right, string name equals, und dann Control V, um sie einzufügen Also haben wir die Variable dem Stringnamen rechts zugewiesen Und mach dasselbe für up. Also wähle das aus. Drücken Sie X zum Ausschneiden, tippen Sie nach oben. Geh hier runter. Var up ist vom Typ Zeichenkettenname und entspricht Strg V, um es einzufügen N. Und nur noch einmal. Control X. Geben Sie runter ein, gehen Sie hier runter, runter, Zeichenkettenname ist gleich, Strg V, fügen Sie es ein Okay, jetzt haben wir unsere vier Variablen, die den tatsächlichen Zeichenkettennamen entsprechen , die wir wirklich an Methoden wie diese übergeben Wenn du noch einen lustigen Trick willst, könntest du sie so mit der Tabulatortaste überklicken, direkt hinter dem Gleichheitszeichen-Treffer-Tab auswählen, hinter dem Gleichheitszeichen-Treffer-Tab, hinter dem Gleichheitszeichen-Treffer-Tab, hinter dem Gleichsinus-Treffer-Tab, so. Und du kannst sie alle aneinanderreihen und es sieht hübsch aus und so. Könnte etwas lesbarer sein. Es liegt an Ihnen, ob Sie die Rechnung haben möchten oder nicht. Okay, aber jetzt ist es wichtig , diese Methode zu beenden, wir müssen die anderen Aktionen überprüfen. Also werden wir uns um den Weltraum kümmern. Und dann das gerade Linienzeichen, das Shift ist und direkt unter der Rücktaste die vertikale Linie Also die vertikale Linie, vertikale Linie, und dafür musst du die Shift-Taste gedrückt halten , zumindest auf meiner Tastatur Diese beiden vertikalen Linien bedeuten also oder. Ich denke, du könntest das tatsächlich eingeben oder so, und es wäre dasselbe. Und wir könnten das einfach versuchen, wenn das tatsächlich ein bisschen einfacher zu lesen ist und Event Dot ist Action, und wir wollen Right. Halte durch. Schreiben Sie den Variablennamen. Gut. Also, es sieht so aus, als ob das funktioniert. Also lass uns das einfach nochmal machen oder Event I Action up oder Event ist Action down. Okay, hoffentlich macht das Sinn. Wir prüfen, ob es sich bei dem Ereignis um Links-Aktion, Rechts-Action, Up-Action oder Down-Aktion handelt. Also, diese Linie ist ein bisschen lang. Sie können diesen Grenzwert vertikal sehen. Das sind hier also nur allgemeine Richtlinien. Sie können sehen, dass wir 107 Zeichen in dieser Zeile haben . Kein Problem. Ich meine, ich denke, es ist ziemlich lesbar, aber wenn Sie möchten, dass Ihr Code vertikaler nach unten geht, können Sie ihn hier aufteilen, indem Sie die Eingabetaste drücken. Wenn ich hier Control S drücke , bekommen wir ein Problem. Es wird ein Ausdruck nach oder erwartet. Es weiß derzeit also nicht, dass wir versuchen, zu den nächsten Zeilen zu springen. Was Sie also tatsächlich tun müssen, ist direkt nach dem O einen Backslash zu setzen , und jetzt weiß es, dass dies in der nächsten Zeile so weitergeht Sie können also so weitermachen : Backslash Enter, um eine neue Zeile einzufügen, und dann Backslash Enter und fügen Sie eine neue Zeile und dann Backslash Enter und fügen Nun, ich würde argumentieren, dass das hier ziemlich sauber aussieht. Wir haben also unsere vier Bedingungen, und es wird sie alle überprüfen, und sobald eine von ihnen als wahr bewertet wird, wird sie als wahr zurückgegeben Und wenn keine von ihnen wahr ist, dann ist es falsch. Wenn es sich bei der Aktion also um eine Bewegungsaktion handelt, können wir unseren Bewegungscode verarbeiten. Okay, hier weisen wir den Vektor tatsächlich zu. Es gibt zwei Orte, an denen wir die Eingabe verwenden werden. Eine ist für die Blickrichtung und eine für die Bewegungsrichtung. Holen wir uns also die Variable für die Eingabe. Var-Eingabe ist vom Typ Vektor zwei Wir werden diesen Wert auf Import Dot G vector setzen. Und genau wie zuvor wollen wir links, rechts, hoch und runter. Okay. Und da ist unser Input. Wenn wir also eine Taste drücken, möchten wir die Richtungseingabe einstellen. Die Richtung wird also einfach dem Wert des Imports entsprechen. Aber mit der Richtung, in ist es etwas Besonderes. Ein Charakter in einem Zwei-D-Spiel mit vier Richtungen kann dem Vektor 00 nicht gegenüberstehen, weil das im Grunde genommen auf sich selbst schauen würde, nicht nach rechts, oben, links oder unten, was die einzigen Richtungen sind, in die er schauen kann. Wenn wir den zugewandten Vektor zuweisen, wollen wir das nur tun, wenn die Richtung nicht Null ist Wenn also die Eingabe nicht dem Vektor 20 entspricht, also für einen Vektor mit zwei Richtungen von Null, bedeutet das, dass X Null und Y Null ist. Denken Sie daran, dass Vektoren eine X- und Y-Komponente haben Vorausgesetzt, dass diese Bedingung erfüllt ist, können wir die Ausrichtung nehmen und das als Eingabe festlegen. Und wir werden diesen kleinen Pass hier loswerden , weil wir ihn nicht brauchen. Und dann hier oben, mit der Var zugewandt, wie vom Typ Vector Two. Wir können das einfach standardmäßig auf, sagen wir, Vektor zwei Punkt rechts setzen, was perfekt funktioniert. Wenn erwartet wird, dass unser Charakter beim Laden standardmäßig nach rechts schaut, könntest du das natürlich auch nach links machen, wenn du willst. Und dann die Richtung hier, wir wollen das durch Vektor zwei ersetzen oder wenn du etwas ausgefallener sein willst, obwohl das auch der Standardwert ist, könnten wir sagen, Doppelpunkt entspricht Vektor zwei Punkt Null Das hier bedeutet also, dass wir den Typ der Variablen aus der Zuweisung ableiten, und die Zuweisung ist ein Vektor zwei, was bedeutet, dass dieser automatisch einem Vektor zwei zugewiesen wird, was bedeutet, dass Sie nicht eingeben müssen Vektor zwei ist gleich Vektor zwei. Das sieht einfach lustig aus. Also, das kannst du auch einfach hier unten machen. Und mach es ein bisschen weniger wortreich, obwohl beide hier perfekt funktionieren werden Der einzige Nachteil ist, wenn Sie diesen Vektor mit zwei Punkten rechts in etwas wie eine Zeichenfolge umwandeln , dass das auch technisch korrekt sein wird , weil er jetzt der Zeichenfolge des Vektors mit zwei Punkten rechts zugewiesen wird, und das bedeutet, dass dies jetzt eine Zeichenfolge ist Da müssen Sie also ein wenig vorsichtig sein. Ich habe das nicht wirklich als Problem angesehen . Ich denke also, dass es in diesen Fällen den Typ der Variablen abzuleiten zu deklarieren durchaus vernünftig und in Ordnung ist, den Typ der Variablen abzuleiten, anstatt den Variablentyp direkt , und oft etwas einfacher Es liegt also an Ihnen, Sie können beides tun. Wenn ich die Dinge richtig betrachte, denke ich, dass das vorerst im Grunde unser Spielerskript ist. Wir kommen später zurück und fügen Signale hinzu. Okay, also lass uns in unserem Player-Skript die Dinge hier ändern. Anstatt also eine lokale Variable für Richtung zu haben und statt eines physikalischen Prozesses die Richtung zuzuweisen , klicken wir auf Export var input ist vom Typ Spielereingabe Und hier unten für den physikalischen Prozess wollen wir die aktuelle Richtung aus der Eingabe ermitteln Also var direction, und ich werde den Typ aus der Punktrichtung des Eingangs ableiten, der lokalen Richtung zugewiesen wird, und dann verwenden wir das für den Rest unseres Skripts, indem wir überprüfen, ob die Richtung tatsächlich ein Wert ist, der nicht Vektor 20 ist, was diese Zeile hier bedeutet Und wenn ja, nehmen wir die Richtung und multiplizieren sie mit der Geschwindigkeit Der Unterschied besteht jetzt darin, dass die Eingabe von einem völlig separaten Skript verwaltet wird. Unser Spielerskript ist übersichtlicher gehalten und wir haben eine wiederverwendbare Spielereingabekomponente , die für völlig unterschiedliche Charakterdesigns verwendet werden könnte völlig unterschiedliche Charakterdesigns die dieselbe Art von Spielereingabe benötigen, auch wenn der Charakter die Mechanik seiner Bewegung tatsächlich völlig anders handhabt . Lasst uns also auf das Spielerskript klicken und sicherstellen , dass Import zugewiesen ist. Wie zuvor könnten wir also die Funktion setzen, Unterstrich bereit stellen und sicherstellen, dass die Eingabe nicht Null ist, und ihr die Nachricht geben Eingabe muss zugewiesen werden damit sich der Körper des Charakters richtig bewegt, das Spiel startet und sicherstellt, dass unsere Bestätigung fehlschlägt, was gut ist Klicke auf den Spieler und weise die Eingabe der Spielereingabe zu, führe es noch einmal aus und sieh, ob es tatsächlich funktioniert. Und wenn du WASD verwendest, kannst du anhand der Eingaben aus unserem Player-Import-Skript sehen, dass es sich bewegt Eingaben aus unserem Player-Import-Skript 8. Animationen mit Signalen wechseln: Im Moment wird unsere Richtungseingabe von oben nach unten links und rechts durch das Spielereingabeskript gesteuert, aber wir haben noch nicht, dass die Animationen durch die Richtung in diesem Skript gesteuert werden. Wenn wir uns also das Move-State-Skript ansehen würden, könnten wir uns vorstellen, dass wir Lage wären, einfach einen Verweis auf die Spielereingabe zu nehmen und sie wie zuvor als übergeordnetes Element zu übernehmen. Diese Methode funktioniert zwar im Allgemeinen gut, hängt aber vom HSM-Skript des Spielers ab , das auf all diese Eigenschaften verweist Wenn wir das hierarchische State-Machine-Skript des Players zu irgendeinem Zeitpunkt ändern , kann das die Funktionsweise dieses Skripts beeinträchtigen, und das Skript ist auch quasi direkt davon abhängig, dass das übergeordnete Skript all diese Eigenschaften besitzt quasi direkt davon abhängig das übergeordnete Skript all diese Wir wären also nicht in der Lage, dies auf einer völlig anderen Zustandsmaschine wiederzuverwenden , auf der, sagen wir, kein Animation-Player verfügbar ist Als weitere Option können Sie also Blackboards verwenden Wir schauen also hier auf der rechten Seite nach, wenn Sie das HSM ausgewählt haben. Sie können sehen, dass der Blackboard-Plan eine Option ist Wenn Sie also einen Blackboard-Plan erstellen, teilt er allen untergeordneten Knoten im State-Machine-System worauf sie Zugriff haben werden Und in diesem Fall wollen wir die Richtung, in die der Spieler zeigt, eingeben Also werde ich hier auf dem Player-HSM einen neuen Blackboard-Plan erstellen und dann auf Verwalten klicken Wir können hier drüben eine Variable hinzufügen, und wir möchten hinzufügen, lassen Sie uns mit Facing weitermachen Wenn wir also über die Animationen sprechen, für uns eher die Richtung relevant ist für uns eher die Richtung relevant, in die der Charakter zu schauen versucht , als die Richtung , in die sich der Charakter bewegt. Das wäre normalerweise dasselbe, aber nicht immer. Also sehen wir hier und dann im Drop-down-Menü Vektor zwei, sodass wir hier auf Verwalten klicken und dann eine Variable hinzufügen können hier auf Verwalten klicken und dann eine Variable hinzufügen Und wir werden nach dem Richtungsvektor zwei suchen. Ändern Sie also den Typ von Float auf Vector Two. Und dann können wir auf Okay klicken, also um auch diese Richtung zu bekommen und sie in unseren verschiedenen Zustandsmaschinenzuständen zu verwenden, wollen wir zur Bindung und dann zur Richtung gehen , wir wollen sie an das Player-Import-Skript binden. Aber wenn wir das jetzt tun, wird nichts auftauchen. Eine der Einschränkungen, die das Lambo AI-System in Sicht hat, besteht also darin, dass, um eine Immobilie an den Blackboard-Plan zu binden, diese Eigenschaft variabel exportiert werden muss Wenn wir also zur Spielereingabe gehen, können wir hier die Richtung angeben und sie einfach beim Export angeben und dann speichern Wenn du also auf Player-Import klickst, wirst du sehen, dass die Richtung hier angezeigt wird. Technisch gesehen bedeutet das, dass du die Richtung ändern kannst , bevor das Spiel beginnt. Es wird sofort von dieser Import-Funktion überschrieben , sobald Sie eine Taste drücken Es gibt also nicht wirklich einen großen Nachteil. Es ist nur so, dass die Richtung angegeben werden muss , damit das funktioniert Auf dem HSM können wir uns jetzt an das Player-Inport-Skript binden, und wir werden nach der Direction-Eigenschaft suchen Wählen Sie also die Richtung und klicken Sie auf Öffnen. Okay. Wenn Sie das jetzt lesen, ist die Richtung jetzt an die Importrichtung des Spielers gebunden, was bedeutet, dass alles, was wir für die Importrichtung des Spielers festgelegt haben , auf diesem Blackboard wiedergegeben wird , und wir können das in unseren Skripten verwenden, wie zum in unseren Skripten verwenden, wie Wenn wir schon dabei sind, können wir den Animation-Player auch auf den Blackboard-Plan setzen, wodurch die Abhängigkeit zwischen dem Bundesstaat und dem HSM aufgehoben wird zwischen Lassen Sie uns eine Variable verwalten und hinzufügen, ich sage Animation-Player Und lassen Sie uns den Node-Pfad eingeben und auswählen. Ich glaube, das ist das, was wir hier wollen. Okay. Klicken Sie auf Okay. Und wir weisen das dem Animations-Player zu. Wenn wir also aus dem Blackboard für die Eigenschaft Animation Underscore Player lesen , sollten wir in der Lage sein, einen Verweis auf den Animation-Player zu erhalten Okay, wenn wir jetzt zu Move State wechseln, sieht das eher so aus Underscore Animation Player wird also Blackboard entsprechen Das Blackboard wird also zur Laufzeit auf der Grundlage des Blackboard-Plans erstellt Grundlage des Blackboard-Plans Das ist also im Grunde das Runtime-Objekt in dem wir die Variablen erhalten, die wir benötigen Also müssen wir Blackboard dot, Get VR, get underscore var ausführen und wir suchen nach dem Eigenschaftsnamen In diesem Fall wird das also der Animationsunterstrich-Player sein Die Standardeinstellung ist Null. Wir möchten, dass es sich beschwert, wenn es es nicht finden kann , weil das bedeutet, dass wir irgendwo in unserem Setup Jetzt können wir diese Zeile im Grunde entfernen, und jetzt hängt unser Skript überhaupt nicht mehr vom HSM-Skript ab Es hängt nur davon ab, ob Blackboard so eingerichtet ist, dass es über einen Animation-Player verfügt , der eine Fehlermeldung erhält wenn er keinen Animation-Player im Nun zur Richtung, ich schätze, wir müssen das nur auf den neuesten Stand bringen Also Funktion, Unterstrich Update und wir erhalten die aktuelle Blackboard-Variable Das wird also die Richtung VR sein. Es wird Blackboard dot Get VR entsprechen, und wir suchen nach einer Richtung Und wir können diesen Variablentyp nicht ableiten, weil wir nicht wissen, was Git VR hier eigentlich zurückgeben wird Deklarieren wir es also als Vektor zwei. Okay, jetzt haben wir die Direction-Eigenschaft und unser Skript muss nicht einmal etwas über das Spielereingabeskript wissen . Alles, was wir wissen müssen, ist, dass Blackboard über eine Richtungseigenschaft verfügt, die wir für unsere Animationen verwenden können Also ganz einfach: Wenn Direction nicht Null ist, das ist die Kurzform dafür, dann spielen wir die Run-Animation auf dem Animation-Player ab Unterstreichen Sie also Animationsspieler, Punkt abspielen, Animation ausführen, Ale, Animationsspieler, Punkt abspielen, Animation im Leerlauf Lassen Sie uns also weitermachen und auf Jetzt abspielen klicken und sehen, ob das funktioniert. Also wenn ICH WAR und D, dann kannst du sehen, dass wir die Animationsbewegung für unseren Charakter bekommen . Nun, hier gibt es einen großen Fehler, nämlich dass der Offset auf unseren Sprites nicht übereinstimmt Nun, das liegt in der Natur der Art wie die spezifischen Spritesheets eingerichtet wurden Ich denke, die Größe der einzelnen Frames stimmt nicht überein. Es entsteht also ein Offset. Nun, das können Sie entweder in einem Editor wie A Sprite korrigieren , wenn Sie der Künstler sind, oder wenn Sie es einfach zum Laufen bringen möchten In diesem Fall können wir das im Animation-Player tun Im Animation-Player können wir also sagen, wir überprüfen die inaktive Animation Und hier haben wir es hier zentriert, wie wir es erwarten würden. Wenn wir also zur Run-Animation von Run gehen, müssen wir nur sicherstellen, dass diese der Leerlauf-Animation übereinstimmt. Also werden wir die Position in jeder unserer Animationen mit einem Keyframe versehen wollen . Fügen wir also eine Spur hinzu, eine Eigenschaftenspur. Mal sehen, die Sprite Two D, weil wir über den Sprite-Offset sprechen, nicht über den Offset der Spielercharaktere Und dann wollen wir hier eine Position haben. Dann fügen wir einen Schlüssel hinzu. Im Moment ist es bei minus 14. Ich gehe nach Idle. Und dann werden wir dieselbe Immobilie im Voraus hinzufügen . Positionieren Sie also zwei D und fügen Sie dann den Keyframe hier hinzu. Der Grund, warum ich das mache, ist die Leerlaufposition bereits korrekt ist. Ich möchte also nicht, dass sich diese Änderung ändert, wenn ich den Lauf einrichte Wenn wir schon dabei sind, schauen wir uns den Tod an. Ich denke, die Todesanimation ist tatsächlich an der richtigen Stelle. Also müssen wir nur hier hingehen, den Track hinzufügen, Sprite zwei D, Position Okay, steck den Schlüssel ein. Okay, und dann sollte das gut sein. Jetzt müssen wir also den Wert für die Runde speziell auf Animation ändern . Drücken Sie also Q, um in den Auswahlmodus zu wechseln. Klicken Sie mit der linken Maustaste auf das Sprite. Du solltest diese große Kiste haben. Du kannst wahrscheinlich sehen , woher der Offset kam , weil es hier oben so viel Leerraum gibt. Aber wie dem auch sei, wir müssen nur W drücken und dann das Ganze nach oben bewegen. Lass mich die Transformation überprüfen. Ja, negative 27 Pixel. Ich glaube, das hatte ich und das war auch im Projektentwurf. Lassen Sie uns das also mit einem Keyframe versehen . Lass uns auf Play klicken und sehen, ob das besser ist Also WASD, es ist fast da, aber ich denke, es muss ein paar Pixel höher sein Also lass uns W und dann das nach oben verschieben. Lass uns 30 versuchen, W. N drücken, es ist immer noch nicht da. Okay, lassen Sie uns das weiter nach oben verschieben. Ich werde mir die Animation im Leerlauf ansehen. Okay. Und da stehen seine Füße auf dem Boden. Also lass uns wieder rennen. Okay, und seine Füße sollten hier oben sein, zwei Pixel unter dem Boden. Okay, dann im Leerlauf und dann rennen. Okay, ich habe vergessen, es mit einem Keyframe zu versehen. Also lass mich das noch einmal verschieben. Ich glaube nicht, dass wir den X-Offset brauchen. Lassen Sie uns das hier bei negativen 30 Pixeln als Keyframe eingeben. Okay, lassen Sie uns auf Play klicken und noch einmal testen. WASD. Das sieht für mich richtig machen wir also. Lass uns den Player hier mit Sop anschlagen. Und nur um das klarzustellen: Für eine längerfristige Lösung wäre es besser, die Animationsspitzen zu reparieren und einfach sicherzustellen, dass sie alle gleich groß sind, unabhängig davon, wie viel Bewegung in die Animationsspitzen zu reparieren und einfach sicherzustellen, dass sie alle gleich groß sind, unabhängig davon, den Animationen ist , sodass Sie nicht mit der Position herumspielen müssen Langfristig ist das etwas schwieriger zu handhaben, daher ist es besser, wenn es einfach direkt auf dem Animationsblatt fixiert direkt auf dem Animationsblatt Okay, was den Leerlauf und die Bewegung unserer Charaktere angeht, das Letzte, was wir für die Grundbewegung unserer Charaktere tun müssen , ist sie umzudrehen, wenn wir uns nach links bewegen , und dann zurückzudrehen, wenn wir uns nach rechts bewegen Das wird das nächste Video sein, also sehen wir uns im nächsten. 9. Umdrehen eines 2D-Charakters: Wir bewegen den Charakter also nach oben, unten, links und rechts, und er kann wieder in den Ruhezustand wechseln. Das ist großartig. Was wir hier allerdings ändern müssen, ist, dass unser Charakter in der Lage sein muss, von rechts nach links zu wechseln, je nachdem, ob wir eine linke oder rechte Eingabe haben. Also wollen wir den Sprite-Knoten grundsätzlich von links nach rechts umdrehen Nun, Sprite hat hier direkt einen Flip H. Wir könnten es sicherlich einfach in einem benutzerdefinierten Skript anweisen, das H umzudrehen je nachdem, was die Spielereingabe tut Um einen Schritt davon entfernt zu sein. Stattdessen könnten wir einen übergeordneten Knoten platzieren, sich selbst umdreht, wenn sich die Richtung der Spielereingabe ändert, und dann wird der Sprite-Knoten Richtung der Spielereingabe ändert, automatisch umgedreht, weil der Sprite-Knoten ein untergeordnetes Element dieses übergeordneten Knotens zwei D ist . Wenn ich also auf den Spieler-Knoten klicke und ein Kind hinzufüge, fügen wir einen Knoten zwei D hinzu, und dann nenne ich es Flip Two facing Two D's und dann nenne ich es Flip Two facing Two . Klicken wir mit der rechten Maustaste darauf und hängen Sie ein Wir platzieren das an der Standardposition, create, und geben dem Klassennamen den Klassennamen Flip Two gegenüber zwei D. Und das wird die X-Skala bei der Transformation umdrehen , je nachdem, ob der Charakter nach links oder rechts schaut. Okay, was bedeutet das also im Grunde? Wenn ich mir diese zwei leuchtenden D schnappe und sie auf zwei D umdrehe und sie dann wieder an die Stelle setze, wo sie vorher war, der Spitze der Hierarchie, drehe ich um, dass zwei D zugewandt sind, und dann hier auf der rechten Seite deaktiviere ich die Verbindung zwischen X und Y, weil wir nur die X-Skala ändern Okay? Geben Sie dann negativ eins für das X und Sie werden sehen, dass der Charakter nach links kippt Wenn wir eins bis zum X eintippen, das Zeichen die ursprüngliche Richtung , also nach rechts Natürlich müssen Sie bei der Einrichtung etwas vorsichtig sein . Wenn Sie Ihre Waffen unter die Kippe legen, sodass sie zwei Dno gegenüberstehen, bedeutet das, dass Ihre Waffen auch nach links oder rechts zeigen Nun, manchmal wollt ihr das, und in anderen Fällen ihr euer Projektilabschusssystem später nicht, ihr wollt nicht, dass es sich umdreht, je nachdem , was diese Knotenskala Aber wenn du, sagen wir, einen Speer in die Hand des Charakters legst, würdest du wahrscheinlich wollen, dass dieser Geist in die richtige Richtung zeigt , wenn du nach rechts schaust oder in die linke Richtung, wenn du Sie müssen also nur vorsichtig sein , unter welchen Knoten Sie hier platzieren, denn alles, was in der Hierarchie unter Flip to facing two D steht , wird jetzt umgedreht, sobald dieser übergeordnete Knoten Sie also einfach daran, was wem untergeordnet ist , und es sollte Ihnen gut gehen Also wollen wir innerhalb unseres D-Skripts „Flip to face two D “ eine Export-Variable hinzufügen Und wir werden Input sagen, was vom Typ Spielereingabe ist. Für den Moment bedeutet die Abhängigkeit von Spielereingaben, dass es sich bei diesem Skript speziell um ein Spielerskript handelt und nicht unbedingt von den gegnerischen Skripten verwendet wird. Für ein so kleines Skript könnte es sich in diesem Fall einfach lohnen, den direkten Verweis auf die Spielereingaben zu haben , denn das bietet dir die einfachste und praktischste Einrichtung. Und dann müssen Sie nur noch sicherstellen, dass die Eingabe tatsächlich im Inspektor zugewiesen wurde. Das können wir also mit dem Assert machen. Lassen Sie uns bereits eine Funktion ausführen, unterstreichen und dann bestätigen, dass die Eingabe nicht Null ist, und sagen um den Verweis auf den Spieler umzukehren , ist eine Eingabe erforderlich Sie können auch hier immer einfach zum Top-Hit-Spiel gehen und es wird Ihre Behauptung treffen, sodass der Test startklar ist Andernfalls können wir an dieser Stelle einfach den Signalzugriff von der Spielereingabe erhalten und ihn verwenden, um diesen Knoten umzudrehen, wenn sich die Blickrichtung ändert Soweit ich mich erinnere, habe ich die Signale noch nicht eingegeben. Wenn wir also mit der rechten Maustaste auf die Spielereingabe klicken Symbol suchen, wollen wir nach oben gehen und einige Signale deklarieren. Ein Signal ist also wie ein Ereignis. Wenn Sie aus anderen Sprachen wie C Sharp kommen , ist es ein Ereignis. Und in diesem Fall bedeutet das, dass etwas innerhalb Ihres Codes ausgelöst wird , und Sie möchten abonnierte Objekte darüber informieren , dass etwas passiert ist, und optional einige kontextbezogene Informationen oder Daten an das empfangende Objekt übergeben oder Daten an das Okay, lassen Sie mich weitermachen und eins deklarieren, und dann werde ich es etwas einfacher erklären Signal ist also das Schlüsselwort, und dann würden wir sagen, dass sich die Richtung geändert hat, und wir würden auch die Richtung angeben wollen, in der es sich geändert hat, also könnten wir Wert oder Gegenüberstellung sagen, und das wäre dann Typfaktor zwei. Also deklarieren wir den Parameter. Was wir an alle empfangenden Objekte senden , steht hier in diesen Klammern Das Signal hat sich also verändert. also das Ereignis ändert, in diesem Fall hier unten, wollen wir ein Signal aussenden, das alle abonnierten Objekte darüber informiert, dass alle abonnierten Objekte Wert des Gegenübers geändert hat Zu diesem Zeitpunkt können sie also in ihrem eigenen Code darauf reagieren Und das bedeutet, dass Sie nicht bei jedem einzelnen Frame-Update ständig überprüfen müssen, ob die Spielereingaben direkt angezeigt werden überprüfen müssen, ob die . Sie warten einfach darauf, dass das Skript Sie darüber informiert, dass sich der Wert tatsächlich auf einen anderen Wert geändert hat. Sie haben also diese aussagekräftigen Informationen und müssen nur einmal alle paar Sekunden aktualisieren, und müssen nur einmal alle paar Sekunden aktualisieren da Ihr Spieler seine Bewegungsrichtung nur einmal alle 3 Sekunden oder in diesem Fall die Blickrichtung geändert hat . Mit anderen Worten, Sie werden von einem Signal abhängig Ihren anderen Code auslöst, anstatt ständig manuell einen Wert auf Änderungen zu überprüfen also unsere Eigenschaft mit der Vorderseite hier unten haben, wollen wir sie nehmen und einen Setter hinzufügen , sodass wir, wenn sich der Gegenwert ändert, das Signal tatsächlich immer dann ausgeben, wenn es Wenn Sie also am Ende einen Doppelpunkt hinzufügen, können Sie Ihre Setter und Getter deklarieren Du kannst einfach einen von ihnen machen. Du musst nicht beides tun. In diesem Fall wollen wir also „Sollwert“ sagen. Und beachten Sie, dass dies in einer neuen Zeile steht. In diesem Fall deklarieren wir also tatsächlich eine Funktion Und das läuft immer dann, wenn wir den Wert dieser Eigenschaft auf etwas Neues setzen den Wert dieser Eigenschaft auf etwas Neues Wir ändern also die Standardeinstellung , indem wir nur den Wert festlegen und nichts anderes tun, um ihn festzulegen und zusätzlichen Code auszuführen. Wenn wir also den Wert festlegen, wollen wir Facing nehmen und ihn auf den Wert setzen. Das wäre also das, was es standardmäßig tut. Wenn Sie keine Setter-Getter-Funktionen deklarieren, wäre der Getter einfach eher so, rückwärts gerichtet, oder? Das würdest du erwarten Sie greifen über den Namen und das Gesicht auf die Eigenschaft zu, und sie würde den Wert zurückgeben, auf den sie gesetzt ist. Wenn Sie also keinen benutzerdefinierten Code für den Getter benötigen, brauchen Sie ihn nicht zu deklarieren, weil er das standardmäßig tut, und das ist es, was Facing standardmäßig tun würde Wenn Sie nun so etwas wie ein Signal ausgeben möchten, benötigen Sie den zusätzlichen Code Nun wollen wir sagen, dass Facing den Namen des ausgesendeten Signals geändert hat, also senden wir das Signal aus, was bedeutet, dass jedes Objekt es abonniert, jetzt benachrichtigt wird, aber wir wollen die Information über das Gegenstück weitergeben Also gehen wir gegenüberliegend weiter. Also nehmen wir diesen Wert, senden ihn über das Signal, und dann werden wir in unseren anderen Skripten diese Information empfangen und können entscheiden, was wir damit machen wollen. Aber es gibt noch einen anderen Trick, den ich hier zeigen möchte, nämlich dass wir nicht wollen, dass sich Veränderungen einstellen, wann immer wir den Nennwert festlegen. Dies könnte in jedem Frame auf den gleichen Wert gesetzt werden. Ich denke, dass der Bewegungsaktionscheck tatsächlich davor schützt , weil er nur ausgelöst würde wenn es eine echte Bewegungsaktion gibt, was in diesem Fall so wäre, als würde man die rechte Taste drücken oder die rechte Taste loslassen oder dasselbe für die anderen Richtungen. Aber es ist immer gut, bei der Programmierung defensiver vorzugehen. einfach davon aus, dass Ihre anderen Annahmen nicht unbedingt richtig sind, und schützen Sie sich dann davor. Also werden wir hier eine Wache aufstellen. Wenn die Ausrichtung bereits dem Wert entspricht, würde das bedeuten, dass es keine Änderung gibt. Also wollen wir einfach hierher zurückkehren. Wir müssen die Ausrichtung nicht festlegen , da der Wert bereits der Ausrichtung zugewiesen ist. Es ist bereits korrekt, und wir müssen das Signal nicht ausgeben, und wir sollten das Signal auch nicht ausgeben weil sich der Wert nicht wirklich ändert. Wir haben also diesen Schutz vor schlechten Anlagen auf dem gegenüberliegenden Grundstück. Aber wenn der Wachmann vorbei ist, stellen wir die Verkleidung ein und geben das Signal ab. Mit all dem wird das Signal jetzt ausgestrahlt. Und wir können einfach umdrehen und zwei D gegenüberstellen. Und nachdem wir bestätigt haben, dass Import nicht Null ist, wissen wir, dass es gesetzt ist. Wir können also zur Eingabe übergehen, dass die Punktzuweisung geändert wurde. Sie werden sehen, dass das Signal hier tatsächlich namentlich referenziert wird und dass es dieses kleine Wi-Fi-Symbol oder -Signal hat. Also haben wir die Flächen der Eingabepunkte geändert. Jetzt schauen wir uns den Signalnamen und wollen eine Verbindung herstellen also keine Verbindung her. Und was wollen wir damit verbinden? Nun, das wäre eine aufrufbare Funktion , die wir hier eingerichtet haben Um die Dinge so einfach wie möglich zu halten, sollten wir unten eine benutzerdefinierte Funktion erstellen Ich würde also sagen, dass die Ausrichtung des Unterstrichs geändert wurde. Es wird immer noch ein Fehler auftreten, weil es unserem Skript keine Funktion mit diesem Namen Wenn ich also ein paar Mal die Eingabetaste drücke, sagen wir, dass Funktion, Unterstrich bei Gegenüberstellung geändert wurde Nun, welche Parameter wird diese Funktion annehmen? Nun, sie nimmt alles auf, was in das Signal eingegeben wurde. In diesem Fall würden Sie also in die Richtung schauen. Also werde ich P sagen, mit dem Unterstrich nach vorne gerichtet, P wie im Parameter, um deutlich zu machen, dass dieser Wert von den Parametern stammt von den Parametern stammt , die an die Funktion übergeben wurden Und dann ist das ein Vektor zwei. Wir werden nichts zurückgeben, also kehren wir leer zurück. Und jetzt können wir den Code schreiben, der auf die veränderte Ausrichtung des Signals reagiert . Okay, also wenn die Ausrichtung geändert wird, wollen wir die X-Richtung der Ausrichtung nehmen und damit bestimmen, ob wir nach rechts oder nach links schauen sollen. Wenn also der Punkt X, der dem Punkt X zugewandt ist, ein positiver Wert ist, dann wollen wir die Skala X dieses Knotens nehmen , zwei D, die Umkehrung zum gegenüberliegenden Knoten, und wir wollen ihn gleich dem absoluten Wert des Skalenpunkts X setzen . Wenn Sie den absoluten Wert nehmen, Sie eine immer positive Zahl. also nach rechts schauen, machen wir unsere positive Richtung nach rechts. Wir wollen also immer nach rechts schauen wenn der Eingang tatsächlich nach rechts zeigt. Jetzt werden wir nichts anderes sagen. Wir werden etwas anderes sagen, wenn P, das X zugewandt ist, kleiner als Null ist, also wollen wir nicht, dass der Fall Null weil unsere Charaktere nicht in der Lage sein sollten, den 00-Punkt auf dem Vektor zwei zu sehen, nicht wirklich als Blickrichtung für diese Art von Zwei-D-Spiel existiert der nicht wirklich als Blickrichtung für diese Art von Zwei-D-Spiel existiert. Wir wollen also nichts tun, wenn das der Fall ist. Deshalb überprüfe ich ob der Wert kleiner als Null ist, weil weniger als Null eigentlich nach links zeigen würde. Also machen wir den skalierten Punkt X, und wir setzen diesen Wert gleich einem negativen mal dem absoluten Wert, skaliert mit Punkt X. Okay, das wird immer eine positive Zahl ergeben, und dann werden wir sie immer negativ machen Es gibt hier also wahrscheinlich ein paar verschiedene Möglichkeiten, das zu rechnen, aber ich denke, das sollte gut funktionieren Okay, also gehen wir zu Two D View. Wir klicken auf Flip to front two D und weisen dem Spieler eine Eingabe zu. Okay, da werden wir also das Signal bekommen. Wir werden in unserem Drehbuch eine Verbindung zu Rudy herstellen Okay, also wenn ich auf Play drücke, machen wir die richtige Bewegung Unser Charakter schaut nach rechts, und wenn ich nach links drücke, schaut unser Charakter nach links. Wenn wir das oben links machen, schauen wir nach links. Wenn wir es nach unten rechts machen, schauen wir nach rechts nach unten. Testen Sie einfach alle acht Richtungen, in die sich unser Charakter mit Tastatureingaben bewegen kann, und das sieht für mich gut aus. Um also ein bisschen vorausschauend zu denken, könnten wir uns diesen Code schnappen und ihn für eine andere Funktion herausziehen und könnten wir uns diesen Code schnappen und ihn für eine andere Funktion herausziehen und ihn in eine neue Funktion umgestalten Sagen wir Funktion aktualisieren, umdrehen, und das erfordert die Richtung, in die Also nach P gerichtet, Vektor zwei, und dann nehme ich das, schneide es hier ab und wenn es sich verändert, würde Update Flip P Facing nennen. Der Grund dafür ist, dass ich auch wiederverwenden kann, wenn es fertig ist. Also fertig, wir sagen einfach Update Flip Import mit Punktverstellung. Wenn unser Skript zum ersten Mal geladen wird, wollen wir die Richtung festlegen, unmittelbar bevor ein Import tatsächlich von unserem Player kommt , weil es der Fall sein kann, dass wir, sagen wir, bei Spielereingaben entscheiden , wir diese Richtung exportieren und dann die Standardeinstellung von Vektorpunkt nach rechts auf Vektor zwei Punkt links ändern Vektorpunkt nach rechts , weil wir aus welchem Grund auch immer unsere , die standardmäßig nach links zeigen. Damit können wir uns darauf vorbereiten, indem wir automatisch mit der richtigen Umkehrrichtung initialisieren, je nachdem , was die Eingabe sagt Also, das ist jetzt eine öffentliche Funktion. Wir könnten dies einfach von einem anderen Skript aus aufrufen, wenn es einen Fall gäbe , der nichts mit Import zu tun hat, in dem wir die Umkehrrichtung des Charakters ändern wollten. Vielleicht möchtest du während einer Zwischensequenz alle Spielereingaben herausschneiden und das Ganze manuell aufrufen. Ihr Charakter hat also nach rechts geschaut und in der Zwischensequenz soll er nach links schauen. Sie hätten also die Möglichkeit, einfach Update Flip aufzurufen , wenn Sie auf zwei D-Knoten umschalten. Okay, das eröffnet da definitiv einige Möglichkeiten. Und das ist so ziemlich alles, was wir für die WASD-Bewegung unseres Spielers tun müssen für die WASD-Bewegung unseres Spielers Es sieht gut aus. Ich finde, alle Anliegen sind ziemlich getrennt 10. Kartenebenen für Gras und Schmutzkacheln: Okay, also da die Bewegung und Animation unserer Charaktere im Grunde sowohl für Idol als auch für Run spielen, einschließlich des Richtungswechsels, denke ich, dass jetzt ein guter Zeitpunkt ist etwas Hintergrund einzubauen, damit das Spiel ein bisschen hübscher aussieht , anstatt nur standardmäßigen grauen Gadot-Hintergrund zu haben Lassen Sie uns also weitermachen und zu unserer Weltszene wechseln. Wenn Sie das nicht geöffnet haben, können Sie hier nach unten links gehen. Suchen Sie einfach nach World und Sie sollten in der Lage sein, World DottScn zu finden , wenn das derselbe Name ist, den Sie verwendet haben wie ich Und dann wollen wir in der Welthierarchie mit der rechten Maustaste klicken und einen neuen Knoten hinzufügen, und wir suchen nach einer Kachelkartenebene Sie können sehen, es gab einen anderen Knoten namens Tilemap, aber ich glaube, der ist veraltet, seit 4.3 und seit 14.41 und kurz vor dem Wechsel zu 4.5. Es wird auf jeden Fall empfohlen, Es wird auf jeden Fall empfohlen, zu Tilemap-Ebenen zu wechseln, wodurch die Tilemap in einzelne Ebenenknoten aufgeteilt wird, anstatt jede einzelne Ebene zu haben. In einer Kachelmap enthalten. Fügen wir also eine Kachelkartenebene hinzu. Und wir werden das so etwas wie Boden nennen, also werde ich es in Boden umbenennen. Und wenn Sie es unten ausgewählt haben, sollten Sie das Tilemap-Fenster haben. Also öffne das, falls es nicht schon geöffnet ist. Und dann müssen wir die Kunstgegenstände aus unserem Projekt finden. Also werde ich mich mit Kunst und dann mit den Kachelsets für Pixel-Crawler-Umgebungen befassen, und wir werden hier mit den Bodenfliesen arbeiten wollen hier mit den Bodenfliesen arbeiten Damit wir das umsetzen können, wollen wir nicht auf der Tilemap sein, sondern auf der Registerkarte „Kachelset Schauen Sie in der oberen rechten Ecke während Sie die Kachelkartenebene ausgewählt haben , und Sie werden das Kachelset als Ressource sehen , die Sie hier zuweisen können Sie möchten mit der linken Maustaste klicken und ein neues Kachelset Sobald Sie das unten getan haben, wird ein neuer Tilset-Tab angezeigt Wenn Sie es also in Boden umbenannt haben, schauen Sie oben rechts nach , wo es ausgewählt ist, und Sie sollten ein Feld für den Kachelsatz sehen Also wollen wir hier klicken und eine neue TileStrSource deklarieren Das machst du ganz unten. Hier sollten sich zwei Tabs auf die Kachelmap beziehen. Dabei handelt es sich um eine Kachelkarte , handelt es sich um eine Kachelkarte , diesen Kachelsatz auszuwählen und zu zeichnen , der zum Einrichten deiner Kacheln dient, und dann Kachelmap zum Zeichnen deiner und dann Kachelmap zum Zeichnen Also wollen wir zum Tile-Set gehen. Du solltest hier ein Kästchen sehen das wir die Bodenfliesen ziehen können. Suchen Sie also nach Bodenfliesen im Projekt. Es sind also Fußböden, Unterstriche, Fliesen, Punkt PNG, und wir ziehen das einfach per Drag-and-Drop hierher. Es wird dieses kleine Popup geben, das Sie fragt, ob Sie die Kacheln automatisch erstellen möchten , wir tun das Also machen wir weiter und treffen uns hier. Und dann werdet ihr im Vorschaufenster sehen , dass alle Kacheln automatisch in tatsächliche Kachelressourcen aufgeteilt wurden in tatsächliche Kachelressourcen , die wir im Spiel verwenden und aus denen wir malen können Die einfachste Art zu zeichnen wäre also , einfach zu Tilemap zu gehen und dann die Kacheln einzeln auszuwählen, die wir platzieren wollten Drücken Sie Q, um sicherzustellen, dass Sie sich im Auswahlmodus befinden. Und dann hier unten im Tilemap-Fenster wollen wir uns in den Malwerkzeugen befinden, also ist das D auf der Tastatur Und dann können Sie mit der linken Maustaste klicken, um die Kachel zu zeichnen. Sie können über eine Kachel gehen und linken Maustaste klicken und eine weitere Kachel ablegen. Du wirst sehen, dass das Tippen tatsächlich vor dem Spieler angezeigt wird . Das wollen wir nicht. Das kannst du machen, ist einfach den Boden nach oben zu bewegen und das wird automatisch sortiert, sodass der Boden unter dem Spieler ist. Das ist also der einfachste Weg, das zu tun. Das Auswählen der einzelnen Kacheln auf diese Weise funktioniert zwar , ist aber sehr, sehr mühsam Was wir stattdessen wahrscheinlich tun wollen, ist ein Gelände-Set auf der Grundlage dieser Grasplättchen zu erstellen und dieses dann zu verwenden , um automatisch zu zeichnen welches Kachel wir benötigen, je nachdem was an dieses Plättchen angrenzt, wenn überhaupt Wenn Sie also das Kachelset oben rechts erweitern, können Sie zu den Geländegruppen gehen und dann ein neues Element hinzufügen. Wir lassen es also so, dass es an den Ecken und Seiten passt, und du erweiterst Terrains und fügst ein Element hinzu Und wir können das einfach umbenennen, sagen wir, Grasgelände und die Farbe in etwas Grasigeres ändern , wie ein Grün Gehen Sie jetzt unten zum Kachelset und dann malen wir Wir werden Terrains aus dem Eigenschafteneditor auswählen. Wir wählen das Terrain aus, das als Terrain Set Null festgelegt ist, und dann ist das Terrain, das wir zeichnen, Gras Es sollte also ziemlich offensichtlich sein , welche Grasplättchen hier sind . Aber damit die Plättchen korrekt und automatisch gebaut werden, müssen wir die Kacheln auswählen , die Teil dieses Grasgeländes sein sollen. Du kannst also einfach mit der linken Maustaste klicken, gedrückt halten und ein Kästchen um all diese Grasplättchen ziehen, so ähnlich. Wenn es hervorgehoben ist, bedeutet das, dass es grundsätzlich als Teil dieses Terrains markiert ist. Und das ist dunkles Gras hier. Das könnten wir später einrichten. Okay. Und dann müssen wir die vielleicht auch herbringen . Wir werden sehen, wie das läuft und diese Lichtkacheln da sind. Nun, diese unteren sehen aus, als wären sie eher dunkles Gras. Wir können versuchen, sie einzubeziehen und zu sehen, wie es sich entwickelt, aber sie schaffen es vielleicht nicht bis zum letzten Schnitt für das Gelände, das eher ein dunkles Gras sein könnte. Also müssen wir sehen, wie das tatsächlich passt. Okay, wir haben also all diese Kacheln als Gras ausgewählt. Jetzt wollen wir zum oberen linken Feld gehen und die Ecken und Seiten markieren , die Gras sind oder an Gras angrenzen. Die einfachste Art, sich das mit diesem Kachelset vorzustellen, ist, dass der Bereich durchsichtig ist. Im Allgemeinen werden Sie ihn diesem Kachelset vorzustellen, ist , dass der Bereich durchsichtig ist. Im Allgemeinen nicht markieren, und wenn es sich um festes Gras oder in der Nähe von festem Gras handelt, dann markieren Sie es als Gras oder angrenzendes Gras. Wenn ich hier einfach mit der linken Maustaste klicke und herumziehe, wirst du sehen, dass es den Cursor ausfüllt, und wir wollen, dass diese acht Quadrate, die sich nicht in der unteren rechten Ecke befinden, als Gras markiert werden , weil das genau hier in der unteren rechten Ecke bedeutet, dass hier unten noch etwas anderes ist . Die Kachel unten rechts ist kein Gras und diese Kachel spiegelt das wider. Es wird also im Grunde genommen dieses Plättchen verwenden, wenn alles unten rechts oben links und diese drei Ecken Gras sind, Gras angrenzt, die untere rechte aber nicht. Die Idee ist also, dass Sie eine für all diese Szenarien haben. In diesem Fall würden Sie also diese obersten sechs Kacheln erstellen, und das bedeutet, wenn sich kein Gras darunter oder unten links oder unten rechts befindet, wird diese Kachel automatisch zugewiesen. Also wollen wir diese Art von Dingen einfach die ganze Zeit machen . Also dieser sieht aus wie alle Ecken und Seiten außer der unteren linken. Und dann ist dieser die Top Vier. Dieser ist, glaube ich, genau wie dieser hier oben, die ersten Acht auf der rechten Seite. Und ja, es ist möglich, mehrere Kacheln zu haben, die dasselbe haben, ich glaube, sie nennen es hier eine Bitmaske. Wenn wir also nach unten gehen, werden Sie mit Sicherheit feststellen, dass dies alles neun quadratische Kacheln sind , weil sie alle Gras sind und Gras nebeneinander liegen. Sie würden diese also tatsächlich alle vollständig ausfüllen . Und dann füllt das alles aus, was sich in diesen Randkacheln befindet. Okay, also wir müssen das einfach weitermachen. Also das hier oben wird die Mitte von oben nach unten und die rechte von oben nach unten sein . Hier haben wir die acht Seiten und Ecken außer der oberen linken. Das sind die unteren rechten vier. Das ist alles außer oben links. Die unteren sechs Steine, alles außer oben rechts, die unteren linken vier, alles außer oben rechts, die linken sechs, alles außer unten und die oberen linken vier. Wir haben unsere Eckstücke hier oben und wir haben die festen Grasstücke hier unten. Um damit zu zeichnen, gehen wir einfach zu Tilemap und wählen dann Terrains Und wir können uns einfach dieses Rechteckwerkzeug schnappen. Lassen Sie mich die Kamera hier ein wenig verkleinern. Und wir zoomen mit dem mittleren Mausrad auf der Spielkarte heraus , und wir können einfach mit der linken Maustaste klicken und ein riesiges Kästchen in den Hintergrund ziehen . Und da ist unser Gras im Hintergrund. Jetzt werden Sie sehen, dass diese Kacheln tatsächlich dunkler waren. Auf meinem Bildschirm war es etwas schwer zu erkennen. Also vielleicht sind das in dem Kachelset auch dunkles Gras , sodass es für mich wirklich genauso aussah . Die Lösung dafür ist also einfach, dass wir die dunklen Kacheln von den hellen Kacheln entfernen dunklen Kacheln von , wenn wir das Gras zuweisen Wenn ich also mit der rechten Maustaste auf eines dieser Teile der Bitmaske klicke, wird es als Teil der Kachel entfernt, wenn wir alle neun Seiten, Ecken und die Mitte vollständig entfernen Wenn wir das jetzt noch einmal neu zeichnen, sind diese beim Ausfüllen der Kacheln keine Option Also klicke ich einfach mit der linken Maustaste und ziehe ein weiteres Feld darüber, und da haben wir das helle Gras und nur das helle Gras für die gesamte Szene In einem Survivor-ähnlichen Spiel kann es sein, dass sich dein Charakter viel auf der Karte bewegt Also werde ich das Gebiet tatsächlich zu einem sehr großen Gebiet machen. Wir gehen einfach von hier nach hier, damit der Charakter genügend Platz hat , um sich zu bewegen. Jetzt können Sie sehen, dass es tatsächlich eine Weile dauert , das auszufüllen, weil das eine Menge Kacheln sind. Okay, ich möchte auch zeigen, ob ich E drücke, um in den Rennmodus zu wechseln, und dann D für das Malwerkzeug. Dann können wir hier mit der linken Maustaste klicken und Sie werden sehen , dass die benachbarten Teile automatisch anhand der Kachel in der Mitte zugewiesen die benachbarten Teile automatisch anhand der Kachel in der Mitte Diese Kachel hat also keine Kachel, also hat sie automatisch erkannt: Oh, ich brauche die Eck - und Seitenteile , die wir dem Terrain zugewiesen haben Und ich kann den Radierpinsel einfach weiter so benutzen. Und Sie werden sehen, dass die Seiten und Ecken automatisch generiert werden die Seiten und Ecken automatisch generiert Es kann einige Einschränkungen haben, wie zum Beispiel, dass man zwei mal zwei und eine Linie ziehen muss, um richtig auszusehen Das hängt wirklich vom Kachelset ab, denn es gibt verschiedene Arten, die Kacheln zu bauen Aber zumindest geht das viel, viel, viel schneller, als wenn Sie all diese Seiten- und Eckplatten manuell zuweisen müssten. Einfach den Computer das anhand der von Ihnen definierten Geländeregeln für Sie herausfinden zu lassen, wie wir es anhand der von Ihnen definierten Geländeregeln für Sie herausfinden zu lassen, gerade getan haben, ist eine enorme Zeitersparnis Also werden wir das ausfüllen. Es gibt auch das Farbeimer-Tool hier unten, also können wir einfach auf diesen Bereich klicken , in dem alle Kacheln gleich sind. Und oh, nun ja, wir müssen auch E verwenden, um das Erasuod zu entfernen. Und jetzt klicken wir mit der linken Maustaste und alles wird ausgefüllt. Wie Sie sehen können, wird die Region ausgewählt, die Sie gerade betrachten. Das könnte also die ganze Sache sein. Wenn du es mit einem völlig anderen Kachel-Gelände füllen willst , könntest du das tun, indem du einen Dreck definierst und hier unten auf Dreck umstellst und ihn deklarierst, so dass einen Dreck definierst und hier unten auf Dreck umstellst das ein bisschen fortgeschrittener ist , als ich eigentlich beabsichtigt hatte, aber lassen Sie uns hier ein anderes Terrain mit diesem Dreck definieren, die Art von orangefarbenem Dreck , in den Schmutz übergehen aber lassen Sie uns hier ein anderes Terrain mit diesem Dreck definieren übergehen , als ich eigentlich beabsichtigt hatte, aber lassen Sie uns hier ein anderes Terrain mit diesem Dreck definieren, die Art von orangefarbenem Dreck , in den Schmutz kann Also lass uns oben rechts einen neuen Geländetyp deklarieren und ich nenne das Dreck. Das Braun ist in Ordnung, finde ich. Vielleicht möchtest du kein Braun auf braunen Kacheln verwenden, damit du leichter erkennen kannst, wo du definiert hast und wo nicht. Aber wenn es für dich funktioniert, ist das in Ordnung. Welche Farbe Sie auch immer zuweisen möchten, ist völlig in Ordnung. Okay, wir werden also mit Farbschmutz im Fliesenfenster arbeiten Farbschmutz im Fliesenfenster und genau das Gleiche mit diesen Schmutzfliesen machen . Also hier malen wir die oberen linken acht, nicht die unteren rechten, und dann die oberen sechs, so. Und ich werde einfach so weitermachen. Dieser ist etwas unklar, aber ich werde mich für die vier oben rechts entscheiden und wir werden sehen, ob es richtig funktioniert. Wenn Sie tatsächlich mit Ihrem Terrain zeichnen, es nicht so aussieht, haben Sie vielleicht einen Teil hier oder da übersehen, Sie wissen schon, ob es sich um oder um oder um die Mitte oder die Seiten handelt. Manchmal braucht es also ein bisschen Versuch und Irrtum, um es richtig zu machen. Aber auf lange Sicht lohnt es sich auf jeden Fall. Also mach einfach weiter, du weißt schon, dieselbe Form. Nimm die Ecken und Seiten, wo es Schmutz ist und markiere es als Dreck und dann mach einfach weiter, bis du im Kreis rundum fertig bist . Okay, und dann mach mit den unteren drei Kacheln hier unten fertig . Wir nehmen den hellen Dreck und lassen den dunklen Dreck vorerst einfach weg. Okay, und das sieht gut aus. Okay, weißt du was? Ich habe erwähnt, dass ich den Übergang vom Dreck zum Gras regeln würde . Aber bei diesem Kachelset glaube ich nicht, dass das nötig ist weil diese Fliesen einzeln, sie haben eher Transparenz als Gras hier neben dem Dreck. Du musst also nicht das einzelne Grasgelände als Teil des Erdbodens definieren das einzelne Grasgelände , wo du diese anderen Steine nehmen und sagen würdest: Oh , da drüben ist Gras und unten links dann Dreck. Weil es hier Transparenz ist, also ist das eigentlich nicht nötig. Aber in anderen Kachelsets müssen Sie das möglicherweise tun. Wenn du weißt, dass an einer Ecke Gras sein soll, dann markierst du es dort als Gras. Also zwei Geländetypen für eine Ecke oder Seite. Aber hier brauchen wir meiner Meinung nach nur einen. Lassen Sie mich das versuchen und sehen, wie das aussehen wird. Also gehe ich zu Tilemap Wir machen Dreck und versuchen, es zu überarbeiten. Ich denke darüber nach, was wir eigentlich brauchen. Okay, also ja, hier können wir sehen, dass es die Seiten als durchsichtig markiert . Ich irre mich. Also werde ich versuchen, diese Seiten als Gras zu markieren, aber ich glaube nicht , dass wir damit wirklich das erwartete Ergebnis erzielen werden. Ich denke, was wir tun müssen, ist einfach zwei separate Ebenen für dieses spezielle Kachelset zu haben. Okay. Also werde ich versuchen, damit zu zeichnen. Also kacheln Sie den Kartenmodus und zeichnen Sie dann mit Schmutz und lassen Sie uns das versuchen. Es ist immer noch irgendwie durcheinander. Ich versuche es einfach einer Kiste. Ja, funktioniert immer noch nicht. Also Control Z ein paar Mal rückgängig machen. Und was wir eigentlich machen wollen, ist einfach mit Erde über das Gras zu malen, oder Gras über den Dreck hängt davon ab, welche Schicht Sie darauf haben möchten. Also klicke ich mit der rechten Maustaste auf das Stammverzeichnis und füge einen untergeordneten Knoten hinzu. Sagen wir, Kachelkartenebene. Ich benenne es um, sagen wir, Dirt. Ich verschiebe es unter die Erde, sodass es standardmäßig über dem Boden angezeigt wird. Also was auch immer unten ist, ist tatsächlich oben. Ich bin mir nicht sicher, warum es so eingerichtet ist. Ich bin es einfach. Und dann gehen wir in den Dreck. Oh, und wir wollen übrigens dasselbe Kachelset wiederverwenden. Also im Boden klicke ich mit der rechten Maustaste auf das Kachelset und speichere es. Das ist übrigens oben rechts. Also speichere es. Lokal im Projekt. Ich kann also einen neuen Tileset-Ordner erstellen und dann sage ich einfach Ground Tileset Dot TRs speichern Okay, wenn wir jetzt auf Dirt klicken und dann zum Inspektor gehen, können wir auf das Drop-down-Menü „ Quickload“ und „Ground Tile Set“ klicken Quickload“ und „Ground Okay, jetzt können wir mit dieser Tilemap-Ebene dieselben Kachelsätze verwenden, die wir bereits zuvor definiert haben So funktionieren Ressourcen im Allgemeinen. Es ist sehr einfach, sie über mehrere Knoten oder mehrere Szenen usw. hinweg gemeinsam zu nutzen , indem die Ressourcen auf diese Weise gemeinsam genutzt werden Okay, also wir werden hier mit Dreck zeichnen, und dann werde ich hier mit Dreck zeichnen, und du wirst einfach sehen, dass der Dreck einfach perfekt oben sitzt , weil wir auf verschiedenen Ebenen malen, also das zeigt sich nur auf dem Hintergrund und weil hier an diesen Seitenkanten Transparenz herrscht, füllt das Gras im Grunde die Lücken aus. Die andere Methode, die ich gezeigt habe, bei der sich alle Texturinformationen wie Gras und Schmutz in einer Kachel befinden, wäre eher so, als würde man mehrere Terrains in einer Kachel einrichten, was ehrlich gesagt komplizierter ist. Also benenne ich den Boden in Gras um. Weil wir da genauer sein werden. Wir haben also zwei Kachelmap-Ebenen, und es ist viel einfacher, sie zu manipulieren, als es die Kachelmap gewesen wäre. Okay, lass uns sehen, wo wir sind. Wir wollen wahrscheinlich eher einen Feldweg zeichnen. Okay, damit der Dreck richtig zugeordnet werden kann, wollen wir eine Linie von zwei mal zwei zeichnen. Sie möchten also das Rechteckwerkzeug oder die Tastatur verwenden . Wenn Sie nur eine Linie mit einer Kachel zeichnen, wird es ungefähr so enden. Basierend auf der Kachelseite ist nicht sicher, wie man auf die Informationen hier hereinfallen soll. Es gibt keine Kachel, bei der Transparenz oben und Transparenz unten vorhanden ist, also funktioniert das nicht. Sie müssen tatsächlich einen zwei Pixel hohen Pfad wie diesen erstellen und dann einfach Ihr Feld ziehen, und das wird dafür funktionieren. Also könnten wir einfach ein paar Pfade auf der Ebene erstellen, etwa so, weißt du, einfach zwei kachelbreite Pfade zeichnen , wo immer du sie haben willst. Und das wird es ein bisschen interessanter machen als nur einfache Grasplatten zu haben. Aber es liegt ganz bei dir, wie du das organisieren und interessanter machen willst , wie du das organisieren . Also, falls du jemals, sagen wir, Sim City gespielt hast , ist das genau das, was ich gerade hier mache , wie Straßensystem zu bauen und es im Grunde zu platzieren, wo ich will. Ich werde nirgends irgendwelche Wohngebiete füllen oder so. Aber nur ein paar mehr Kacheln auf der Karte zu haben, ist ein bisschen interessanter als buchstäblich nur Gras. Okay. Also werden wir sehen, ob das gut ist. Ich drücke Play. Und ja, unser Charakter hat jetzt irgendwie etwas , auf dem er laufen kann, das ist also ein bisschen interessanter. 11. Platzieren von Bäumen als Karten-Requisiten: Und jetzt denke ich, dass es eine gute Idee wäre, dem Spiellevel einige Requisiten hinzuzufügen Wir haben also auch einige Requisiten hier oben im Umgebungsordner Es gibt also einige animierte und statische. Wir könnten einfach mit Bäumen als der einfachsten Requisite beginnen , die wir in das Spiellevel integrieren können Also schnappen wir uns, äh, ich weiß nicht. Wir doppelklicken hier und Sie können die Baummodelle dort oben sehen. Vielleicht möchten wir uns diese großen Bäume schnappen, und das könnten wir einfach mit einem Beispiel für einen Sprite Two-D-Knoten machen einem Beispiel für einen Sprite Two-D-Knoten Und wir können sie ganz einfach einfügen. Alles, was wir wirklich tun müssen, ist zur PNG-Datei zu gehen und sie in die Spielszene zu ziehen. erstellt Hier oben wird automatisch ein Sprite Two D Also benenne es einfach in Tree um , dann nehmen wir diese Textur und zeichnen nicht die gesamte Textur Wir werden einen Bereich davon zeichnen. Wir möchten also eine Atlas-Textur verwenden , damit wir die Region auswählen können, die wir zeichnen. Also klicken Sie mit der rechten Maustaste hier und ich werde dieses Bild sehr schnell kopieren weil wir auf das Drop-down-Menü klicken und zur Atlas-Textur gehen, zur Atlas-Textur gehen, wodurch diese Textur vorübergehend aufgehoben wird Erweitern Sie dies und klicken Sie dann mit der rechten Maustaste und fügen Sie die Textur, die wir gerade kopiert haben, in den Atlas Und da haben wir es wieder angezeigt. Jetzt wollen wir auf Region bearbeiten klicken. Und dann gehen wir hier in den Snap-Modus, Cid Snap, das mittlere Mausrad vergrößern, um ihn zu vergrößern, und wir nehmen diesen Baum einfach so, drücken auf „Schließen“ und schon haben wir einen Baum in der Szene. Okay, je nach deinem Spielstil kannst du entscheiden, deinem Baum Kollisionsformen hinzuzufügen. Du würdest das genauso machen wie mit einem Spielercharakter. Wenn wir uns also den Spielercharakter ansehen, kannst du ihn hier als Kollisionsform sehen und du kannst ihn so gestalten, dass Objekte mit den Bäumen kollidieren Für diese Demo wollen wir jedoch die Anzahl der Kollisionen minimieren , die unsere Feinde mit jeder Art von Spielfigur haben werden mit jeder Art von Spielfigur Wenn wir eine Menge kollidierbarer Objekte im Spiel haben und wir nicht so etwas wie einen Navigationsagenten einsetzen oder Charakterkörper zwei D verwenden , damit sie sich entlang der Kollisionsform bewegen und gleiten können , dann werden Feinde stecken bleiben Viel einfacher wäre es, die Kollision einfach zu überspringen und einfach einen beliebigen Charakter durch den Baum laufen zu lassen , ihn dort zu haben Ausschließlich für visuelle Zwecke. Wir haben den Baum hier. Ich klicke mit der rechten Maustaste auf die Szene und wir erstellen einfach einen neuen Knoten für alle Bäume. Also sage ich Knoten zwei D, erstellen, und wir verschieben ihn aus dem Baum, also sollte er Unterwelt sein Und ich könnte es einfach in Requisiten umbenennen. Ich stelle den Baum hier rein. Und dann können wir diesen Baum einfach so oft duplizieren , wie wir brauchen. Also klicke ich zuerst mit der rechten Maustaste und speichere den Zweig als Szene. Ich glaube, wir werden den Baum in einen neuen Ordner legen. Ich rufe es an. Lass uns mit Objekten weitermachen. Ja, und ich lege es einfach hier rein . Ja, drei Punkte TSN. Wir können auf Save N klicken, wenn wir den Baum bearbeiten wollen, ihn in einen anderen Baumtyp ändern wollen, dann können wir einfach in die Szene springen Um das zu tun, findest du einfach dieses kleine Symbol hier und öffnest einen Editor, sodass du diesen Baum bearbeiten und nach Bedarf ändern kannst , wenn du alle Kopien davon auf der Welt ändern möchtest . Lassen Sie mich ein Beispiel dafür zeigen. Wir haben also den Baum. Ich werde es ein paar Mal duplizieren und dann W drücken, um die Kopien in der Szene zu verschieben. Wählen Sie also Baum zwei, W, und bewegen Sie ihn in der Szene. Der Bewegungsmodus ist genau hier. Der Auswahlmodus ist da. Sie müssen es also auswählen und dann in den Bewegungsmodus wechseln. Und jetzt möchte ich den Baum ändern, alle Kopien des Baums im Spiel. Also gehe ich einfach zur Baumszene und dann hier auf der rechten Seite erweitern wir den Atlas, bearbeiten die Region und wählen dann stattdessen diese rote aus. Also roter Baum, klicken Sie auf Schließen, klicken Sie auf Speichern und jetzt, zurück auf der Welt, sind alle Bäume wie rote Herbstblätter. Jetzt gehe ich zurück zum Baum und werde das rückgängig machen. Drücken wir also ein paar Mal Strg. Wir nehmen einfach den normalen grünen Baum. Und wenn Sie zwei Arten von Bäumen wollen, dann suchen Sie einfach hier nach der Baumszene in Ihrer Hierarchie. Sie können also einfach mit der rechten Maustaste hier klicken und es duplizieren. Nennen wir es Baumherbst und klicken wir auf Okay. Öffne Tree Autumn, das ist ein Doppelklick. Lassen Sie uns den Baum vergrößern und ich nehme die Textur und bearbeite die Region, und wir können uns einfach diese roten Bäume von hier drüben holen. Und wenn wir jetzt zur Welt gehen, können wir die Herbstbäume einfügen, oder wir können den Baum einfügen, indem wir die Szene direkt in die übergeordnete Szene, die Welt, ziehen Szene direkt in die übergeordnete Szene, die Welt, Wenn du dich daran gewöhnst, kannst du die Szene ziemlich schnell bevölkern Nun, eine Sache, die ich hier ändern möchte, und vielleicht muss ich zeigen, dass, um das deutlich zu machen , dass bei der Y-Sortierung die Position und die Baumszene des Sprites wichtig sein werden, die Position und die Baumszene des Sprites wichtig sein werden weil wir Y-Sortierung von der Mittelposition aus Also dort, wo der Charakter den Boden berührt , wollen wir den Sprite generell positionieren Also hier oben in diesem Spiel, weil ich das mit dem Spieler gemacht habe, richtig? Also wollen wir sichergehen, dass die Charaktere von dort aus sortieren, wo sie stehen. Das gilt auch für Objekte. Um zu zeigen , warum das ein Problem ist, gehen wir zurück zu den Requisiten der Hauptszene Ich gehe hier auf der rechten Seite zur Bestellung über. D Y Sort ist weltweit aktiviert, mach dasselbe. Gehen Sie zur Bestellung und wählen Sie WySort aktiviert. Okay. Und wenn wir jetzt spielen und unseren Charakter vor einen Baum bewegen, nun ja, die Kameras lassen uns das eigentlich nicht tun. Fügen wir also eine Follow-Cam hinzu, damit wir uns tatsächlich ein bisschen mehr auf der Karte bewegen können. Ich nehme den Spieler, klicke mit der rechten Maustaste, füge einen untergeordneten Knoten hinzu, transformiere zwei D per Fernzugriff , und dann wollen wir ihn rechts der Kamera zuweisen. Wir wollen die Position aktualisieren und nicht die Drehung und nicht die Skala, also deaktiviere diese Okay, wenn wir jetzt auf Play klicken, also stopp und spielen. Die Kamera wird unserem Spieler folgen, und das ist eine einfache Follow-Kamera in Gudo Okay, also kommen wir zu diesem Objekt. Wenn wir hier oben sind, können Sie sehen, dass wir hinter dem Baum sortieren, was wir erwarten würden. Aber wenn ich zur Hälfte gehe, stehen jetzt die Charaktere quasi im Baum Visuell gesehen wollen wir immer noch, dass der Charakter hinter dem Baum steht, bis er hier ist. Ansonsten sieht es einfach komisch aus. Um den Sprung in die Baum-Szene zu korrigieren, können Sie hier klicken, um einen Editor zu öffnen. Und wir wollen, dass dieser Geist hier oben ist. Aber ich denke, wenn du das Sprite einfach so verschiebst, weil es der Wurzelknoten ist, wird das nichts reparieren Also gehen wir zurück in die Welt und ja, drücken wir einfach auf Play. Du wirst sehen, was ich meine. Wir werden hier drüben gehen und es wird die Position ändern, wo es diese Bäume platziert, nicht die Position , von der aus es sortiert wird, oder? Siehst du, dass das Problem immer noch da ist? Also müssen wir zurück zur Baumszene gehen und ich klicke mit der rechten Maustaste. Ich füge einen untergeordneten Knoten hinzu, einen Knoten zu Ich klicke mit der rechten Maustaste darauf und mache ihn zum Szenenstamm. Das ist also der echte Baum an der Wurzel, und dann sind das jetzt nur noch die Sprite Two D. Wenn Sie also ein Objekt innerhalb einer anderen Szene instanzieren, wird die Wurzel quasi an der zentralen Position platziert Das ist also der Mittelpunkt des beiden übergeordneten D-Knotens, und jetzt können wir das Sprite verschieben Also, wenn ich dieses Sprite nehme, ist es eigentlich schon versetzt, aber Sie können es einfach mit W verschieben und es dorthin verschieben, wo Sie es brauchen Denken Sie nur daran, dass Ihre Transformationsposition ein Offset von der Wurzel ist und dass die Wurzel genau dort ist, wo sie am 00-Punkt genau hier instanziert werden soll am 00-Punkt genau hier instanziert Deshalb ist es notwendig, eine Basis auf zwei D zu haben und dann das Sprite darunter zu verschachteln Also wollen wir dasselbe auch mit dem Baumherbst machen. Aber vielleicht stellen Sie fest, dass diese Objekte, weil sie sich sehr ähnlich sind, tatsächlich eine Reihe von Schritten wiederholen. Was wir also tatsächlich tun können, ist eine vererbte Szene, die auf dem sommergrünen Baum basiert die auf dem sommergrünen Baum in der wir nur das SRT-Bild ersetzen, aber alles andere ist für diesen Baum gleich Also werde ich die Herbstszene hier unten löschen . Herbstbaum. Lass uns das löschen. Oh, ich muss es löschen und die Szene schließen. Also lösche das und dann hier oben, stell sicher, dass du das auch schließt. Also speichere nicht. Und dann kann es sein, dass es immer noch eine Kopie der Szene hat, weil es sie nicht vollständig löscht. Es ist nur so, dass es jetzt keine übergeordnete Szene gibt, in die das gehen könnte. Ich schneide das auch aus und speichere es. Also haben wir alle Instanzen verschoben. Okay. Und jetzt wollen wir unten links mit der rechten Maustaste auf Tree klicken neue geerbte Szene erstellen. Jetzt haben wir also eine ungespeicherte Szene, die auf der übergeordneten Szene basiert. Wir können das als Tree Autumn speichern, und wir möchten es in den Objektordner legen . Also speichern Sie das. Und das Einzige, was wir hier ändern, ist der Sprite. Also klicken Sie auf Region bearbeiten und holen Sie sich das Sprite für den Sommerbaum, klicken Und wenn wir zur Hauptszene zurückkehren, werden Sie sehen, dass wir den Baumherbst wieder instanzieren können den Baumherbst wieder Es scheint, als hätte ich es tatsächlich vermasselt. Also müssen wir die Atlas-Textur einzigartig machen. Sonst landest du hier, wo es die Bäume ersetzt. Nun zur Baumherbst-Szene, wir wollen diese leuchtenden zwei D nehmen, und der erste Instinkt, den ich hatte, war, die Region einfach zu bearbeiten und sie hier unten so zu ändern Aber das ist eigentlich falsch. Und lassen Sie mich erklären warum. Also, das ist eine Texturressource, und Ressourcen werden von jeder Szene gemeinsam genutzt , die darauf verweist. Und sowohl unser Baum unser Baumherbst verweisen auf dieselbe Ressource Wenn wir also ihre Eigenschaften wie die Atlasregion ändern, genau wie die Bearbeitungsregion hier in der Herbstszene, werden dieselben Eigenschaften auch in der ursprünglichen Baumszene aktualisiert , da sie dieselbe Ressource gemeinsam nutzen Es ist also keine neue Kopie der Texturressource. Es ist buchstäblich dieselbe Ressource. Also wollen wir hier mit der rechten Maustaste klicken und es dann in der Herbstszene einzigartig machen . Und jetzt können wir das auf diese Textur hier unten ändern. Wählen Sie also den Sommerbaum aus und klicken Sie auf Schließen. Klicken Sie auf Speichern. Wenn wir zu dem grünen Baum gehen, solltest du sehen, dass er immer noch den grünen Baumgeist hat . Wir können zur Welt hinübergehen. Sieht so aus, als ob ein paar dieser Bäume irgendwie nicht referenziert wurden, also sollten wir sie vielleicht ganz schnell löschen Also nehme ich Requisiten und mache daraus 00. Und dann möchte ich den Requisiten-Knoten nehmen und ihn sperren Also, wenn du hier oben klickst, kannst du es sperren, und ja, das sollte verhindern, dass es sich bewegt Wenn ich also W drücke und versuche, den Requisiten-Knoten zu verschieben, bewegt er sich nicht Eine wichtige Sache, die es zu beachten gilt, ist, dass Sie hier einen übergeordneten Knoten mit zwei D haben, Requisiten, die gesamte Position seiner untergeordneten Knoten basiert tatsächlich auf der Position des übergeordneten Wenn Sie also einen Gruppierungsknoten wie Requisiten haben, dieser aber trotzdem ein Knoten zwei sein muss, ist es wahrscheinlich eine gute Idee, ihn zu sperren Ich würde also dasselbe anwenden, wenn Sie einen Gruppierungsknoten für Feinde oder Projektile haben , was wir wahrscheinlich später haben werden Jetzt können wir unsere Bäume einfach zu Requisiten hinzufügen, also werde ich einfach ein paar da reinhängen Okay, also wenn ich diesen Baum nehme wir gerade erstellt haben , und W drücke und versuche, ihn über den Zaunpunkt hinaus nach oben zu bewegen, dann wirst du feststellen, dass er, wenn er hier ist, einfach hinter dem Gras und dem Dreck verschwindet hinter dem Gras und dem Dreck Also das liegt daran, warum wir sortieren. Also, was wir tun müssen, ist oben links für Gras und Dreck, wir werden sie auswählen müssen. Ich denke, Sie können sie sogar beide gleichzeitig auswählen. Und dann geh auf die rechte Seite. Wir suchen nach einer Reihenfolge und nehmen ihren Z-Index und setzen ihn auf etwas wie, sagen wir, minus zehn, jeden Wert, der negativ ist. Das macht es also so , dass diese immer hinter allem stehen, was einen Z-Index von Null hat. Wenn wir also jetzt den Baum auswählen und zu W gehen und ihn verschieben, ist er jetzt behoben. Es wird immer über diesen anderen Objekten angezeigt. Es geht also nur darum, wie wir unsere Szene überlagern. Manche Objekte möchten Sie mit anderen Objekten auf demselben Z-Index sortieren , wie das Zeichen im Baum Aber dann sollten andere Objekte wie die Kachelkarte bei diesen Bodenplättchen einfach immer im Hintergrund sein diesen Bodenplättchen weil die Charaktere auf dem Boden stehen, also solltest du die Charaktere sehen , bevor du den Boden siehst. Okay. Und jetzt wollen wir die Szene einfach mit ein paar mehr Bäumen füllen. Sie können sie einfach auswählen und duplizieren und nach oben verschieben. Stellen Sie sicher, dass Sie sie nur aus Sortiergründen als übergeordnetes Objekt in den Requisitenknoten einfügen nur aus Sortiergründen als übergeordnetes Objekt in den Requisitenknoten Und dann wählen wir diese einfach aus und duplizieren sie. Sie können mehrere gleichzeitig duplizieren. Wenn Sie also nur ein bestimmtes Muster wollen, dann können wir einfach eine Gruppe von Bäumen bilden und diese dann einfach alle kopieren. Sie können diese sogar in eine eigene Untergruppe verschieben, Beispiel mit einem übergeordneten Baumblock, und dann haben wir einen Haufen verschiedener Bäume und Sie können es verstecken, damit Sie nicht so viele Baumknoten haben , die Requisiten bevölkern Falls dir das hilft. Okay, lassen Sie uns ein paar Bäume etwas mehr verschieben, und ich könnte einfach all diese zehn Bäume auswählen. Und ich werde ja, versuchen wir es mit dem Blockieren, das ich erwähnt habe. Ich klicke einfach mit der rechten Maustaste und füge einen untergeordneten Knoten hinzu. Sagen wir Knoten zwei D, Baumblock. Ich schnappe mir alle Bäume und schiebe sie unter den Baumblock. Also wähle sie einfach alle aus. Und jetzt könnte ich diese Baumblockszene im Projekt speichern , und wir werden diesen Objektbaumblock speichern wollen. Jetzt können wir einfach den Baumblock duplizieren, D W steuern ihn so verschieben und die Szene einfach nach Bedarf mit Bäumen füllen , wo immer wir sie haben wollen. Irgendwann möchtest du das wahrscheinlich ein bisschen mehr anpassen, aber ich denke, das ist eine schnelle Möglichkeit die Szene als Prototyp zu erstellen, und hoffentlich sieht sie nicht so schlecht aus wenn wir auf Play klicken und die Ansicht vergrößert haben Aber ja, wenn ich das Baum für Baum machen würde, würde das, weißt du, wahrscheinlich etwa 20 Minuten oder so dauern , wahrscheinlich etwa 20 Minuten oder so Wenn wir also einige Anpassungen vornehmen müssen, wie hier, wenn wir die Ansicht vergrößern, sehe ich diesen Baum, weißt du, irgendwie in sehe ich diesen Baum, weißt du, der Nähe der Straße, vielleicht möchte ich ihn bearbeiten, sodass ich Q drücken und dann mit der linken Maustaste darauf klicken kann Wir können sehen, dass es Teil von Baumblock drei ist. Wir können mit der rechten Maustaste in die Hierarchie klicken und Bearbeitbare Kinder auswählen Und dann können wir jetzt speziell für diesen Baum die Bäume auswählen und verschieben. So haben wir also eher einen maßgeschneiderten Baumblock. Okay, und das können wir verstecken. Jetzt schauen wir uns nur 15 Baumblöcke an, nicht 150 Bäume. Wir können spielen, in den Spielmodus wechseln und einfach durch unsere Spielwelt laufen. Und von diesem Heranzoommodus ist es ziemlich schwer zu erkennen, es ist nur eine Kopie, die gleiche Baumstruktur zehnmal einzufügen , aber es ist viel weniger langweilig als nur Gras zu haben, oder ? aber es ist viel weniger langweilig als nur Gras zu haben, oder Wir haben quasi den Pfad, wir haben Gras. Wenn wir hier ein paar Blumen oder anderes Zeug reinbekommen, könnte es fast wie ein legitimes Spiellevel aussehen Oh, und hier ist ein Baum, den wir reparieren können. Also, weißt du, ein bisschen Spieletest. Du kannst solche Sachen finden. Lass uns reinzoomen und das ganz schnell beheben. Das ist also Teil von Baumblock zwei. Wenn Sie auf den Bildschirm schauen, können Sie tatsächlich den Namen des Knotens sehen , über dem wir den Mauszeiger bewegen Das ist also der übergeordnete Knoten, derjenige, bei dem die Szene Enstus, der Baumblock, ist, nicht seine untergeordneten Knoten, die dieser Szene enthalten sind Um dies editierbar zu machen, klicken Sie mit der rechten Maustaste auf Tree Block two, Drücken Sie Q, um in den Auswahlmodus zu wechseln, wählen Sie diesen Baum aus, bewegen Sie ihn, und wir können auch diesen Baum nehmen, ihn aus dem Weg räumen und nur diese kleinen Änderungen vornehmen Und ja, wenn man die Ansicht verkleinert, sieht es so aus, als ob keiner der Bäume mehr auf der Straße ist Also das ist wahrscheinlich das absolute Minimum von dem, was wir tun müssen 12. Stumpfe hinzufügen und Y-Sortierung korrigieren: Also habe ich das Pixel-Crawler-Paket nach Blumen durchsucht , die man um die Szene herum platzieren könnte, um sie ein wenig um die Szene herum platzieren könnte aufzupeppen Das habe ich in der kostenlosen Version leider nicht wirklich gesehen der kostenlosen Version Aber ich schätze, wir haben diese Baumstümpfe hier drüben. Wir können versuchen , das als Requisite zu verwenden und die Lücken ein bisschen zu füllen und es ein bisschen weniger langweilig zu machen Also nehmen wir das und erstellen daraus eine neue Stumpfszene. Also werde ich im Grunde die gleichen Schritte mit dem Baum wiederholen Ich ziehe das auf die Szene. Gehen wir zur Textur. Rechts, klicken Sie auf Kopieren. Kopieren Sie also diese Textur. Und dann klicken Sie im Drop-down-Menü auf eine neue Atlas-Textur, und dann fügen wir den Atlas hier ein. So wie es ist. Okay, du solltest also das ganze Bild sehen. Jetzt wollen wir die Region bearbeiten und den Baumstumpf auswählen, den wir in unserer Szene verwenden möchten Also, ich glaube, dieser hat einen etwas weniger rötlichen Baumstumpf , der unserem eigentlichen Baum näher kommt Also lass uns das machen. Drücke auf Speichern. Jetzt klicke ich mit der rechten Maustaste darauf und speichere es in einer neuen Szene. Also sagen wir Stump Dot TACN. Wenn Sie sich erinnern, wollen wir auch diesen Stumpf Vielleicht müssen wir das sowieso. Ich denke, in diesem Fall muss es ein paar Pixel tiefer sein. Das heißt, wir brauchen einen weiteren Knoten zwei D in der Wurzel. Klicken Sie also mit der rechten Maustaste auf Einen untergeordneten Knoten hinzufügen, Knoten zwei D, und klicken Sie dann mit der rechten Maustaste und machen Sie diesen zum Stammknoten. Okay, jetzt ist das nur ein Sprite Two D. Okay, die Stump-Textur ist ein Sprite Two D, und dann ist die Wurzel Stump und dann ist die Wurzel Jetzt speichern wir die Stump-Szene. Nimm das Sprite, drücke W, bewege es nach oben, wahrscheinlich um es genau dort herum zu sortieren, um Y zu sortieren Geh zurück in die Welt. Jetzt haben wir den Baumstumpf Lassen Sie uns noch ein paar Baumstümpfe erstellen und noch mehr Baumstümpfe rund um die Szene erstellen Falls Sie versehentlich Gras oder Erde ausgewählt haben, können Sie einfach hier oben links nach oben gehen und die Knoten so verriegeln Und jetzt solltest du sie nicht mehr auswählen können , glaube ich. Also, wenn wir Q drücken und den Baumstumpf oder den Baumstumpf auswählen, okay Jetzt sollten diese Knoten nicht mehr durch Anklicken auf der Karte ausgewählt werden können durch Anklicken auf der Karte ausgewählt Gehen wir runter zu den Baumstümpfen hier unten. Sie verwenden nicht die rechte Basis-Szene. Ich werde sie eigentlich einfach auswählen und löschen. Und lassen Sie uns auch den Knoten zwei D loswerden. Okay, durchsuche das Projekt nach Baumstumpf. Verwandle das in solche Requisiten. Okay, jetzt zoomen wir raus. Wir finden diesen Sumpf, drücken W, ihn zu bewegen, positionieren ihn, wo Sie ihn haben wollen Wir haben dich kontrolliert, es zu duplizieren. Okay, jetzt hat es den Namen Stump to, wenn es als Requisiten verwendet wird, also ist das eher das, wonach wir suchen Und lege einfach ein paar Baumstümpfe um die Szene herum, weißt du, einfach Dinge, denen man begegnen kann und die interessanter anzusehen sind als interessanter anzusehen Natürlich hat das Paket auch andere Dinge wie Gebäude für ein Bastelspiel Ich dachte nicht, dass die am besten geeignet sind. Und wenn Sie wirklich Gebäude einbauen wollen, würden Sie meiner Meinung nach anfangen zu argumentieren, dass Sie die Kollisionsformen und möglicherweise Navigationsagenten wirklich brauchen und möglicherweise Navigationsagenten um das Ganze glaubwürdiger zu machen Aber wir halten es so simpel wie möglich, weil wir einfach, du weißt schon, ein wirklich einfaches Survivor-ähnliches Spiel machen ein wirklich einfaches Survivor-ähnliches Ich denke, es gibt schon genug im Kurs, weißt du, ich will niemanden überfordern , aber wenn du am Ende wirklich die Navigationsagenten und Baumstümpfe verstehen willst, du am Ende wirklich die Navigationsagenten und Baumstümpfe verstehen willst Navigationsagenten und Baumstümpfe Ich habe ein paar Videos für solche Dinge auf YouTube. Wenn Sie nach dem Navigationsagenten von Chris Tutorial suchen, sollten Sie in der Lage sein, diese zu finden, wenn Sie damit beginnen möchten. Aber ja, das sieht nach einer ordentlichen Szene aus. In Ordnung, spiel Lass uns herumlaufen. Unsere Szene. Wir haben die Baumstümpfe. Wir können es jetzt einfach durchgehen. Das ist okay. Nun, hier, das ist ein bisschen weniger okay. Wir können sehen, dass die Sortierung in diesem Baum nicht korrekt ist. Tatsächlich sortiert der Baum überhaupt nicht. Ich denke schon, ich denke, hier müssen wir uns mit der Herbstbaumszene befassen und versuchen, das zu korrigieren. Okay, also gehen wir hier oben links zur lokalen Szenenansicht. Wir schauen uns die Herbstszene mit Bäumen an. Klicken Sie auf die Wurzel. Und vielleicht müssen wir hier überprüfen, warum die Sortierung für diese Szene aktiviert ist , und das müssen Sie möglicherweise auch in der übergeordneten Szene tun . Die Sortierung nach Y ist also aktiviert. Beachten Sie, dass meine Spiele immer noch laufen, sodass ich zurückblättern und sofort sehen kann , ob es funktioniert hat oder nicht. Und derzeit ist es das nicht. Also lass mich den Baum auf der Welt sehen. Gehört er tatsächlich zum Elternteil? Oh, weißt du, was es sein muss? Es sind die Tree Blocks. Okay, wir müssen zu den Baumblöcken gehen und auf den Baumblock klicken, um YSort aktiviert zu bestellen Oh ja, wenn Sie eine neue Hierarchieebene erstellen und die Y-Sortierung trotzdem beibehalten möchten, müssen Sie YsOrdEnabled auf der übergeordneten Ebene zuweisen Also props hat YSorting aktiviert, Tree Block jedoch nicht. Jetzt tut es Tree Block. Also, wenn ich zurück zum Spiel gehe, ist das Sortieren. Okay, also wir wollen in der Lage sein, über die Baumstümpfe zu laufen und zu sehen, dass wir vor dem Baumstumpf und hinter dem Baumstumpf sortieren können Baumstumpf und hinter dem Baumstumpf Und in den meisten Fällen funktioniert das. Nun, mir ist auch aufgefallen, dass es ein kleines Problem mit den Bäumen gibt. Sie machen das Sortieren, oder zumindest hat es das Sortieren gemacht, warte mal. Lassen Sie mich das bei dem Baum nachfragen. Ja, der ist in Ordnung. Aber die Position, von der aus es sortiert wird, ist ziemlich falsch. Ich möchte also in die Basisbaum-Szene gehen , sodass sie für beide Bäume gilt, und sicherstellen, dass Sie sich hier in der lokalen Ansicht befinden, wenn das Spiel oben links läuft . Wählen Sie den Sprite-Two-D-Knoten , weil wir den Offset des Sprites kontrollieren Drücken Sie W und bewegen Sie es dann nach unten, wahrscheinlich irgendwo wie dort Ich gehe jetzt zurück zum Spiel. Und wenn du dann versuchst, so zu laufen, solltest du sehen, dass die Y-Sortierung viel besser ist. Also hier stehen wir vor dem Baum, wie wir es erwarten würden. Und dann stehen wir hier hinter dem Baum. Also das ist viel besser. Sie müssen diese Offsets richtig machen, sonst sehen die Dinge einfach nicht richtig aus Und das sieht aus wie das meiste, was wir hier für die Level-Requisiten brauchen Ich könnte auch eine Baumstumpfgruppe erstellen, also nehme ich einfach diese 16 Baumstümpfe und gebe ihr ein übergeordnetes Klicken wir also mit der rechten Maustaste und wechseln wir zu einem neuen Knoten. Und dann erstellen wir einen Knoten zwei D. Jetzt sind all diese Stümpfe unter einem Knoten zwei D gruppiert . Wir nennen das den Stump-Block Wir klicken hier mit der rechten Maustaste und speichern den Stump-Block als eigene Szene im Objektordner Und jetzt können wir einfach unseren Baumstumpf duplizieren, W drücken, ihn auf unserem Bildschirm bewegen und Baumstümpfe einfach, du weißt schon, an anderen Stellen platzieren Es ist hier also nicht genau wie prozedurale Generierung, sondern eine ähnliche Idee, bei der wir nur versuchen, das Mapping mit dem Muster zu füllen Von den Parametern, bei denen es im Grunde nur darum geht, die Positionen der Baumstümpfe zu duplizieren und sie dann auszugleichen Es sieht also ein bisschen anders aus. Und wir können noch einmal ein Spiel spielen. Wir haben die Weiss-Sortierung hier ziemlich gut funktioniert. Vielleicht wollen wir für den Baumstumpf ein paar Pixel ändern, damit wir zur Baumstumpf-Szene übergehen können Und dann gehen wir zur lokalen Ansicht und verschieben den Sprite-Zwei-D-Offset um ein paar Pixel nach unten Schauen wir uns also an , wie das jetzt ist. Äh, vielleicht habe ich die Richtung verwechselt. Vielleicht sollten wir es eher so machen und dann auf Speichern klicken. Also verschieben wir das nach oben. Okay, das ist hinter dem Baumstumpf Das ist vor dem Baumstumpf. Okay. Ja, das sieht ein bisschen richtig aus. Also sollte nur der untere Teil des Baumstumpfes unter dem 00-Punkt des Elternteils Und wir werden herumlaufen. Ja, wir werden nur Baumstümpfe und Bäume sehen. Es muss hier nicht wirklich sehr abwechslungsreich sein, denn der Fokus liegt nur auf dem Kampf und es wird darum gehen, aufzusteigen und Noten zu erhalten und solche Dinge Aber etwas im Hintergrund zu haben , macht es interessanter Also wollte ich das alles einfach durchmachen. Sie können natürlich einige dieser Baumstümpfe manuell aus dem Weg räumen, wenn sie auf die gleiche Weise wie zuvor auf der Straße gelandet Also lass uns in die Welt gehen, lass uns den Baumstumpf finden , der auf der Straße war, okay? Ich drücke Q, wir wählen es aus. Also sehen wir Stump Block drei hier auf der linken Seite. Klicken Sie mit der rechten Maustaste und wählen Sie Bearbeitbare Kinder. Klicken Sie dann auf den Baumstumpf, schieben Sie ihn aus dem Weg und machen Sie dasselbe mit allen anderen Baumstümpfen Und hier ist einer. Okay, also werde ich diesen Knoten auswählen, Stump-Block zwei. Wir werden editierbare Kinder verwenden. Klicken Sie dann auf den einzelnen Baumstumpf, W, um ihn zu verschieben, bewegen Sie ihn aus dem Weg, und fertig Okay, das können wir auch mit diesem Baum hier oben machen. Das ist also Teil von Tree Block Five. Lass es uns editierbar machen. Wähle den Baum aus, verschiebe ihn. Oh, hier ist noch einer. Interessant. Ich muss tatsächlich einen Baumblock an derselben Stelle dupliziert Ja, richtig. Lass uns da drüben hingehen. In Ordnung. Okay, ich sehe wirklich keine anderen Bäume auf der Straße. Da drüben ist ein Baumstumpf, also werde ich versuchen, den auch zu reparieren Wir bewegen es, räumen es aus dem Weg. Machen Sie das übergeordnete Element bei Bedarf bearbeitbar. Und das wird wahrscheinlich fast okay sein. Und noch eine letzte. Also editierbare Kinder. Also wähle es aus Machen Sie den übergeordneten Knoten bearbeitbar, wählen Sie den einzelnen Knoten aus und verschieben Sie ihn aus dem Weg. Und das ist es im Grunde Also lass alles zusammenbrechen, damit es deine Hierarchie nicht durcheinander bringt Das ist einer der Gründe, warum ich den Prop-Node überhaupt erstellt habe den Prop-Node überhaupt Ähm, wenn du Blumentexturen oder andere Doodads hättest , vielleicht Steine, würdest du sie wahrscheinlich auf eine separate Felsen- oder Doodads-Ebene hier oben legen eine separate Felsen- oder Doodads-Ebene hier oben und sie einfach auf einem Z-Index positionieren , der höher ist als Das wäre ein guter Weg, damit anzufangen. Alternativ können sie ihre individuellen gesehenen Objekte sein. Bei der Leistung bin ich mir allerdings nicht sicher. Ich würde annehmen, wenn es Teil der Kachelmap ist, ist es wahrscheinlich viel besser, als wenn sie, du weißt schon, ihre eigenen Knoten in der Spielszene sind . Aber solange du nicht zu viele hast, ist es wahrscheinlich kein Ähm, es wahrscheinlich kein Ähm, also das wird im Grunde unser Teil des Kurses mit dem Kachel-Mapping sein unser Teil des Kurses mit dem Kachel-Mapping Und von hier aus können wir einfach weitermachen, Waffen und Feinde aufzustellen, EP zu sammeln, Level aufzusteigen, HP zu sammeln, all diese abtrünnigen RPGs-Features. 13. Projektile mit einem Timer auslösen: Charakter kann sich bewegen . Wir haben so etwas wie eine Spielwelt, auf der wir spielen können. Als Nächstes müssen wir einen Angriff starten, der auf einem Timer läuft, der ein Projektil erzeugt , mit dem wir Gegner angreifen können, ohne weitere Tasteneingaben vom Spieler zu benötigen ohne weitere Tasteneingaben vom In Survivor-Spielen sammelst du normalerweise eine Menge verschiedener Waffen an, und sie werden einfach automatisch Das Einzige, worüber du dir Sorgen machen musst, ist, auf dem Bildschirm herumzulaufen und die Waffen die Arbeit machen zu lassen , während du Feinden ausweichst Und das ist im Grunde die Gameplay-Schleife. Fangen Sie also damit an. Lass uns unser Waffenskript und unseren Player erstellen. In dieser Zwei-D-Szene werde ich also mit der rechten Maustaste auf die Wurzel klicken. Wir werden hier einen neuen untergeordneten Knoten D hinzufügen, Knoten zwei D. werden das in Waffe umbenennen, und lassen Sie uns mit der rechten Maustaste darauf klicken und ein Skript als Waffe dotGD anhängen ein Skript als Waffe dotGD Und das kann vorerst in den Player-Ordner gehen. Also werden wir dieses Waffenskript haben. Wir könnten es sogar zu Waffe zwei D machen, ehrlich. Wenn wir also in das Dateisystem gehen wollen, können wir es in Waffe zwei D umbenennen, falls das sinnvoller ist. Okay, was dieses Waffen-Zwei-D-Skript benötigt, um die Projektil-Spielobjekte zu erstellen, die eigentlich die Zwei-D-Repräsentation der Waffe in der Spielwelt sind , die einem Feind Schaden zufügen kann, ist, dass wir einen Timer benötigen Also sage ich Var Timer vom Typ Timer. Jetzt können Sie diese direkt im Szeneninspektor hier auf der rechten Seite hinzufügen , so wie Sie andere Knoten hinzufügen würden. Aber ich möchte das nicht für jedes einzelne Waffenskript tun müssen, das ich erstelle. Um das ein bisschen schneller und einfacher zu machen, sage ich Function Underscore Ready Wenn unser Skript fertig ist, nehmen wir einfach die Timer-Variable und setzen sie auf einen neuen Timer Nun, füge den Timer als Kind hinzu, also füge den Child-Timer hinzu. Das bedeutet, dass dieser neue Timer unter der Waffe existieren wird . Wenn wir die Waffe entfernen, entfernen wir auch den Timer. Und dann wollen wir uns mit dem Signal des Timers verbinden. Der Timer hat also ein Timeout-Signal, und wir wollen dieses mit einer Funktion verbinden , einer aufrufbaren Funktion, sodass wir sagen können, ob es ein Timeout Und hier unten können wir bei Timer-Timeout weiterarbeiten. Nun, dieser Signal-Timeout sendet eigentlich keine Daten, also brauchen wir keine Klammern Und dann wird diese Funktion den Rückgabetyp void haben Wenn also der Timer abgelaufen ist, wollen wir im Grunde unseren Zauber aussprechen. Wir wollen die Projektile beschwören. Also ich denke, Cast ist ein guter Name für diese Funktion. Also sagen wir einfach Cast und wir wollen die Richtung angeben die unser Projektil geworfen werden soll Wenn wir also nach oben zeigen, werfen wir nach oben. Wir können dafür einen Verweis auf die Blickrichtung bekommen , aber darauf kommen wir gleich zurück. Wir werden also eine Funktion umwandeln, und das wird die P-Richtung von Vektor zwei nehmen, die Richtung, in die wir umwandeln, und dafür können wir void zurückgeben. Damit das Timeout-Signal überhaupt erreicht wird, müssen wir also zuerst den Timer starten Also sagen wir Timer Punkt Start. Also die Zeit, die wir festlegen wollen, wie lange es dauert, bis wir eine Projektilinstanz erstellen, hängt von der Definition der einzelnen Projektilwaffen Und später werden wir verschiedene Waffenstufen haben, also können wir die Abklingzeit tatsächlich ändern , wenn die Waffe steigt, sodass wir öfter schießen können wäre eine Möglichkeit, unseren Charakter zu stärken Für die Waffe zwei D wollen wir diese Definition als Ressource haben , die wir verwenden können, damit unsere Waffe weiß, wie sie funktioniert. Lassen Sie uns das beim Export von VR tun und sagen wir, die Definition des Waffentyps, und das müssen wir erstellen. also im Dateisystem Lassen Sie uns also im Dateisystem nach außen expandieren, und dann werde ich einen neuen Ordner für unsere Waffen erstellen Also klicke ich mit der rechten Maustaste auf Ressourcen und wähle Create New Folder Weapons Und in diesem Ordner erstelle ich einfach eine neue Ressource. Klicken Sie also mit der rechten Maustaste auf Neue Ressource. Und lassen Sie uns sie als Basisressource für den Moment erstellen. Ich sage Speer-Definition. Da unser Charakter ein Ragont ist geben wir ihm einen Speer als Also speichere ich es hier, Script, wir müssen unsere neue Waffendefinition erstellen Also lass uns mit der rechten Maustaste auf Waffen klicken und ein neues Skript erstellen. Nehmen wir die Waffendefinition für den Moment an, und es wird von der Ressource erben und diese erstellen Jetzt gehen wir zur Waffendefinition über. Geben wir ihm den Klassennamen, die Waffendefinition. Und hier werden wir die Statistiken in der Benutzeroberfläche definieren , z. B. den Namen dafür, wie unsere Waffe in einem Datenformat dargestellt wird, aber nicht in der Spielwelt Das wird eher der Projektilklasse angehören, die sich vom Knoten bis zum D erstreckt. Also brauchen wir hier ziemlich viele, um alles irgendwie zusammenzufügen Ich würde sagen, das Waffensystem ist wahrscheinlich der komplizierteste Teil, also werde ich versuchen, es gründlich durchzugehen Also zunächst möchten wir vielleicht einen Namen festlegen. Also beim Export des Variablennamens. Knoten haben also standardmäßig eine Namenseigenschaft, Ressourcen jedoch nicht. können wir uns zunutze machen, indem wir einen benutzerdefinierten Zeichenkettennamen definieren. Das wird also der Anzeigename sein, wie wir ihn in der Benutzeroberfläche dargestellt haben. Und dann könnten wir bei Export Var Icon vom Typ Textur zwei D sagen Export Var Icon vom Typ Textur zwei . Später werden wir benutzerdefinierte Statistikblöcke für jedes Waffenlevel hinzufügen , aber das ist zu viel für dieses eine Video. Für den Moment benötigen wir von hier aus vielleicht eher eine Abkühlfunktion, und wir könnten hier ein Level übergeben, weil wir anhand der Waffendefinition nicht wirklich wissen, um und wir könnten hier ein Level übergeben, weil wir anhand der Waffendefinition nicht wirklich wissen welches Level es sich bei der Waffe handelt. Das wird für das Runtime-Objekt Weapon Two D hier drüben gesetzt . Weil das im Spiel steigt. Und dann ist die Definition eher eine Editor-Definition. Es legt fest, wie die Waffe auf jeder Ebene funktioniert. Das sind also verschiedene Dinge. Das Level ist an der Waffe an D. Also wollen wir das Level weitergeben, auf dem sie sich gerade befindet. Wir könnten also sagen, Stufe P, und das wäre eine Ganzzahl. Wir geben einen Float zurück, sobald die Waffe abgekühlt ist. Für den Moment werde ich es einfach machen und sagen wir einfach, wenn Sie einen Punkt drehen. Später können wir es noch individueller gestalten, indem wir die Abklingzeit tatsächlich auf der Grundlage des Levels festlegen, das wir weitergeben Aber halten wir es hier einfach, damit wir testen können , ob alles, was Waffe Zwei D ist, auch wirklich funktioniert In Waffe zwei D wollen wir also den Timer bei, sagen wir, dem Definitionspunkt Get Cool Down starten . Und wir geben hier einfach sagen wir mal, eine negative , sagen wir mal, eine negative Zahl ein, weil wir sie ändern wollen. Also schreibe ich hier eine kleine Notiz, um mich daran zu erinnern, das tatsächliche Niveau zu ermitteln, nur eine Notiz, damit wir, wissen Sie, sobald wir es getestet haben , von dort aus weitermachen und das System vollständig implementieren können . Okay, wir werden auch in der Lage sein wollen, die Projektilinstanz zu bekommen , die wir zu erstellen versuchen Lassen Sie uns also einfach eine Funktion zum Abrufen der Szene ausführen. Wir können das Level auch bestehen. Das wird zu einer vollen Szene führen. Lassen Sie uns weitermachen und diese Waffenszene erstellen, genauer gesagt das Projektil Lassen Sie uns also in der Zwei-D-Ansicht weitermachen und eine neue Szene hinzufügen. Wir werden hier eine Zwei-D-Szene erstellen. Ich werde das in Spear umbenennen . Klicken wir mit der rechten Maustaste darauf, hängen wir ein Skript und das wird Projectile Dot GD sein Ich möchte das wahrscheinlich speichern und oh, sagen wir, den Waffenordner Ich denke, das macht Sinn. Und dann Create öffnen, das ist Abbrechen. Create ist hier drüben, und dann wollen wir ihm den Klassennamen Projektil geben und wir speichern Spear Dot TSCN in Waffen, damit wir das Projektil tatsächlich sehen können Wir wollen ein Sprite daran anhängen. Klicken Sie auf Spear, hängen Sie einen Sprite-Zwei-D-Knoten und dann holen wir uns die Waffe Das wird Teil einer Atlas-Textur hier oben rechts Also mach eine Atlas-Textur. Und dann lass uns schnell aus unserem Projekt laden. Ich glaube, es war 16 mal 16. Und dann müssen wir unsere Textur bekommen. Gehen Sie also unten links zu Kunst. Geh zu Pixel Crawler, geh zu Waffen, Holz Und dann Word Dot PNG, wir legen das in den Atlas-Slot Okay. Und jetzt können wir die Region bearbeiten, heranzoomen und wir wollen den Speer, der genau hier ist Ziehen wir das mit der Maus herum und klicken Sie auf Schließen. Okay, jetzt haben wir den Speer-Sprite. So können wir zumindest sehen, wie unser Projektil im Spiel auftaucht, sobald es im Grunde genommen geladen ist Wir wollen diese Szene einspielen. Gehen wir zurück zum Player und ich öffne das Waffenskript. Dann klicke ich mit der rechten Maustaste auf Waffendefinition und Loup-Symbol Und um die Szene zu bekommen, machen wir einfach so etwas wie Return Load Und jetzt wollen wir die Speerszene einspielen. Also spuck Punkt TSN aus. Sie können sehen, dass Sie es einfach in den Ressourcen finden können , Waffen, Spit Punkt TSEN, und es dort hineinlegen Also noch einmal, dies ist eine vorübergehende Maßnahme nur um sie einfach zu halten , damit wir sie nicht vollständig umsetzen müssen Wenn wir also unsere Waffe zwei D einsetzen, werden wir die Waffe anhand der Definition sehen. Also wollen wir var sagen, Projektil wird vom Typ Projektil sein, und wir setzen das auf Definition Get SN und wir sagen hier negativ eins für das Level. Wissen Sie was? Eigentlich könnten wir einfach damit beginnen unseren aktuellen Stand der Waffe zu deklarieren Also machen wir daraus eine Stufe eins. Ich sage auf Export-Var-Ebene. Dies wird ein Typ vom Typ Integer sein, und er beginnt bei eins. Okay, jetzt können wir das Level einfach an diese Funktionen weitergeben , uns abkühlen und gesehen werden. Es hat noch nichts damit zu tun , aber zumindest haben wir es da. Und wenn wir unsere Waffe hochleveln, erhöhen wir das Level hier natürlich einfach um eins, und das wird ändern, was uns diese Funktionen zurückgeben , wenn wir versuchen, die Abkühlung zu bekommen oder die Szene zu bekommen Okay, wir haben die Szene und dann wollen wir sie instanziieren. Dann wollen wir es als Kind zu unserer Projektilgruppe und der Hauptszene hinzufügen zu unserer Projektilgruppe und der Hauptszene Woher bekommen wir den Knoten, in dem die Projektile tatsächlich spawnen können Gehen wir zur D-Ansicht von World Scene Two, und ich werde das minimieren Klicken wir mit der rechten Maustaste auf Welt und oben links und fügen einen neuen Knoten zwei D hinzu. Ich werde diese Projektile einfach umbenennen Gehen wir jetzt nach oben rechts, und ich werde hier Gruppen verwenden Wir werden dem Projektilknoten eine Gruppe zuweisen. Also füge eine neue Gruppe hinzu. Ich mache Projektile in Kleinbuchstaben, mache es global und ich sage den Knoten, in dem sich alle Projektile befinden, Enter Okay, jetzt können wir sehen der Projektilknoten diese Gruppe hat, und wir können auf den Knoten verweisen, indem wir zuerst in der Gruppe vorgehen Gehen wir also zurück zum Drehbuch. Es sind die Projektile, die das unterstreichen. Wir könnten das auch als Konstante deklarieren, wenn wir wollen. Ich würde also sagen, dass die Projektilgruppe konstant ist, sodass konstante Großbuchstaben zur Standardkonvention Es macht deutlich, dass dies ein konstanter Wert ist , der sich nicht ändern wird, und unterscheidet sich von einer regulären Variablen wie Level oder Definition, die sich während des Spiels ändern können Lassen Sie uns diesen Wert wie zuvor auf Projektile in Kleinbuchstaben Also werden wir diesen Knoten holen und ihn zu diesem Knoten hinzufügen wollen . Also lass es uns zwischenspeichern. als lokale Variable an, Nehmen wir als lokale Variable an, var projectiles parent, und das wird ein Knoten sein Um das fertig zu machen, machen wir es vor dem Timer Unterstrich: Das Elternteil eines Projektils entspricht dem G-Knoten. Aber zuerst müssen wir den Baum holen . Also hol dir Tree Dot Get First Node und Group, und wir wollen die Projektilgruppe, was ein Stringname ist In den meisten Fällen können Zeichenketten und Zeichenkettennamen synonym verwendet werden In vielen Fällen werden im Hintergrund automatisch zwischen den Typen konvertiert vielen Fällen werden im Hintergrund automatisch zwischen den Wir können es hier als Zeichenkettennamen deklarieren , weil es das erwartet, was es dafür erwartet. Wir bekommen also den ersten Knoten in der Gruppe. Wenn das nicht existiert, werden wir wahrscheinlich einen Fehler in der Konsole bekommen , was gut ist. Wir müssen also nur sicherstellen, dass unsere Spiellevel tatsächlich über einen solchen Projektilknoten verfügen Wenn du möchtest, könntest du diesen Knoten in deinem Projekt speichern und wiederverwenden, rechten Maustaste auf Szene mit den Zweigen speichern klickst und dann erstellen wir vielleicht einen Level-Ordner Für alles, was mit Levels zu tun geben Sie hier den Punkt TSC für Projektile Wenn du sie dann von hier aus immer wieder verwendest, werden sie immer in dieser Projektilgruppe sein, und du solltest sie nicht grundsätzlich zwischen mehreren Leveln desynchronisieren desynchronisieren Jetzt können Sie die Projektilszene wiederverwenden, ohne sich Gedanken darüber machen zu müssen, dass sich die Werte zwischen den Ebenen ändern, auf denen Sie sie verwenden Das könnte also Und jetzt, nachdem wir das Projektil erstellt haben, wollen wir sicherstellen, dass es als untergeordnetes Objekt zum Projektil-Elternteil hinzugefügt wird untergeordnetes Objekt zum Projektil-Elternteil Unterstreichen Sie also das übergeordnete Projektil und fügen Sie das untergeordnete Projektil hinzu. So wie das. Das können wir jetzt loswerden. Und dann wollen wir nur sichergehen, dass die globale Position der Waffe zwei D entspricht. Nehmen wir an, die globale Position des Projektils entspricht hier der globalen Position. Wir nehmen also die Position des zweiten D-Knotens der Waffe ein. Und dann müssen wir die Richtung an die Besetzung übergeben. Also lass uns einfach Vector Two Dot machen, oder? Das sind Hauptstädte. Ein konstanter Wert Und jetzt sollte das Skript ohne Fehler ausgeführt werden können. Okay, es hat also die Szene. Ich weiß, welche Abklingzeit ich einstellen muss. Und es weiß, dass es nach Ablauf des Timers eine Kopie des Projektils auf dem zweiten D-Knoten der Waffe erstellen muss Timers eine Kopie des Projektils auf dem zweiten D-Knoten der Waffe Lassen Sie uns das also ausführen und es versuchen. Wir können sehen, Abklingzeit und Null bekommen. Wir haben also die Waffendefinition nicht wirklich festgelegt. Wir könnten also sagen, behaupten, dass die Definition nicht gleich Null ist. Für jede Waffe ist also ein Waffendefinitionssatz erforderlich. Also müssen wir zum Spieler gehen. Wir müssen diese Waffe finden, zwei D-Knoten. Ich benenne ihn in Waffe zwei D um. Gehen wir zum Inspektor oben rechts und definieren dann hier unsere Waffendefinition. Also neue Waffendefinition, erweitere das. Wir werden möglicherweise das Symbol und den Namen wollen. Also nenne ich das Speer. Und holen wir uns das Symbol aus der Speerszene. Also können wir einfach dasselbe Sprite nehmen und es auf das Symbol kopieren Also werde ich mit der rechten Maustaste auf die Textur klicken. Und kopiere. Gehen wir nun zu der Spieler-Szene, in der wir die Waffendefinition festgelegt haben , klicken wir einfach mit der rechten Maustaste auf das Symbol und fügen es ein. Okay, da ist also unsere UI-Darstellung des Speers. Also klicken wir auf Play und wir bringen den Speer alle 1 Sekunde zur Instanz Jetzt bewegt sich unser Projektil noch nicht. Es gibt keinen Code, um es zu bewegen, aber wir haben die Zeit Projektile auf der Grundlage unserer Waffendefinitionsklasse zum richtigen Zeitpunkt in die Welt zu bringen zum richtigen Zeitpunkt in die Welt auf der Grundlage unserer Waffendefinitionsklasse Natürlich steckt noch viel mehr dahinter. Wir haben noch nicht mit Statistiken oder ähnlichem herumgespielt , aber das ist ein guter Anfang Also werde ich mich im nächsten Schritt näher damit befassen 14. Projektile in Abschussrichtung bewegen: An diesem Punkt sind wir also bereit, Feinde ins Spiel zu bringen und dann dafür zu sorgen , dass unsere Projektile sie treffen können, wenn sie sich entlang des Bildschirms bewegen Okay, also lasst uns dafür sorgen, dass sich unsere Projektile jetzt in die Richtung bewegen können , in die sie abgefeuert wurden Ich gehe zur Speerszene rüber , und das ist das Speerprojektil, das tatsächlich in der Spielwelt auftaucht. Lass uns das Drehbuch öffnen. Und wir werden hier eine Startfunktion einbauen wollen , damit, wenn unser Projektil instanziert wird, ein anderes Skript ihm sagen kann, in welche Richtung es sich bewegen wird Also werde ich den Funktionsstart einschalten und wir werden eine Richtung einschlagen P unterstreicht also den Richtungsvektor zwei, und das ist die Richtung, in die sich die Projektile bewegen werden die Projektile bewegen Also wollen wir diese Startrichtung nehmen und sie lokal machen , damit wir sie in unseren Prozessfunktionen verwenden können Prozess wird jede Sekunde aktualisiert und unser Projektilknoten wird über den Bildschirm übertragen Var-Richtung wird also Vektor zwei sein, und das werden wir gleich hier beim Start einrichten Also Richtung entspricht P-Richtung. Sobald wir ein Projektil abgefeuert haben, wollen wir es auch in die Warteschlange stellen, bis es nach einer gewissen Zeit wieder freigegeben Andernfalls würden Projektile, die niemals ein Ziel treffen, für immer in eurer Spielwelt existieren und irgendwann zu Leistungseinbußen führen Deshalb wollen wir sicherstellen, dass Objekte irgendwann frei werden. können wir also tun, indem wir eine gewisse Zeit warten . Ich sage, warte. Das bedeutet also im Grunde, dass es zum Rest des Codes zurückkehrt , der dieser Zeile folgt, nachdem die Bedingung erfüllt ist. Also sagen wir, hol dir einen Baum. Also holen wir uns den aktuellen Szenenbaum, in dem dieser Projektilknoten existiert, und dann erstellen wir einen Timer Und wir geben ihm eine Zeit. Sagen wir einfach 1,0 Sekunden. Alles andere kannst du als Standard belassen. Diese ganze Sache bedeutet also, dass wir auf die Timeout-Methode für den Timer warten die Timeout-Methode , den wir mithilfe des Szenenbaums erstellen, und wir warten eine Sekunde , bis dieser Timeout eintritt Und wenn das erledigt ist, können wir uns einfach auf den Projektilknoten konzentrieren Dadurch wird das Projektil auf allem, was sich darunter befindet, freigesetzt. Nun, ein Projektil, das Ziele trifft, wenn es ein Ziel trifft, wird es sich wahrscheinlich vorher selbst entfernen, aber das ist nur ein Fallback, sodass es sich irgendwann freilegt, wenn es einfach alle Feinde komplett verfehlt freilegt Okay, und dann brauchen wir das Projektil, um sich tatsächlich zu bewegen. Nehmen wir an, die Funktion unterstreichen Prozess oder ein physikalischer Prozess, ist wahrscheinlich ein bisschen besser geeignet Lass uns das machen. Normalerweise verwendet man den physikalischen Prozess also für alles, was das Verschieben von physikalischen Objekten im Spiel beinhaltet . Nun, das ist ein Knoten zwei D. Wir fügen dem Projektil nichts wie Starrkörperphysik hinzu, sondern nur, damit seine Bewegung mit allem anderen im Spiel synchronisiert wird Wenn der physikalische Prozess auf 60 Mal pro Sekunde oder 60 Bewegungsperioden pro Sekunde eingestellt ist , dann bewegt sich das Objekt 60 Mal pro Sekunde, nur um es mit allem anderen im Spiel konsistent zu halten Exportiere var speed up hier oben im Typ float. Wir werden es zu 100 hinzufügen. Das ist also nur die Standardgeschwindigkeit für das Projektil. Dinge wie die Geschwindigkeit und die Dauer, die dieses Projektil in der Spielwelt hält, sind Statistiken, die ich in ein separates Statistik-Skript übertragen möchte , damit wir sie pro Waffe und pro Level jeder Waffe viel übersichtlicher definieren können Waffe und pro Level jeder Waffe viel übersichtlicher Aber für den Moment ist es gut genug, also werden wir später daran arbeiten Also wollen wir hier „ Übersetzen“ sagen. Jeder Knoten TD kann auf dem Bildschirm übersetzen. Es ist Bewegung ohne Kollision. Und wir werden sagen, dass wir uns in Richtung mal Geschwindigkeit, mal Delta bewegen . Nun, wenn Sie wissen wollen was das berechnet, wenn Sie debuggen einen Breakpoint erreichen, dann sollten Sie vielleicht etwas Ähnliches tun Var move, das ist ein Vektor zwei, der genau diesem Bit hier entspricht, Strg X , füge das Ende dort ein, und dann übersetzt du einfach Wenn du also genau hier einen Breakpoint erreichen würdest, und wir könnten das vielleicht tun, indem wir einfach auf Play drücken, weil der Physikprozess ausgelöst wird , sobald dieser Geist erzeugt wird, dann können wir unten sehen, dass wir den Zugwert von 00 haben und Y ist Null, Null, weil wir das Projektil nicht mit dieser Funktion abgefeuert haben, also hat es nicht wirklich , für die momentan standardmäßig der Vektor zwei Punkt Null ist. Okay, also werde ich den Breakpoint rückgängig machen. Du. Okay, also schließ das Spiel. Es bringt sogar einen guten Punkt zur Sprache, den ich ansprechen möchte, nämlich dass, wenn die Richtung Vektor 20 ist, das wahrscheinlich ein Problem darstellt, weil wir immer in eine Richtung starten die die Charaktere zeigen, was niemals Vektor zwei Punkt Null sein sollte. Wir könnten also erwarten, dass die Startfunktion bereits aufgerufen wurde bevor wir sie vollständig mit Adhild in Szene setzen Machen wir also einfach den Funktionsunterstrich fertig. Und wir werden behaupten, dass die Richtung nicht dem Vektor 20 entspricht Rufen Sie Launch auf, um die Richtung oder das Projektil festzulegen , bevor Sie es als untergeordnetes Objekt hinzufügen Wir wollen also, dass wir voraussetzen, dass wir die Richtung bereits mit der Startfunktion festgelegt haben , und einen Hinweis geben , dass wir launch aufrufen sollten , bevor wir Add hild aufrufen Das Ready erfolgt also nach Okay. Wenn ich jetzt renne, sollten wir sofort den Assert aufrufen, wie wir es erwarten würden. Lassen Sie uns also zum D-Skript für Waffe zwei übergehen, in dem wir das Kind des Projektil-Elternteils hinzufügen das Kind des Projektil-Elternteils hinzufügen Jetzt wollen wir den Projektilpunktstart in P-Richtung aufrufen , den wir an die Cast-Funktion übergeben Damit es tatsächlich auf etwas Richtiges eingestellt wird. Nun, wir können das hier unten auf dem Vector Timeout sehen, wir verwenden Vector Two Dot Right Also ich denke, das wäre eine gute Art zu testen. In diesem Fall sollte es immer nach rechts gehen. Das Problem hier ist also wirklich, dass unser Launch versucht, zwei verschiedene Dinge zu tun. Ich denke, es ist tatsächlich sinnvoller, dieses Bit die Ready-Funktion zu übernehmen, da wir das jetzt verwenden. Also füge ich das dort ein, Control X, das, Control V, füge es ein. Das ergibt Sinn. Sobald das Projektil fertig ist, machen wir es bereit, es nach einer bestimmten Zeit freizulassen Dadurch kümmert sich die Startmethode nur um eine Sache, nämlich das Initialisieren des Objekts, sobald es erstellt wurde Das ist also mit ziemlicher Sicherheit der bessere Weg, es zu tun. Okay, jetzt drücken wir auf Play. Und wir haben unser Projektil nach rechts abgefeuert. Man kann auch sehen, dass sie nur 1 Sekunde halten, wahrscheinlich nicht lange genug, aber es ist ein guter Test um sicherzugehen, dass sie sich tatsächlich befreien Zu diesem Zeitpunkt werden also immer nur ein oder zwei der Speere in der Szene sein oder zwei der Speere in der Szene Es sollte keinerlei Leistungsprobleme verursachen. 15. Einrichten von Feinden und Hitboxen: Unsere Projektile bewegen sich nach rechts. Lassen Sie uns nun einen Feind erschaffen, damit sich unsere Projektile tatsächlich mit ihm verbinden und ihn treffen können bedeutet also, dass wir in diesem Video eine Trefferbox und eine Verletzungsbox einrichten , und wir werden uns später um Statistiken kümmern, wie zum Beispiel HP Also, in meinem aktuellen Projekt, sehe ich unten, gibt es hier ein paar Warnungen. Diese erwähnen nur , dass Sie einen Parameter unterstreichen sollten, wenn Sie ihn nicht verwenden Also werde ich auf jeden von ihnen klicken und es dort nur leicht unterstreichen. Also verwende ich Delta nicht in diesem Prozess der Spielerphysik. Also unterstreiche ich das Delta. Das bedeutet, dass es nicht benutzt wird. Und dann werde ich hier in einem anderen Drehbuch dasselbe tun. Und nur für jede der Warnungen, die du bekommst, wiederhole es einfach. Sie verwenden den Parameter nicht und unterstreichen ihn dann, um anzuzeigen, dass Sie erwarten, den Parameter nicht zu verwenden, und dass das kein Unfall oder Fehler Und wir werden weitermachen und unseren ersten Feind erschaffen. Fangen wir also mit einem Oc an. Ich werde hier oben eine neue Szene erstellen und wir gehen zur Zwei-D-Szene auf der linken Seite über. Ich werde das in Oc umbenennen. Wir machen es mit der rechten Maustaste, klicken darauf, ändern den Typ in einen Charakterkörper mit zwei D. Und wählen das aus. Okay, dann möchte ich mit der rechten Maustaste auf den Ork klicken und einen untergeordneten Knoten hinzufügen Wir machen hier ein Sprite TwoD. Klicken Sie auch mit der rechten Maustaste hier und fügen Sie eine Kollisionsform für Kinder hinzu. Und auf der rechten Seite machen wir daraus einfach eine kleine Kreisform, so wie du es mit dem Player gemacht hast. Und lassen Sie uns die Steuerung übernehmen, die Szene in den Charakteren speichern. Ich werde einen neuen Ordner für Feinde erstellen. Also Feinde, leg das da rein und speichere dann den Orca-TAC Okay, jetzt braucht unser Orc natürlich Bright. Wählen wir also diesen Brit-Knoten und gehen dann nach unten links Wir suchen nach Entitäten, ich glaube, es waren Wesen, Mobs, Ork-Crew, und wir wollen uns eines davon schnappen Also habe ich nur den Standard-Orc verwendet damit wir uns das ungenutzte Blatt schnappen können Ich wähle diesen Bright Two-D-Knoten und dann drüben auf der rechten Seite ziehen wir das ungenutzte Blatt hierher. Okay? Nun haben wir offensichtlich ein ähnliches Setup wie der Player, wo wir ein Spritesheet haben Wir müssen definieren, wie viele Frames H-Frames von links nach rechts sind. Sie können also sehen , dass es vier Und das wollen wir mit einem Animationsplayer machen. Also klicke ich auf Ok, füge einen untergeordneten Knoten hinzu. Animationsspieler. Wählen Sie also den Animation-Player aus, gehen Sie nach unten machen Sie eine neue Idol-Animation Okay, und wir müssen einige der Sprite-Eigenschaften mit Keyframes versehen Fügen wir also eine Spur, eine Eigenschaftenspur, Sprite zwei D hinzu, und wir werden nach H-Frames suchen. Also doppelklicken Sie darauf Okay, und dann wiederhole die Schritte für Property Track, Sprite Two D, V Frames, Property Track, Sprite Two D Textur Und unten rechts, aktiviere hier das Snapping und ändere dann die Fangzeit auf Also ein Bild pro Zehntelsekunde. Und schließlich wollen wir auf der rechten Seite die Gesamtdauer auf 0,4 Sekunden ändern und das Looping aktivieren Okay. Gehen Sie auf der Timeline hier zurück zum Anfang der Animation klicken Sie mit der rechten Maustaste auf Schlüssel einfügen. Wir haben also unsere H-Frames. Wir wollen das nehmen und oben rechts ändern wir das auf vier. Und dann VFrames wollen wir einen Schlüssel einfügen. Wir belassen das hier oben als eins. Klicken Sie mit der rechten Maustaste, um einen Rahmen einzufügen. Das wird also unser erster Frame sein. Sie sich keine Gedanken darüber, wie alle vier Frames gleichzeitig angezeigt werden, in einer Sekunde automatisch behoben wird. Und dann wollen wir mit der rechten Maustaste klicken und einen Schlüssel für unsere Textur einfügen , von der Sie oben rechts sehen können, dass sie hier bereits standardmäßig auf unsere Animation eingestellt ist bereits standardmäßig auf unsere Animation Wir haben die Animation also noch nicht abgespielt, es werden also immer noch vier Frames angezeigt, aber sobald ich sie abspiele, wird das erste Bild der inaktiven Animation angezeigt, und der Frame-Bereich hier unten aktualisiert sich automatisch so, wie wir es erwarten würden Jetzt wollen wir also zu 0,1 Sekunden übergehen. Es sollte 2,1-Sekunden-Intervalle aufnehmen und dann mit der rechten Maustaste klicken und eine Art Taste für Frame auswählen und dann das oben rechts in eins hier oben ändern. Das ist also der zweite Frame der Animation. Fügen Sie dann den Frame-Wert Zwei hinzu, das ist das dritte Bild hier oben und das letzte Bild mit dem Wert drei, was dem vierten Animationsframe entspricht. Okay, wenn wir jetzt spielen, sollten wir unsere inaktive Animation haben. Und für den einfachen Charakter, der wie ein Überlebender aussieht, werden wir ihn nur nach links und rechts drehen Also brauchen wir in diesen einzelnen Animationen nur einen Umkehrknoten diesen einzelnen Animationen ob er nach links oder rechts zeigt Da es sich also um ein einfaches Survivor-ähnliches Spiel handelt, zeigen wir es nur mit der Vorderseite nach links und rechts Also müssen wir später nur noch einen Flipping Node hinzufügen. Und abgesehen davon brauchen wir nur unsere Idle Run- und Death-Animationen Und das ist so ziemlich alles, es sei denn ein Charakter benötigt eine spezielle Angriffsanimation. Lassen Sie uns also die Leerlaufanimation duplizieren und unsere Run-Animation einfügen. Für die Run-Animation wollen wir die Textur hier runternehmen und den Wert und den oberen rechten Rand in das Run-Sheet ändern. Also nimm Run und ziehe das nach oben rechts. Okay. Und das sind sechs Animationsbilder. Also wollen wir hier H-Frames nehmen und es auf sechs ändern. Und dann wollen wir hier Bild fünf und Bild sechs hinzufügen. Also ändert der Schlüssel diesen Wert und den Wert oben rechts auf vier, fügt einen Key ein, ändert diesen Wert auf fünf, und dann nimmt man die Dauer der Run-Animation und macht sie 0,6 Sekunden lang, auf Play, und wir sollten unsere Run-Animation haben. Nun, ich glaube, es ist falsch versetzt, so wie es das Idol für den Lauf des Spielers war Also müssen wir auch diese Offset-Einstellung vornehmen. Also lass uns zum Idol gehen. Lasst uns diesen Charakter nach oben verschieben. Stellen Sie sicher, dass Sie den Sprite-Knoten speziell auswählen. Drücken Sie dann W, um in den Bewegungsmodus zu wechseln, und bewegen Sie das Sprite nach oben , sodass der 00-Punkt hier unten auf seinen Füßen zentriert ist Dort, wo es sich im Schwerpunkt befindet, wo es den Boden berührt, sollte Gehen Sie dann rechts zur Transformation und fügen Sie einen Keyframe ein Ich habe also negative 14 Pixel als Y-Position. Geben Sie das ein, klicken Sie auf Erstellen und schon haben Sie den Reset-Track. Das ist in Ordnung. Und jetzt müssen wir den Lauf auch mit einem Keyframe versehen. Für die Ausführung gehen wir also nach oben rechts und ich mache es. Versuchen wir es mit negativen 27 Pixeln Versuchen wir es mit negativen 30 Pixeln. Ich dachte mir, dass sie irgendwie genauso aufgebaut sind wie der Spieler, derselbe Künstler und so. Also lass uns das mit einem Keyframe versehen Und erschaffe. Und wir haben unsere Laufanimation. Lassen Sie uns jetzt schnell zu Idol wechseln. Okay, jetzt läuft unsere Run-Animation. Lass uns schnell zu Idle wechseln und es wird abgespielt. Und es scheint, als ob die Pixel aneinandergereiht sind. Wir müssen das Endspiel natürlich testen, wenn wir die Idle-Animation tatsächlich zeigen wollen. In diesem Fall werden wir die Idle-Animation jedoch möglicherweise nie zeigen , es sei denn der Feind wird jemals aufhören, auf den Spieler zuzurennen. Aber zumindest bei diesem Setup wird die Idee sein, dass der Feind immer auf den Spieler zuläuft , solange der Spieler existiert. Also werden wir die inaktive Animation vielleicht nie wirklich sehen. Es würde an dir liegen. Vielleicht fangen die Charaktere, wenn der Spieler besiegt ist, einfach im Leerlauf an, anstatt sich mehr auf dem Bildschirm zu bewegen, weil es keinen Spieler mehr gibt, gegen den sie kämpfen können Aber das wäre nur ein Extra, das nicht wirklich benötigt wird. Was wir jedoch brauchen, ist die Todesanimation. Lassen Sie uns laufen weil ich denke, die Todesanimation besteht aus sechs Frames, und wir werden das duplizieren um eine Todesanimation zu machen, also geben Sie Death Enter ein. Dafür werden wir das Looping ausschalten. Charaktere sterben nur einmal. Dann wollen wir die Textur nehmen und sie in das Death-Sprite-Blatt unten links umwandeln Ziehe das in den Inspektor und lass uns dort auf Play drücken. Und wenn wir dann in den Leerlauf wechseln, scheint es, als ob es sich aneinanderreiht und Run scheint, als ob es sich aneinanderreiht. Okay, das ist wahrscheinlich gut. Ich schätze, die Position zum Tod ist minus 30. Wie dem auch sei, wir haben unseren Oc. Wir können einfach einen Ork in die Spielwelt bringen. Also lass uns hier einen Ork nehmen. Und eigentlich wollen wir wahrscheinlich eine Feinde-Hierarchie, also klicke ich mit der rechten Maustaste auf einen Knoten einfügen Also Knoten zwei D, wir werden Feinde machen oder könnten auch einfach nur NPCs sein, wenn wir wollen Vielleicht sind Feinde besser. Und ich werde einen Ork von unten links fallen lassen . Unter Feinden. Wir können also sehen, dass die Animation noch nicht wirklich angezeigt wird. Also werde ich auf Öffnen und Editor klicken und wir werden sehen, was damit los ist. Wir müssen wahrscheinlich eine Standardanimation festlegen. Also könnte ich den Tod nehmen und ihn auf Untätigkeit umstellen. Lassen Sie es uns standardmäßig auf inaktiv setzen. Okay? Drücke auf Play. Lass uns zurück zur Spielwelt wechseln. Behebt das das? Ich glaube nicht. Okay, da das nicht funktioniert, sollten wir zum Reset gehen. Animation. Das heißt wenn Sie eine Animation nicht abspielen, sie auf diese Werte zurückgesetzt Und wir können sehen, dass der He-Rahmen hier, wenn wir oben rechts hinschauen, tatsächlich auf eins gesetzt ist Wenn wir das also auf vier setzen und ich glaube, jetzt beim Zurücksetzen auf Play drücken, dann sollten wir uns das ansehen, wenn wir zur Spielwelt zurückkehren. Also speichere deine Ork-Szene, gehe zur Spielwelt und okay, jetzt sieht sie richtig Also drücke ich W und bewege das C. Okay, und dann lass uns einfach D noch ein paar Cs duplizieren Und dann glaube ich, das Letzte, was wir hier tun wollen, ist, Feinde zu nehmen und bei Bestellung die Sortierung von Y zu aktivieren. Da das für alle Orks offensichtlich ist, wollen wir, dass die Orks auch untereinander sortieren Das könnte notwendig sein. Es könnte also notwendig sein, das dort einzustellen. Okay, unsere Speere können sich bewegen, aber sie können eigentlich nichts treffen Wir haben keine Hitbox eingerichtet und unsere Orks können existieren, aber sie haben keine HRT-Box, um tatsächlich Schaden zu nehmen HRT-Boxen und Hitboxen und Gadot D werden also Area Two Ds sein Wenn du aus Unity kommst, wäre das eher eine Triggerzone Gehen wir zu Spear und wir erstellen ein Gebiet zwei D, das wir zu unserer Trefferbox machen werden Also klicke ich mit der rechten Maustaste auf den Knoten Spear Add Child, Area Two D, und ich benenne ihn schnell in Hit-Box Two D um . Klicken wir mit der rechten Maustaste darauf und hängen ein Skript an Nun, das wird wahrscheinlich eher wie die Wurzel reingehen. Also lass mich sehen. Ich schätze, es ist hier sinnvoll, es in den Waffenordner zu legen und wir öffnen. Also erstellen wir das Skript bei Weaponlash Hit Box zwei D. Create geben ihm den Klassennamen Hit Box Two D. Okay, in unserem HIT-Box-Skript wollen wir also sofort eine Verbindung zu dem Signal herstellen, das der Bereich bereits hat , also Bereich betreten Denn wir versuchen zu überprüfen, ob wir den Bereich einer RT-Box betreten Wenn wir also die Funktion underscore ready machen, dann können wir bei Bereit den eingegebenen Bereich verbinden, und wir werden sie mit einem eingegebenen Bereich verbinden, was eine Funktion ist, die wir gerade einrichten Erstellen Sie also einen Funktionsunterstrich auf dem eingegebenen Bereich. Dieser wird empfangen und Bereich zwei D ist der Parameter. Also P Bereich zwei D und Rückgabetyp von v Okay, also ein Bereich hat diesen Bereich betreten, welche Art von Bereichen interessieren uns? Wir interessieren uns für Boxen, die speziell verletzt wurden. Also wenn P-Bereich eine Hurt-Box zwei D ist und der Typ noch nicht existiert, also sollte es hier eine Ära sein. Dann könnten wir vorerst etwas wie Ausdrucke sagen , dann könnten wir vorerst etwas wie Prance sagen, das eine Nachricht auf die Konsole drucken wird Warum versuchen wir es nicht so? Prozent und Anführungszeichen bedeuten, dass wir das durch eine Zeichenfolge ersetzen werden. Prozentsätze treffen. Wir könnten sogar bei Position sagen, Prozent, und dann werden wir diese Zeichenketten durch ein anderes Prozentzeichen ersetzen Und wir haben drei Zeichenketten , die wir innerhalb dieser Zeichenfolge ersetzen müssen Also werden wir eine Reihe von Werten übergeben , die wir für den Ersatz verwenden möchten. Also, der erste wird , sagen wir einfach, ich selbst sein. Also holen wir uns die Hit-Box, die die Hurt-Box im P-Bereich treffen wird. Und dann werden wir sagen, dass die Position die globale Position des P-Bereichspunkts ist . Ein Bereich zwei D befindet sich also immer noch auf Knoten zwei D, hat also immer noch eine globale Position. Das funktioniert, um einfach festzustellen, dass unsere Hit-Box tatsächlich auf die HRT-Box trifft. Okay, jetzt müssen wir eine RT-Box auf dem Oc bauen. Gehen wir also zum Oc und ich klicke hier mit der rechten Maustaste und erstelle einen Agile-Knoten, Area zwei D. Lassen Sie uns diesen in Hurt Box umbenennen, und ich werde das B für Box groß Zwei D. Klicken wir mit der rechten Maustaste darauf und hängen Sie ein Skript an. Wir werden Box zwei D verletzen wollen. Das kann vorerst einfach in Charaktere passen. Wir werden nicht wirklich zerstörbare Objekte haben, zumindest nicht in dieser Demo Sie könnten also argumentieren: Okay, das gehört eher in den Objektordner, oder vielleicht organisieren Sie Ihre Skripte insgesamt in einem Skriptordner, der speziell Skripte enthält Die Organisation liegt ganz bei Ihnen. So mache ich die Dinge einfach. Also, die Charaktere schneiden Hurt Box zwei D, wir werden es dort erstellen Okay, dieses Skript, wir müssen es den Klassennamen Hurt Box Two D nennen . Im Moment werden wir nichts anderes daran ändern Wir wollen nur das Identifizierungs-Tag, Hurt Box two D. Nun, die Hurt-Box, Sie können sehen, dass sie auch eine Kollisionsform benötigt. Klicken wir also mit der rechten Maustaste und fügen einen untergeordneten Knoten hinzu, die Kollisionsform. Und dann werde ich auf der rechten Seite eine neue Kreisform erstellen. So können wir definieren, wo dieser Charakter getroffen werden kann. Also könnte ich W drücken und es nach oben verschieben. Wir können es hier einfach ziemlich groß rausbringen. Also, wenn ich es größer machen würde, irgendwie so, wäre das in Ordnung. Vielleicht bevorzugen Sie auch eine Kapselform. Wenn wir also die Kapselform auswählen bevorzugen Sie vielleicht auch hier eine Kapselform. Wenn wir also eine Kapselform haben, die eher einer Humanoiden ähnelt, können wir die Kapselform wählen Und dann hier drüben können wir einfach W drücken und es hierher verschieben Das wäre gut, wenn Sie möchten, dass alle Pixel, die auf dem Bildschirm für das K angezeigt werden, tatsächlich schädliche Bereiche sind. Sie könnten also dieses Argument vorbringen. Und dann wollen wir einfach, dass es ein Kind von The Hurt Box Tot ist. Und dann braucht unser Ork auch eine Kollisionsform. Also wo können die Füße für das C kollidieren? Also das wird hier als Kreisform sinnvoller Und dann schauen wir uns die Füße der Orks an. Lass es uns hier einfach verkleinern, so etwas in der Art. Wenn wir uns also für Kollisionen zwischen unseren Orks und anderen Orks oder Orks und dem Spieler, anderen Requisiten und dem Objekt entscheiden zwischen unseren Orks und anderen Orks oder Orks und dem Spieler, anderen Requisiten und dem würden, dann ist das die Form, die wir eigentlich dafür verwenden würden Nun, wenn du willst, dass deine Feinde mit anderen Feinden und Spielern kollidieren und so , wenn sie sich bewegen, indem du Bewegen und Rutschen benutzt, dann ist das etwas, was ein Charakterkörper zwei D sofort tun kann Aber das wird mit Leistungseinbußen verbunden sein, da es tatsächlich Bewegungen auf der Grundlage von Physik berechnet Bewegungen auf der Grundlage von Physik Wenn Sie die maximale Anzahl an Zeichen auf dem Bildschirm haben möchten , könnten Sie stattdessen die Option Translate verwenden, genau wie wir es mit dem Speer gemacht haben. Das heißt, er bewegt sich einfach, unabhängig davon, was auf dem Bildschirm angezeigt wird , in die Richtung , in die er sich zu bewegen versucht Wenn Sie es also so dämlich und einfach wie möglich halten , liegt es ganz bei Ihnen, was Sie am Ende des Tages wollen Und wie viele tausend Feinde du gleichzeitig auf dem Bildschirm haben musst Okay, bevor wir das zum Abschluss bringen, denke ich, dass der Speer auch eine Kollisionsform für die Trefferbox braucht eine Kollisionsform für die Trefferbox Also klicke ich hier mit der rechten Maustaste, füge einen untergeordneten Knoten hinzu, Kollisionsform zwei D. Wir gehen nach oben rechts Machen wir daraus eine Kreisform und dann nehmen wir die Kreisform und bewegen sie bis zur Spitze des Speers und verkleinern sie, etwa so Vielleicht bevorzugen Sie eine Kapselform. Es hängt irgendwie davon ab, wie wählerisch du sein willst. Kapsel könnte offensichtlich eher ein Oval oder weniger ein reiner Kreis Oder vielleicht sogar nur ein Rechteck. Wenn du also ein Rechteck verwenden möchtest, könntest du, sagen wir, hier oben rechteckig machen , die Seiten so verkleinern, das nach unten ziehen und vielleicht so Also hier die einfachste primitive Form wie möglich für die Trefferbox verwenden hier die einfachste primitive Form wie möglich für und trotzdem versuchen, die tatsächliche Form des Sprites beizubehalten , wo es Sinn macht Also ich denke, das wäre ziemlich gut. Ich glaube nicht, dass irgendjemand wirklich merken würde, dass, weißt du, vielleicht diese Hälfte des Speers hier nicht getroffen hat Wenn du wirklich wählerisch sein willst, könntest du es so machen Und ja, vielleicht wäre das ein bisschen besser. Nur ein bisschen weniger Chance, dass es es trifft, könnte hier entlang der Kante nach links rutschen. Noch einmal, eins von diesen mehr, probiere es aus und mach dir ein Gefühl dafür, wie es funktioniert, und ob es für dein Spiel geeignet ist oder nicht. Lass uns das Spiel jetzt starten und versuchen, die Orks dazu zu bringen mit diesen Projektilen zuzuschlagen Mal sehen, dass keine Null instanziiert werden kann. Ebene. Okay. Also momentan ist das Projektil nicht mehr auf die Waffe Zwei D gerichtet. Das ist interessant Gehen wir zum Spieler und ich nehme die Waffe zwei D. Wir können sehen, dass die Waffendefinition hier festgelegt ist. Wenn ich Waffe zwei D erweitere, kommen wir zur Waffendefinition. Wir haben also das Suchsymbol. Vielleicht habe ich die Waffe bewegt. Lass uns sehen. Wo ist Spear? Ich habe Spear versehentlich von Weapons Spear in diesen anderen Ordner verschoben Weapons Spear in diesen anderen Ordner Lassen Sie uns das also zurück zu Waffen verschieben. Okay, jetzt wird es gut funktionieren. Wir drücken Load. Okay, und dann haben wir die Speere. Gehen wir also zur Ausgabe. Ich werde das etwas nach unten verschieben, diese Orks werden tatsächlich vom Speer getroffen, was gut ist Wir können die Position sehen, an der das passiert ist. Die Informationen in der Trefferbox sind nicht allzu nützlich, aber zumindest wissen wir, welcher Typ auf welchen Typ trifft. Wenn es ein ganz anderer Gebietstyp wäre, würde hier der Klassenname dafür stehen. Und das funktioniert ziemlich gut. 16. Füge Gegnern mit Hitboxen und Statistiken Schaden zu: Trefferboxen und Verletzungsboxen funktionieren so gut, dass wir den Treffer auf der HT-Box aufnehmen können, was der Anfang sein wird, um unseren Ork-Feinden Schaden zuzufügen. In diesem Video müssen wir also die Statistiken für den Ork einrichten und sicherstellen , dass wir bei einem Treffer Schaden an den Ork weitergeben , der Schaden erleiden wird Ein großer Teil dieses Tutorials wird darin bestehen , die Werte des Speers und die Statistiken des Orks zu definieren und die Interaktion zwischen den beiden einzurichten die Interaktion zwischen den beiden Wenn wir also in das Projektil-Skript springen, möchten wir, dass das Projektil reagiert, wenn die Trefferbox auf die Verletzungsbox trifft , indem es den Schaden des Projektils an die Verletzungsbox weitergibt Projektils an die Verletzungsbox Also werde ich eine AT-Export-Variable für Trefferboxen einrichten. Das wird eine Reihe von Hit-Box zwei D sein. Okay. Nun, die möchte ich bei der Inspektion zuweisen . Wenn ich also auf Spear-Array zwei D klicke, ist die Reihe der Trefferboxen hier drüben. Wir müssen es auf eins vergrößern , auf ein Zeichen auf dem ersten Element klicken und dann Hit Box wählen Jetzt haben wir also einen Verweis auf das Trefferfeld für das Projektil im Skript Es wird als Array erstellt, weil manche Waffen tatsächlich zwei oder mehr Trefferboxen haben Also machen wir das hier von Anfang an zu einer Option. Und wir werden bei jedem Treffer eine Verbindung zu jedem Trefferbox-Signal , sodass unser Projektil den Schaden anrichten kann Klicken wir also mit der rechten Maustaste auf das Symbol Hit Box zwei D., machen Sie Lou-Symbol, und das springt zum Hit-Box-Skript Also anstatt zu drucken, was wir getroffen haben, wollen wir das, was wir getroffen haben, ausgeben. Lassen Sie uns also hier oben ein Signal erzeugen. Immer wenn die Trefferbox einen Treffer erkennt, werden wir das Ziel, das wir getroffen haben, oder in diesem Fall die Verletzungsbox , die wir getroffen haben, weitergeben . Also sagen wir hier Hurt-Box ist eine Art Rt-Box zwei D. Okay. Also anstatt hier zu drucken, schneiden wir das aus, und ich sage , drück Punkt EMIT, und wir werden das mit dem P-Bereich als Hurt-Box zwei D übergeben . Wenn wir also jetzt zum Projektil-Skript übergehen, können wir einfach eine Wenn wir also jetzt zum Projektil-Skript übergehen, Verbindung zu dem Signal herstellen, das bereit ist Also lass uns das machen, bevor wir den Teil „Warten“ machen. Zuerst sagen wir, dass die Trefferfelder nicht leer sind. Also wollen wir nicht , dass das wahr ist. Wir könnten also sagen, ist gleich, ist falsch und sagen, dass mindestens eine Trefferbox benötigt wird, um ein Ziel zu treffen Nun, das hängt ein bisschen davon ab , was Ihre Absicht Sie könnten theoretisch ein Projektil haben , das nicht getroffen werden muss Diese Behauptung ist vielleicht nicht notwendig, aber für unser Spiel wollen wir, dass Projektile feindlichen Zielen Schaden zufügen können Schaden zufügen Also werden wir diese Behauptung da drin lassen. Nach unseren Behauptungen können wir also vier Boxen und Hit-Boxen sagen Wir sagen Box Dot Hit Dot Connect, und wir könnten sagen, bei Hit Box Hit Also werden wir dieses Signal mit einer neuen Funktion verbinden , die wir hier unten aufschreiben. Funktion auf Hit Box Hit benötigt also ein P Hurt-Feld , könnte ein HRT-Unterstrichfeld verwenden wenn wir konsistenter sein wollen Und das wird vom Typ Hurt Box Two D sein und ungültig zurückgeben Okay, also mit der HRT-Box werden wir, sagen wir, P Hurt-Box nennen. Nehmen wir an, DL-Schaden, und die Höhe wird auf unseren Berechnungen hier basieren . Woher nehmen wir also den Schaden, um ihn zu berechnen? Nun, lassen Sie uns hier einfach den endgültigen Schaden deklarieren. Und wir setzen das vorerst auf zehn. Und das wird eine Ganzzahl sein. Der gesamte Schaden und die HP im Spiel werden also auf Ganzzahlen basieren. Nur um es einfach zu halten, technisch gesehen könntest du einen Bruchteil einer Schadenseinheit anrichten, aber das ist ziemlich verwirrend. Die meisten Spiele verwenden nur Ganzzahlen. Okay, also sagen wir, dass wir es hier mit dem endgültigen Schaden zu tun haben, und wir werden uns später um die Schadensberechnung kümmern Wir könnten also sagen, wir müssen die Schadensberechnung durchführen. Okay, jetzt zu unserer Hurt-Box, wir wollen diese Schadensmethode hinzufügen. Gehen wir rüber zu Hurt Box. Also sage ich, Funktion verursacht Schaden und wir geben den Schaden einer ganzen Zahl weiter. Oh, wir könnten hier gleich einen Rückgabetyp angeben, ich gebe ihn einfach als ungültig zurück, weil wir erwarten, dass der Schaden, den wir verursachen auch der Schaden ist, den es erleidet. rechnen wir im Projektil-Skript diesem Fall rechnen wir im Projektil-Skript und nicht im Hurt-Box-Skript Lassen Sie uns es tatsächlich in einen booleschen Rückgabetyp ändern. Also werde ich sagen, versuche hier Schaden zu verursachen. Der Grund dafür ist, dass wir eine Bedingung stellen, dass es möglich ist , dass die Statistiken nicht getroffen werden können, also werden wir das hier regeln lassen. Der letzte Schwachpunkt, ob es tatsächlich Schaden erleiden wird, ist also die Unbesiegbarkeit der Statistiken Ich denke, das ist aus Sicht der Box sinnvoller aus Sicht der Box Also sagen wir, wenn nicht, kann ein Punkt im Statistik-Controller getroffen werden, dann geben wir Falsch zurück. Nun sind es die Statistiken, auf die wir den Schaden anwenden. Es wird die Laufzeitstatistiken für den Charakter verwalten. Also müssen wir das alles in einer Minute einrichten. Also wäre jetzt wahrscheinlich der richtige Zeitpunkt, um das einzurichten. Also hier oben werden wir bei Export VR, einer Stack-Controller-Referenz, vorgehen wollen . Das wird also vom Typ Stack-Controller sein. Also erstellen wir ein neues Skript mit. Gehen wir zur Organisationsszene in der 2-D-Ansicht, klicken mit der rechten Maustaste darauf und fügen einen untergeordneten Knoten hinzu. Das wird also ein regulärer Knoten sein. Es ist kein Positionsraum. Das ist ein Statistikmanager, es ist also alles Datenbank. Daher ist es ein Knoten, kein Knoten TD. Und wir nennen es Stat Controller. Ordnung, klicken Sie hier. Wir werden ein Skript anhängen. Also wird es einfach Sat Controller heißen und wir werden es in den Ordner des Charakters legen, weil unser Hauptspielercharakter auch einen Stack-Controller haben wird . Lassen Sie uns das Skript erstellen. Ich werde den Klassennamen eingeben und den vPasteDN Stat Controller steuern weil ich ihn aus dem anderen Skript kopiert habe Dies verwaltet die Laufzeitstatistiken für ein Objekt. Also werden wir Dinge wie varaHP haben , was eine Ganzzahl ist, und wir können das auf einen Standardwert setzen, vielleicht 100 Wir haben auch Var Max HP, was dasselbe sein kann. Die Idee wird sein, dass der HP niemals über dem MX HP gesetzt werden kann . Also, wenn du dich jetzt einfach darum kümmern willst, werden wir hier am Ende noch einen coolen reinlegen, und ich sage Sollwert. HP wird also gleich den Männern mit dem Wert und dem MaxHP sein den Männern mit dem Wert und dem MaxHP Okay, das hier begrenzt es einfach so, dass Sie die immer über der MaxHP setzen können Vielleicht wollen wir auch eine Variable für ist das Objekt lebendig. Also sagen wir Far Live, das wird ein boolescher Wert sein. Es wird standardmäßig auf true gesetzt. Und dann brauchen wir die Funktion , bei der wir einen Fehler bekommen haben. Wenn ich also Hitbox ankreuze, gibt es die Funktion „Kann getroffen werden Das müssen wir umsetzen. Gehen wir also zu Stat Controller. kann eine Funktion aufgerufen werden, Es kann eine Funktion aufgerufen werden, die einen booleschen Wert zurückgibt Also können wir hier die Bedingungen festlegen, die wir wollen. Im Moment werden wir sagen , dass wir live zurückkehren werden. Wenn der Charakter also am Leben ist, kann er getroffen werden. Andernfalls kann er nicht getroffen werden. Also hier drüben, wenn es am Leben ist, dann kann es getroffen werden, aber das ist das Gegenteil mit dem K. Also, wenn es nicht lebt, dann geben wir Falsch zurück. wenn es nicht lebt, dann geben wir Falsch zurück Im Grunde genommen. Nun, hier unten sagen wir Return True weil wir davon ausgehen , dass es zu diesem Zeitpunkt Schaden angerichtet hat, weil die Bedingungen erfüllt waren. Wir haben die Guard-Klausel bereits verabschiedet. Also wollen wir den SAP-Controller nehmen, und wir wollen seine HP nehmen und ihn auf den neuen Wert setzen. Vielleicht möchten wir das direkt darüber berechnen. Und als lokale Variable. Neue HP wird also gleich dem Stat-Controller-Punkt sein . HP minus entspricht dem Schaden oder sogar nur minus Die Aufgabe befindet sich also hier links neben der neuen HP Also setzen wir die HP des Stat-Controllers auf die neue HP und wir geben true zurück. Vielleicht möchten wir hier auch ein Signal einfügen , das die Rt-Box aussendet, was auch ein Treffersignal wäre Okay, ich möchte also alles bis jetzt testen. Ich werde hier auf der linken Seite einen Breakpoint setzen , damit wir ihn beim Debuggen treffen können, falls die Waffe dem Charakter Schaden zufügt Also lasst uns auf Play klicken und schauen , ob es an dieser Stelle funktioniert. Ich bin mir sicher, dass mir ein paar Dinge fehlen. Wir können hier unten sehen, dass es keinen Schaden gibt, weil es jetzt tatsächlich Tri-Deal-Damage ist. Also haben wir den Namen geändert und dann machen wir das nochmal. Haben wir den Breakpoint erreicht? Wir kommen hierher. Der Stack-Controller kann getroffen werden, aber wir haben den Stack-Controller nicht wirklich der RT-Box zugewiesen . Dies könnte also ein weiterer Fall sein , in dem wir oben bestätigen wollen , dass der SAT-Controller tatsächlich eingestellt wurde. Assert Stat Controller ist also nicht gleich Null. Die HRT Box benötigt eine Controller-Referenz, um wirksam zu werden. Die HRT-Box benötigt also eine Referenz zum SAT-Controller damit sie ihre Statistiken ändern kann. Also lass uns sehen. Wenn wir hier oben zu TD View, Lokaler Modus gehen hier oben zu TD View, Lokaler Modus und dann auf die RT Box klicken, weisen wir hier rechts den Stack-Controller zu. Für den Fall, dass wir zu irgendeinem Zeitpunkt eine Verletzungsbox vergessen, haben wir die Gewissheit, einen Fallback zu haben, der uns auffängt Lassen Sie uns das noch einmal ausführen. Wir werden das überprüfen und Sie können sehen, dass wir wahr geworden sind. Sie können auch unten sehen, dass die neue HP auf 90 gesetzt wurde. Unsere Basis-HP für den Statistik-Controller sind 100, also 100 minus zehn, wir erhalten 90, sodass wir wissen, dass das tatsächlich korrekt aktualisiert wird. Und das nächste, was wir zu Beginn des nächsten Videos tun werden, ist, die Ork-Zustandsmaschine so einzurichten , dass wir von lebendig zu tot wechseln können, sobald die HP auf Null und dann den Ork aus der Szene entfernen 17. Todeszustand, wenn der Feind 0 PS erreicht: Jetzt wollen wir eine Zustandsmaschine für unsere Feinde einrichten. Es wird unglaublich einfach sein. Es wird auf Anhieb nur zwei Zustände geben, nämlich den Zugzustand oder den Todeszustand, wodurch er aus dem Spiel Klicken wir also mit der rechten Maustaste auf Oc füge einen untergeordneten Knoten hinzu. Ich werde hier HSM sagen und wir werden uns das Limbo HSM schnappen Wir könnten es in Enemy HSM umbenennen, und dann werde ich mit der rechten Maustaste darauf klicken und ein Skript Das wird also direkt in den feindlichen Ordner Slash EnemySHSM werden wir erstellen. Stellen Sie hier das Oberteil auf. Feindliches HSM. Das ist die Zustandsmaschine für Feinde innerhalb des Okay, also wenn man sich das Spieler-SM anschaut, wird es hier wirklich ähnlich sein Ich denke, weil wir tatsächlich auf Blackboard umgestiegen sind , benötigt dieses Skript keinen direkten Verweis mehr auf den Animation-Player, was richtig wäre, wenn ich hier im Blackboard-Plan nachschauen hier im Blackboard-Plan Die zweite Referenz ist nicht erforderlich. Also kann ich das einfach genau da rausschneiden. Also werden wir diesen Code vom Spieler-HSM in das feindliche HSM-Skript kopieren . Nehmen wir also an, dass es sich nicht um ein Spieler-Skript handelt, sondern um ein NPC-Skript, auf dem die Statistiken festgelegt werden könnten NPCs vom Typ NPC behaupten also , dass der NPC nicht Null ist. Also muss der NPC-Agent auf dem HSM eingestellt sein, und wir werden ihn mit dem NPC-Skript initialisieren Also ich ändere hier meistens die Namen. Also das NPC-Skript, gehen wir zur Orkszene rüber zu D View Und wir wollen auf OC klicken und ein Skript anhängen Wir sagen, das ist ein NPC, und wir werden es in Charakteren und nicht in Charakterkürzel Enemy einbauen, oder es könnte in Feinden sein, die dir überlassen Wir werden dieses Skript für den Charakterkörper erstellen. Und nennen wir diesen ClassName NPC. Der NPC wird also nur einen einfachen Verweis auf den Stack-Controller haben Damit wir diese beiden Dinge nicht unbedingt getrennt referenzieren müssen diese beiden Dinge nicht unbedingt getrennt referenzieren Innerhalb der Zustandsmaschine ist es sehr praktisch, vom Agenten aus auf Eigenschaften zuzugreifen, da Sie immer wissen, dass der Agent in jedem State-Machine-Skript vorhanden sein wird , sobald Sie ihn auf der Zustandsmaschine initialisiert haben ihn auf der Zustandsmaschine initialisiert Wenn wir hier also VAR-Statistiken exportieren und dann Stack-Controller sagen, dann können wir auch innerhalb der Zustandsmaschine darauf verweisen auch innerhalb der Zustandsmaschine Also hier auf der rechten Seite weisen wir den Stack-Controller zu, und jetzt innerhalb des feindlichen HSM sollten die Fehler verschwinden, solange wir auf Enemy HSM klicken. Nun, das ist nicht richtig Da soll NPC stehen. Also müssen wir nur das Cadle-Projekt neu starten, zu Projekt gehen und das Projekt neu laden Okay, und das sollte das beheben. Jetzt weisen wir den Ork zu, das ist der NPC, und wir haben einen Verweis auf den Agenten und die Statistiken, und das sollte das meiste sein, was wir für unsere Zustandsmaschine benötigen Okay, klicken wir mit der rechten Maustaste auf das feindliche HSM. Ich füge einen untergeordneten Knoten hinzu. Und lass uns einen Limbo-Staat machen. Ich könnte das umbenennen und so etwas wie NPC Move State sagen etwas wie NPC Move State Nun, klicken Sie mit der rechten Maustaste auf ein Skript anhängen. Erstellen. Okay, lassen Sie uns als Nächstes einen Verfolgungsjagd-Status für den Feind erstellen. Hier wird die Kernlogik für die Bewegung unseres Charakters zum Spieler liegen. Außerdem wird die Run-Animation abgespielt sobald wir den Status erreicht haben . Also klicke ich mit der rechten Maustaste auf das feindliche HSM. Fügen wir einen untergeordneten Knoten hinzu, einen Limbo-Status. Ich benenne ihn in Chase State um. Und ich werde hier mit der rechten Maustaste klicken und ein Skript anhängen. Also Chase, Staat, der wahrscheinlich einem Feind gehört. Ich drücke Create. Okay. Geben wir ihm oben einen Klassennamen, Chase State, und wir geben ihm einen Kommentar. Am Ende läuft das also auf den Spieler zu , wo auch immer es sich im Spiel befindet. Im Moment lassen wir es einfach die Animation abspielen. Wir werden einen Übergang vom Status Verfolgungsjagd in den Todeszustand einrichten und nur dafür sorgen, dass unser Charakter auf 0 HP fällt der Feind im Spiel lebendig bleibt, wenn unser Charakter auf 0 HP fällt. Also sagen wir Funktion Unterstrich, Enter. Wenn wir eingeben, wollen wir die Run-Animation abspielen. Wir können also sogar die Funktion Underscore einrichten und dann holen wir uns den Animations-Player Bisher unterstreichen wir den Animations-Player vom Typ Animation-Player, und wir werden ihn aus dem Blackboard holen , genau wie wir es mit dem Player gemacht haben Animation-Player entspricht also Blackboard Dot Get Var. Und wir suchen nach dem Animations-Player für Endzitate und möchten uns beschweren, wenn wir ihn nicht finden Wir haben also den Animations-Player. Wenn wir den Staat betreten, spielen wir die Animation ab. Also sagen wir Underscore Animation Player Dot Play und wir wollen die Animation abspielen, die wir hier oben definiert haben Machen wir das bei Export var. Sagen wir Chase-Animation. Sicher. Und das wird ein Zeichenkettenname sein. Ich lasse es standardmäßig laufen. Und dann kopieren wir das hier runter. Also spielen wir die richtige Animation ab , wenn wir den Staat betreten. Okay, und unser Enemy HSM, wir haben es bereits initialisiert Wir haben es bereits aktiviert. Also wird es wahrscheinlich funktionieren. Also können wir sehen, ob es jetzt läuft. Lass uns in den Spielmodus gehen. Oh, wir haben den Animations-Player natürlich nicht in das Blackboard integriert Es sagt uns also sofort , dass es ein Problem gab. Das ist gut. Klicken Sie auf Enemy HSM, wechseln Sie zum Blackboard-Plan und lassen Sie uns New Blackboard Plan erstellen, ihn verwalten und einen variablen Animation-Player hinzufügen Wählen Sie den Typ des Knotenpfads. Klicken Sie auf Okay. Und jetzt wollen wir einen Animations-Player dem Animations-Player des Or zuweisen dem Animations-Player des Or und jetzt können wir ihn innerhalb unserer Bundesstaaten verwenden. Okay, drücken Sie erneut auf Play. Und lass uns sehen, ob unsere Orks rennen. Das sind sie alle Das ist großartig. Also brauchen wir unseren Todesstaat und wir müssen unseren Übergang einrichten. Also klicke ich mit der rechten Maustaste auf Enemy HSM und füge einen untergeordneten Knoten hinzu, der Limbo State heißen wird Benennen Sie ihn in Death State um. Klicken Sie mit der rechten Maustaste, hängen Sie ein Skript an und klicken Sie auf Erstellen. Wir nennen es oben Death State. Also Klassenname Death State. Okay, jetzt in unserem Todeszustand müssen wir auch eine Animation abspielen, die der, die wir im Chase-Zustand gemacht haben, sehr ähnlich ist. Das ist Code, den wir hier irgendwie wiederholen werden, aber weil wir nur ein paar Zustände für unser Spiel erstellen, denke ich, dass Dinge wie das Erstellen einer neuen Basisklasse im Moment einfach ein bisschen zu aufwändig sind. Also werde ich das einfach kopieren. In den Todesstaat. Nun, füge das ein. Und ich könnte einfach sagen, dass die Animation , die wir für den Todeszustand wollen , standardmäßig auf Tod gesetzt ist und wir bekommen die Animation auf die gleiche Weise abgespielt Aber dann wollen wir die Animation hier drüben abspielen. Und da wir keinen Basisstatus verwenden, müssen wir uns auch keine Gedanken über Dinge wie Aufrufen von Super machen, um sicherzustellen, dass der Animationsstatuscode tatsächlich das Aufrufen von Super machen, um sicherzustellen, dass der Animationsstatuscode tatsächlich ausgeführt wird, weil beide Setup verwenden werden und beide Enter verwenden werden. Wenn Sie ein neues Setup oder eine neue Enter-Funktion deklarieren, überschreibt sie tatsächlich alles, was in der Basisklasse steht, falls Sie vergessen, Super aufzurufen, und Sie würden Super übrigens so aufrufen Super bedeutet einfach, dass Sie, was auch immer die übergeordnete Klasse ist, sie zu diesem Zeitpunkt ausführen Sie können also sehen, dass es ein bisschen schwierig und verwirrend ist, diese Art der direkten Vererbung zu verwenden. Wenn Sie etwa fünf oder zehn verschiedene Zustände haben, die alle Animationszustände sind, weil sie sich alle auf genau die gleiche Weise in der Animation abspielen, dann lohnt es sich, das irgendwie zu haben. Aber wir werden buchstäblich nur Chase und Death haben , also ist es übertrieben Aber Tay sollte erwähnen, dass das auch eine andere Art ist, Dinge zu tun Bei Inter wollen wir also im Grunde unseren Charakter unbesiegbar machen Also möchten wir vielleicht so etwas wie Agent Dot Stats Dot LI machen , und wir wollen sicherstellen, dass das auf Falsch gesetzt ist Denken Sie also daran, dass, wenn ein Statistik-Controller nicht aktiv ist, dann kann getroffen werden, der Wert falsch zurückgegeben wird. Dadurch wird verhindert, dass wir versehentlich einen Charakter treffen, der sich im Todeszustand befindet. Sie machen auch so etwas wie, sagen wir, die Funktion ist fertig, und wir deklarieren diese Funktion, damit Sie sie tatsächlich aus der Animation oder an anderen Stellen aufrufen können . Und wir werden sagen, dass der Agent dich befreien muss. Also Agent Qu ist frei. Also das bedeutet im Grunde die Route Aosne, die Organisation. Wir werden es und alles, was darin ist, befreien. Wenn wir die fertige Methode aufrufen. Jetzt können wir hier unten zum Two-D-View-Animation-Player wechseln. Wir gehen zur Todesanimation. Wir vergrößern die Zeitleiste und gehen hier bis zum Ende. Wir fügen Track hinzu, rufen Methoden-Track im Todeszustand auf. Und dann klicken wir mit der rechten Maustaste hier unten, fügen einen Schlüssel ein und wir suchen nach der fertigen Methode, die wir gerade erstellt haben. Das heißt also, wenn unsere Todesanimation fertig ist, wird sie im Todeszustand beendet aufgerufen und der Todesstatus wird den Agenten freigeben , sobald der Frame mit dem Rendern fertig ist und alles andere gelöst Normalerweise rufen Sie Quarter, nicht Free, Free Freeze sofort auf und Quarter wartet, und Quarter wartet bis andere Operationen korrekt Das würde also tatsächlich die Anzahl der seltsamen Bugs reduzieren , die Sie bekommen könnten, wenn Sie sich entscheiden. Okay, das Letzte, was wir tun müssen, ist in das feindliche HSM zu springen Lassen Sie uns eine neue Funktion für Setup-Übergänge erstellen, die als ungültig zurückgegeben wird Wir möchten also einen Übergang von unserem Verfolgungsstatus in den Todeszustand hinzufügen unserem Verfolgungsstatus in den Todeszustand , wenn das Todesereignis ausgelöst wird. Wenn Sie hier also ein Ereignis wie dieses deklarieren, ist das nur eine Zeichenfolge, auf die unser System reagieren wird . Wir könnten hier hochgehen und ein konstantes Todesereignis auslösen. Es wird ein Zeichenkettenname sein, der entspricht , dass wir den Tod in Kleinbuchstaben schreiben, das dort einfügen und wir können uns diese Weise mit den Statistiken auf unserem Agenten verbinden Nehmen wir an, der NPC Dot Stats Alive hat sich geändert. Wir haben dieses Signal nicht erzeugt, aber ich mache einfach weiter und springe hierher, also stelle eine Verbindung her Der Underscore auf NPC Alive wurde geändert. Okay, also ich kopiere das nach unten, Funktion einfügen auf NPC live geändert, und das wird den neuen Wert haben Alive ist also ein boolescher Wert. Könnte P für Parameter sagen, wenn wir hier wollen. Normalerweise mache ich das gerne. Und das wird zu einer Art Leere führen. Wenn der NPC also nicht mehr am Leben ist, möchte ich das Todesereignis auslösen Also, wenn P alive gleich False ist, dann werden wir das Death Event auslösen Okay. Und wenn wir den Übergang hinzufügen, bedeutet das, dass dieser Übergang stattfinden wird , wenn dieses Todesereignis eintritt. Jetzt erhalten wir immer noch eine Fehlermeldung, weil wir hier oben weder den Chase-Status noch den Todesstatus haben weder den Chase-Status noch den Todesstatus . Wir können also einfach sagen, bei Export var Chase State, was ein Limbo-State ist, und bei Export var Death State, was ein Limbo-State ist Speichern Sie jetzt das Skript im Inspektor. Wir können den Status Chase und den Todesstatus zuweisen. Und jetzt, sobald wir die Einrichtungsübergänge aufrufen, kümmert es sich um die Verwaltung dieser Übergänge. Ich denke, wir wollen das vor der Initialisierung oder vielleicht gleich danach aufrufen oder vielleicht gleich danach Lass es uns gleich danach machen. Unterstreichen Sie also die Einrichtungsübergänge nennen wir. Wir richten unsere Übergänge ein. Es sollte nicht nötig sein, einen Todesstaat zu schaffen , um dem Staat hinterherzujagen , weil wir derzeit keine Feinde haben , die wieder zum Leben Sie können später so etwas hinzufügen. Das wäre sicherlich ein gängiges Thema, vor allem bei untoten Feinden Okay, das Letzte, damit das wirklich schnell funktioniert, ist, zur Speerszene zu gehen und in die Speerszene zu gehen und in die Trefferbox zu springen, oder ist es der Speer? Richtig, der Speer Und wir wollen den letzten Schaden nehmen und ihn auf 100 setzen, sodass ein Treffer einem besiegten Ork entspricht Drücke auf Play und lass uns sehen, ob das alles zusammenpasst. Es gibt uns also einen Fehler. Ich habe kein Live-Change-Event in den NPC-Statistiken erstellt Live-Change-Event in den NPC-Statistiken Klicke mit der rechten Maustaste auf das NPC-Symbol und gehe zum Lou-Symbol. Rechtsklick auf das Symbol, Lou-Symbol, Rechtsklick auf Stat Controller, Lou-Symbol Okay, und hier sind unsere Statistiken. Lassen Sie uns das Signal erzeugen, sodass wir sagen könnten, dass sich das Signal live verändert hat. Und das wird den neuen Live-Wert als Boolean übergeben den neuen Live-Wert als Boolean Wir kommen zurück und weisen weitere Signale zu, aber im Moment möchte ich sicherstellen, dass dieses Signal wenn sich ein Live-Wert Also werde ich „Wert festlegen“ sagen. Also zuerst werden wir uns davor schützen, dass der Wert derselbe ist wie der Wert, der ihm zugewiesen wird. Wenn also ein Leben gleich ist, werden einfach zwei Gleichheitszeichen für den Wert zurückgegeben. Andernfalls entspricht ein Live einem Wert. Und schließlich wird ein geänderter Live-Punkt mit dem neuen Wert ausgegeben Also wo wollen wir Alive berechnen? Also, ein guter Ort dafür wäre dieser HP-Setter. Wann immer sich die HP ändert, wollen wir also überprüfen, ob der Charakter noch am Leben ist Das bedeutet, dass nur live sein wird , wenn HP größer als Null ist. Okay, das ist erledigt. Jetzt haben wir das Live-Change-Event. Das alles sollte ausgelöst werden, wenn der Charakter null HP erreicht. Lasst uns das Spiel beenden und es erneut ausführen und schauen, ob wir es mit einer Waffe treffen, entfernt sich der Charakter von selbst? Geht es in den Todeszustand über? Und wir können sehen, dass die Antwort ja lautet. Es nimmt also 100 Schaden. HP erreicht Null. Ein Live wird auf False gesetzt. Das Signal wird ausgegeben. Und dann bedeutet das, dass auf der feindlichen Staatsmaschine der Übergang ausgelöst wird, weil dieses Signal eingetroffen ist. Dieser Patch auf dem feindlichen HSM sendet das interne Ereignis aus. Diese State-Machine-Ereignisse sind also getrennt von Signalen. Diese sind nur für die Zustandsmaschine in Limbo KI-Signale im größeren Kontext von Gadot Wir bekommen also dieses interne Todesereignis, und das bringt uns dazu, vom Chase-Zustand zum Todeszustand überzugehen Innerhalb des Todeszustands spielen wir die Animation Tod auf Enter ab . Allerdings achten wir darauf , dass dieser Wert hier auf Falsch gesetzt ist. Theoretisch müsste man das nicht tun, aber ich glaube nicht, dass es schaden wird sicherzustellen, dass, wenn wir den Todeszustand spielen, dass der Charakter nicht mehr am Leben ist, ich denke, das ist in Ordnung. Und dann haben wir die fertige Methode, die wir eigentlich nur aus der Animation aufrufen. Wie du bereits gesehen hast, ruft die Todesanimation hier unten es direkt am Ende unserer Animation auf, und so lassen wir unsere Feinde live werden, sobald sie auf null HP fallen. Ich weiß also, dass viele Teile zusammenkommen. Ich würde für diesen Teil empfehlen, falls du du dir den für dieses Video schnappst, wenn du, du weißt schon Schnappschüsse der einzelnen Teile noch nicht heruntergeladen hast, dass du dir den für dieses Video schnappst, wenn du, , Schluckauf hast und schaust, wo dein Drehbuch vielleicht nicht stimmt Was wir hier also mit Signalen machen , ist das Es ist wirklich nützlich, wenn Sie möchten, dass ein Codeteil auf eine Änderung in einem anderen Teil Ihres Codes reagiert . Und so etwas wie C Sharp, das würde man Events und dann Event Handling nennen. Aber in Gadot heißt es Signale. Im Wesentlichen handelt es sich jedoch um dasselbe Konzept . Es ist also ein Beobachtermuster. Wenn du das nachschlagen und mehr darüber lesen willst. Das wird also ein Abschluss sein 18. Dreh- und Zielprojektile bei Waffenauslastung: Okay, in diesem Video werden wir es so machen, dass sich unser Speer nach der Instanzierung in die richtige Richtung dreht und dass wir den Speer auch in die richtige Richtung starten können Speer auch in die richtige Richtung starten Wie wir das einrichten müssen, steht in unserem Weapon-2-D-Skript unserem Weapon-2-D-Skript In unserem Survivor-ähnlichen Spiel wollen wir es wahrscheinlich so gestalten, dass ein Charakter mehrere Waffen gleichzeitig haben kann Daher ist es tatsächlich sinnvoll, eine Art Manager für all diese Waffen zu haben eine Art Manager für all diese Waffen zu Wir können also ein Waffenausrüstungsskript erstellen , das für diese Waffe zwei D offensichtlich ist, und wir könnten es als Beispiel verwenden, um Dinge wie den Spielerimport für unsere Waffen individuell zu lösen den Spielerimport für unsere Waffen individuell Klicken wir also mit der rechten Maustaste auf den Player-Node und fügen einen neuen Child-Node Ich nenne diesen Knoten zwei D, und dann werden wir ihn in Waffenausstattung umbenennen werden wir ihn in Waffenausstattung Wir werden hier sofort Waffe zwei D der Waffenausstattung zuordnen, und ich sollte Waffe zwei D so umbenennen, dass sie wie eine Speerwaffe aussieht , sodass deutlich wird, was sie tatsächlich enthält Und dann klicken wir auf Waffenausstattung und fügen ein Skript hinzu. Das wird also eine Waffenausstattung sein , die Sie im Player aufrufen, erstellen und dann oben die Waffenausstattung mit Klassennamen Das wird also ein Manager-Skript für alle Waffen sein , die ein Spieler ausgerüstet hat Hier könnten wir uns also einfach einen kurzen Verweis auf die Spielereingaben verschaffen. Okay, und jetzt können wir zum Speerwaffen-Skript gehen und darauf bestehen, dass wir immer dann, wenn wir eine Speerwaffe haben, dass das Elternteil eine Waffenausstattung ist , die im gesamten Spiel einheitlich Ich denke also, dass das Setup in Ordnung ist. Also mache ich Var Underscore Loadout hier in unserem Weapons Two D-Skript Und das wird vom Typ Waffenausstattung sein. Also weiter bereit, wir werden die Ausrüstung besorgen wollen. Sagen wir also, ein Unterstrich ist gleichbedeutend mit Get Parent, und wir sollten sicherstellen, dass das Loadout und wir sollten sicherstellen, dass das Loadout Das übergeordnete Element einer Waffe sollte die Waffenausstattung sein . Okay, und es scheint, als hätte ich den Klassennamen festgelegt. Sind es Waffen mit S? Ja. Okay, das ist also Waffenausstattung hier, nicht Waffenausstattung. Okay, wir haben also einen Verweis auf das übergeordnete Loadout-Skript Dies schafft zwar eine Abhängigkeit, macht es aber auch einfach, auf Dinge zuzugreifen, die wir benötigen Falls wir also jemals entscheiden sollten, dass wir dieses Muster ändern wollen, erstelle ich hier unten eine Funktion für Get direction. Funktion Get direction wird also einen Vektor zwei zurückgeben. Und in diesem Fall werden wir das Loadout verwenden, um das zu bekommen Geben Sie also die Punkteingabe des Underscore-Loadouts zurück. Punktrichtung Und so lösen wir die Richtung auf, aber wir können einfach immer die G-Richtungsfunktion verwenden , um damit umzugehen. Wenn wir also anrufen, sagen wir, zehn verschiedenen Orten die Richtung ermitteln, aber wir ändern die Ausstattung Also verwenden wir eigentlich kein Loadout mehr oder vielleicht verwendet das Loadout keine Eingabe, dann müssen wir hier nur einmal reingehen und Also vielleicht hat das Loadout einen direkten Richtungsbezug, also ändern wir es einfach so und dann würde es wieder funktionieren Aber ich muss das tatsächlich ein bisschen ändern , weil wir die Richtung nicht verwenden Wir werden die Blickrichtung verwenden, denn denken Sie daran, dass Richtung die Roheingabe ist. Es kann ein Vektorpunkt Null sein, aber in dieser Art von Spiel werden wir niemals einen Speer auf die Füße des Charakters werfen dieser Art von Spiel werden wir niemals einen Speer auf die Füße des Charakters Also wollen wir hier mit dem Gesicht beginnen, und das nehmen wir in Import mit Punktverstellung Wir werden also wirklich die Richtung festlegen , in die der Charakter blickt, und stattdessen. Okay, also nehmen wir das Spiel mit dem Gesicht und wo wir casten, wir machen stattdessen einfach die Besetzung, um das Gesicht zu bekommen. Und wir bewegen unseren Charakter, wirst du schon sehen, wir können in die richtige Richtung casten, und das sollte auch Diagonalen beinhalten, so Okay, das ist also die Hälfte von dem, was wir genau hier tun müssen. Jetzt müssen wir auch alle Projektile, die wir einsetzen, rotieren lassen. Lassen Sie uns also diesen Drehwinkel ermitteln. also innerhalb von Cast, wo wir die Paktszene für das Projektil erstellen, Lassen Sie uns also innerhalb von Cast, wo wir die Paktszene für das Projektil erstellen, den VR-Rotationswinkel verwenden Und wir nehmen den Get Facing-Vektor. Wir werden das hier in einen Winkel umrechnen, und ich glaube, das ist Radiance Wenn ich mit der rechten Maustaste klicke und das Lou-Symbol auswähle, können wir sehen, dass der Vektorwinkel in Bezug auf die positive X-Achse im Bogenmaß zurückgegeben die positive X-Achse im Bogenmaß Das wäre also Zeug wie Pi geteilt durch zwei Dinge Okay, aber wir wollen es so drehen, dass der Speer oder andere Projektile standardmäßig als Basiswinkel nach rechts Wenn es also nach oben zeigt und das Sprite, wollen wir den Pi geteilt durch zwei oder um 90 Grad drehen zwei oder um 90 Grad , also fügen wir Hi hinzu , eine Konstante geteilt durch zwei, und das macht ihn so, dass er nach rechts Ohne es zuzuordnen, ist es hier eher eine Sache mit Versuch und Irrtum Aber lassen Sie uns diese Rotation machen. Also, nachdem wir das Projektil instanziert haben und gesagt haben, dass es sich um eine globale Position handelt, lassen wir den Projektilpunkt rotieren und diese Funktion benötigt Wir haben also unseren Drehwinkel. Wirklich, ich sollte das umbenennen, um es in wechselnde Anzeigen umzubenennen. Also werde ich das Control R doppelt sammeln, und wir sagen, rotiere die Werbung für mehr Strahlkraft, ersetze alle, und das sieht dort viel sauberer Also speichere und renne, und da haben wir unsere Speere die richtige Richtung zeigen Und das sollte auch mit praktisch jedem Projektil funktionieren mit praktisch jedem Projektil Solange diese Projektile standardmäßig nach oben zeigen, können Sie dieses Sprite in der Projektilszene einzeln drehen, können Sie dieses Sprite in der Projektilszene einzeln drehen bis es in die vorgesehene Richtung zeigt Da haben wir also unsere Ziele und Rotationen Und um noch etwas zu zeigen: Wenn ich die Richtung loslasse, dann ist unsere Richtung jetzt Vektor 20, aber wir schießen immer noch nach rechts, weil die Ausrichtung niemals auf Vektor zwei Punkt Null gesetzt wird Und aus diesem Grund verwenden wir die Ausrichtung anstelle der rohen Richtungseingabe. Okay, das ist ein großer Schritt, der genau da gemacht wurde. 19. Hinzufügen von Soundeffekten und Musik: Fügen wir unserem Spiel einige Soundeffekte hinzu. Zuerst werde ich mit einem Start-Soundeffekt beginnen, und wenn die Feinde dann ihren Todeszustand erreichen, haben wir vielleicht die Möglichkeit , sie auch dort einen Soundeffekt abspielen zu lassen. Ich würde mich wahrscheinlich von Treffergeräuschen fernhalten , weil mehrere Gegner getroffen werden jeder Sekunde mehrere Gegner getroffen werden, und das wäre, glaube ich, einfach zu viele Soundeffekte auf einmal. Du würdest deinen Spieler nicht zu sehr überwältigen wollen. Fangen wir also einfach mit diesen beiden an. Also für die Speerwaffe des Spielers, sagen wir in der Waffe zu D, fügen wir einen Soundplayer Also bei Export var Audioplayer vom Typ oder Audio-Stream-Player zwei D. Wir wollen, dass es zwei D weil diese Projektile innerhalb der TD-Spielwelt existieren , also ist es sinnvoll, den Ton auf der Grundlage der räumlichen Positionierung der Kamera und des Projektils und all dem zu beeinflussen auf der Grundlage der räumlichen Positionierung der Kamera und des Projektils und all dem Also nehmen wir den Audioplayer und müssen ihn hier drunter stellen Um also einen Audioplayer-Knoten hinzuzufügen, zoomen wir hier hinein und klicken mit der rechten Maustaste auf Speerwaffe und untergeordneten Knoten hinzufügen Wir wollen also den Stream Player Two D, fügen ihn da drunter Und wir wollen ein Stream-Audio zuweisen , das wir hier abspielen können. Lassen Sie uns also die Soundeffekte herausfinden. Ich werde alle Ordner zusammenklappen. Gehen wir zum Thema Audio über. Lass uns sehen. Was habe ich benutzt? Ich glaube, wir hatten Soundeffekte von Ball Okay, lass mich mein Headset hier aufsetzen , damit es nicht durch das Mikrofon kommt Okay, also in einem, ich glaube, es ging mit Schrägstrich 04, also konnten wir darauf doppelklicken, nach oben rechts gehen und eine Vorschau ansehen Ja, ich glaube, das habe ich in meinem Demo-Projekt verwendet. Nehmen wir also den Schrägstrich und fügen ihn hier in den Stream Jetzt können wir diesem Audio-Stream-Player einfach sagen immer dann abspielt , wenn wir ein Projektil abfeuern Gehen wir also zur Stream-Waffe über. Und wenn wir das Projektil abgeworfen haben, sagen wir, wenn der Audioplayer nicht Null ist, dann sagen wir ihm, dass er seinen aktuellen Audioclip abspielen soll Also hier unten, nachdem wir das Projektil instanziert haben, sagen wir: Ich höre den Audioplayer, dann sagen wir, dass der Audioplayer spielt, und das ist im Grunde alles, was wir tun müssen Der Grund dafür, dass wir diese Bedingung hier haben , ist, dass Sie bei einigen Waffen vielleicht nicht möchten, dass der Ton abgespielt wird, also werden wir diese Option hier einfach überspringen Nun, eine Sache, auf die ich hier hinweisen möchte , ist, dass wir diesem Waffenskript zusätzliche Verantwortung übertragen . Jetzt ist Waffe 2 D nicht nur dafür verantwortlich, die Projektile zu instanziieren, sondern auch dem Audioplayer mitzuteilen, dass er abspielen soll , wenn das Projektil instanziert wird eigene Referenz zur Waffenausstattung einstellt und einen Timer erstellt Es sind also ein paar Dinge im Gange, ich denke nicht, dass das überwältigend und ein Problem für das Spiel ist , aber es ist etwas , dessen aber es ist etwas Wenn du merkst, dass deine Skripte zu viel Verantwortung übernehmen, solltest du vielleicht erwägen, sie in mehrere Knoten mit unterschiedlichen Skripten aufzuteilen und sie als einzelne Teile zusammenarbeiten zu lassen , anstatt als ein riesiges Mega-Skript. Aber wir sind noch nicht da. Das Drehbuch ist nur 50 Zeilen lang. Es ist nicht wirklich ein Problem. Wenn Sie vielleicht zwei oder 300 Codezeilen hätten, würde ich denken, dass Sie wahrscheinlich an den Punkt kommen würden, an dem Sie einige Unterobjekte benötigen würden. Aber mach dir darüber nicht zu viele Gedanken. Die meisten Skripte in diesem Kurs sind ziemlich einfach. Ich möchte nur, dass ihr euch bewusst seid, dass ein Drehbuch in Zukunft zu monolithisch werden kann, was auf lange Sicht problematisch sein kann Wir haben eine Speerwaffe . Wir müssen den Audioplayer zuweisen, damit er tatsächlich Audio abspielen Also den Audiostream-Player zuweisen und dann den Audio-Stream-Player. Wenn wir jetzt spielen, sollten wir unsere Soundeffekte bekommen. Okay, ja, da haben wir's. Jedes Mal, wenn wir ein Projektil instanzieren Okay, jetzt wollen wir einen Soundeffekt abspielen wenn unsere Orks sterben Gehen wir also in die Orkszene. Ordnung, klicken Sie auf den Ork fügen Sie hier einen neuen AudioStream-Player Wenn wir wollen, könnte ich ihn in einen Death-Audioplayer umbenennen einen Death-Audioplayer Wir könnten sagen. Okay, jetzt würden wir also einen geeigneten Todes-Soundeffekt finden wollen. ein bisschen damit herumspiele, denke ich, dass Enemy Death 01 zu viel ist. Sogar Flash Oh Two ist auch ein bisschen viel. Die Sache ist, in dieser Art von Spiel werden Feinde wie Fliegen umfallen. Also brauchen wir etwas sehr Subtiles oder vielleicht sogar gar nichts. Ich glaube, ich suche eher nach etwas wie dem Step Grass 03. Nun, das mag ein bisschen komisch klingen, aber ich denke, alles , was länger ist , wird einfach zu viel sein, um zu sehen, wie es sich entwickelt, vielleicht wird es sogar ganz wegfallen. Lassen Sie uns also das Step-Gras oh drei dem Stream hier zuweisen und ihm sagen, dass er diesen Soundeffekt beim Tod abspielen soll, gehen wir zum Animations-Player. Unten links wählen wir die Todesanimation aus. Und wir fügen einen neuen Titel hinzu, fügen hier einen Titel hinzu, rufen die Methode im Death-Audioplayer auf und wir klicken mit der rechten Maustaste auf den Anfang dieser Animation, fügen die Taste ein und schon wollen wir abspielen. Es ist also so, als würden wir ein Skript schreiben, wenn wir diese Animations-Keyframes definieren, außer dass wir die Timeline haben, sodass wir genau sagen können sodass wir genau sagen können, wann die Animation abgespielt werden soll, und es ist sehr einfach , sie zu einem anderen Zeitpunkt zu verschieben , indem wir sie einfach auf einen anderen Keyframe ziehen. Sie könnten also all diesen GD-Skriptcode schreiben, wenn Sie möchten, und den Animations-Player einfach überspringen Aber offensichtlich macht es der Animation-Player irgendwie viel einfacher , es visuell zu machen. Okay, wenn wir jetzt spielen, sollten wir beide Soundeffekte abspielen lassen. Damit du hören kannst, wenn die Orks tauchen, spielt es diesen kleinen Soundeffekt Es ist ein bisschen leise, aber vielleicht ist das okay. Wenn wir der Meinung sind, dass die Speers im Vergleich zu laut sind, könnten wir sogar den Spears-Audio-Stream-Player nehmen und die Lautstärke hier um ein wenig senken Und drücke auf Play und starte es noch einmal. Du kannst das sogar bearbeiten , während das Spiel läuft. Also könnten wir das einfach fallen lassen . Okay. Du kannst sehen, dass es schon viel leiser ist. Meer, eines der schönen Dinge an Cado ist, dass du das Spiel nicht unbedingt beenden musst, um deine Eigenschaften zu ändern Und lasst uns einen Feind treffen. Okay. Und der Volumenunterschied zwischen diesen ist etwas weniger ausgeprägt. Also ist es jetzt wahrscheinlich gut. Als kleinen Bonus für dieses Video Wenn Sie Musik hinzufügen möchten, gehen wir in die Welt und lassen Sie uns einen Audio-Stream-Player hinzufügen, Audio-Stream-Player zwei D, nur die Standardnote Streamen Sie also den Player hier und wählen Sie dann diesen, den Audiostream-Player Okay, also gehen Sie mit unserem AudioStream-Player nach rechts und wir wollen, dass das auf Autoplay läuft wollen, dass das auf Autoplay Und ich denke, damit es in eine Endlosschleife kommt, müssen wir es zuerst von den Audio-MP Threes laden den Audio-MP Threes Lassen Sie uns also alles unten links wieder schließen, zu Audio gehen und wir haben den Box-Jump-Song aus dem Paket The Red Hearts Also bringen wir das nach oben rechts. Es ist eigentlich nicht P drei. Es ist ein Punkt-OGG, aber beide Musikformate werden in KDO unterstützt, also wird es gut funktionieren Und dann wollen wir das nehmen und Loop einschalten. Aber vielleicht müssen wir das tatsächlich unten links machen. Doppelklicken Sie also hier auf das OGG. Okay, und dann überprüfe Looping hier. Und wenn es zu Ende ist, sollte es das Ganze wiederholen. Okay, das ist also gut. Okay, als letztes, bevor wir das Spiel spielen, nehme ich die Lautstärke DB und stelle sie auf minus 20 weil ich denke, dass es sonst wahrscheinlich ziemlich laut sein wird . Also lass uns auf Play klicken und sehen, wie es läuft. Okay. Also können wir die Musik hören und sie ist immer noch ziemlich laut. Also werde ich das auf minus 30 bringen . Vielleicht sogar minus 40. Ja, das ist wahrscheinlich ein bisschen passender. Jetzt haben wir also das Audio. Wir haben die Musik und wir haben einen Enemy Death-Soundeffekt. Das sind quasi die Grundlagen für Audio-Soundeffekte und Musik im Spiel, und von dort aus können wir weitermachen. 20. Kampfsystem Singleton: Okay, der grundlegende Projektilschaden und der Kampf funktionieren im Moment, aber wir wissen nicht wirklich, wie viel Schaden den Feinden im Spielkontext zugefügt wird Eine Möglichkeit, wie wir das Gameplay auch visuell verbessern könnten , wäre schwebender Kampftext Wann immer einer dieser Charaktere Schaden an der Verletzungsbox erleidet, können wir zum Beispiel mit einem Kampfsystem kommunizieren, wobei der Kampftext jedes Mal, wenn er Schaden erlitten hat, an der Position schwebt, Kampftext jedes Mal, wenn er Schaden erlitten hat, an der Position schwebt wenn er Schaden erlitten hat, an der Position an der er Schaden erlitten hat. Das bedeutet also, dass viele Zahlen auf dem Bildschirm herumschweben werden , aber ich denke, das funktioniert ziemlich gut für den Spielstil. Es ist sehr aktionsorientiert und wir wollen sofortiges Feedback, und wir wollen sofortiges Feedback wenn wir Feinden Schaden zufügen. Und wir wollen auch sehen, welche Vorteile , wenn wir unsere Fähigkeiten verbessern, und dass unser Charakter stärker wird Um unser System zu erstellen, werden wir das als Singleton-Objekt verwenden wollen , was bedeutet, dass es im gesamten Spiel einen Verweis auf diese Klasse oder dieses System Und wenn wir es als automatisches Laden einstellen, wird es immer im Hintergrund sein und es wird leicht anhand seines Namens referenziert werden können Sie können das Singleton-Muster auch im Skript selbst implementieren , aber wir machen es auf die Gada-Art, die etwas einfacher und verständlicher ist Also hier oben werde ich einfach eine neue Szene erstellen. Wir werden es als anderen Knoten erstellen, und das wird ein Basisknoten sein. Wenn ihr hier zu zweit seid, könnt ihr ihn in Kampfsystem umbenennen. Dann klicken wir mit der rechten Maustaste darauf und hängen ein Skript an, Kampfsystem. Wir können das entweder im Stammverzeichnis speichern oder wir können einen Systemordner erstellen, um das zu speichern, was ich wahrscheinlich bevorzugen würde, und ich werde es dort erstellen. Jetzt wollen wir dieses Kampfsystem im Systemordner speichern . Also das Kampfsystem Dot TSC speichert das. Und jetzt machen wir es zu einem automatischen Laden, sodass dieses Node-Skript in unserem Spiel einfach anhand des Namens referenziert werden kann in unserem Spiel einfach anhand des Namens referenziert Also gehe ich zu den Projekteinstellungen. Dann haben wir hier Globals. Und wir wollen ein neues TSCN als globales hinzufügen. Also klicken Sie hier, gehen Sie zu Systems und machen Sie dann TSCN. Ihr könnt auch sehen , dass ihr ein Punkt-GD-Skript als Kampfsystem auswählen könnt ein Punkt-GD-Skript als Kampfsystem Dadurch wird eine neue Instanz des Node-Skripts in eurem Spiel erstellt des Node-Skripts in , sobald das Spiel startet Wenn du jedoch den Punkt TSCN verwendest, hast du den Vorteil Exportvariablen verwenden zu können da es sich um eine sehr spezifische Kopie des Kampfsystems handelt Kopie des Kampfsystems Wenn ich das hier doppelklicke und das als Knotennamen für das Kampfsystem hinzufüge, dann haben wir dieses Kampfsystem jetzt als globales Singleton und Teil unseres Spiels Und der Unterschied zwischen dem automatischen Laden eines Punkt-GD-Skripts und dem direkten automatischen Laden des SEN besteht darin, dass wir das hier einstellen können, wenn wir so etwas wie Export var spawn count, integer equal to Ten machen Export var spawn count, , dann können wir das hier einstellen, oder ? Wenn Sie jedoch ein Skript instanziieren, das noch nicht als Szene oder Knoten definiert wurde, dann hätten Sie keine Möglichkeit , solche Eigenschaften im Voraus anzupassen Ich bin mir sicher, dass es Möglichkeiten gibt, das zu umgehen, aber das ist ein Vorteil der Verwendung von Punkt-TSE Okay, wir haben also unser Kampfsystem. Wir werden eine Art Schadensmeldefunktion benötigen. Also werde ich das einfach irgendwie ausarbeiten. Hier. Sagen wir Funktion. Sagen wir, Treffer melden. Ich denke, das macht Sinn. Nehmen wir an, wir haben ein Ziel, das getroffen wurde, und wir können sagen, dass keine zwei D einfach alles im Spiel sein können, das getroffen werden konnte. Im Allgemeinen wäre das wie ein Charakterkörper oder ein statischer Körper. Aber aus Gründen der Flexibilität verwenden wir nur die Basisklasse. Und dann haben wir hier die Höhe des Schadens. Der P-Schaden ist also eine Ganzzahl. Dies wird als ungültig zurückgegeben. Und dann werden wir in diesem Kampfsystem unsere Szene für den schwebenden Kampftext instanzieren. Gehen wir also hier nach oben und wir können bei Export var schwebende Kampftextszene sagen . Und das wird eine Szene voller Typen sein. Und hier unten bei Report Hit für den Moment machen wir es einfach. Oder wenn du willst, kannst du sogar einen Push-Fehler machen und sagen, nicht implementiert. Das würde dir ein bisschen mehr Feedback geben, falls du jemals vergisst, ein Skript zu implementieren , anstatt dass es nur die Funktion ausführt und sie sodass es keinen Fehler gibt, aber es würde auch nichts bewirken. Ich denke also, dass das während der Entwicklung tatsächlich etwas besser ist. Lassen Sie uns nun zu unserem HRT Box Two D-Skript übergehen. Also Control P, HRT Box zwei D. Und dann können wir hier drinnen auf das Kampfsystem verweisen. Okay, also das Kampfsystem meldet einen Treffer und wir wollen das Objekt , das der Statistikcontroller verwaltet. Also ich glaube nicht, dass der Stat-Controller noch einen Bezug darauf hat. Wenn wir uns die Orkszene ganz schnell ansehen, klicken wir auf den Stat Controller Wir können sehen, dass es hier auf der rechten Seite nichts gibt, was einen Hinweis auf den Oc geben Wir könnten das einfach zu einer Art von Get Parent-Referenz machen oder wir können es zu einer Exportvariablen machen. Wenn du sichergehen willst, dass die Verbindung absoluter ist, die Verbindung absoluter ist, dann würde ich beim Export wählen. Denn das würde bedeuten , dass Get parent den Orc nicht mehr zurückgibt, wenn Sie aus irgendeinem Grund den Stat-Controller eine Ebene nach unten verschieben , zum Beispiel wenn Sie ihn einer anderen überordnen Wenn wir also beim Export verwenden, können wir sicherstellen, dass es das c zurückgibt. Wir könnten etwas sagen wie Körper oder Charakter, vielleicht sogar Objekt, um es allgemeiner zu halten Und dann kann das einfach das Objekt sein , für das dieser Controller Statistiken verwaltet, und ich weise es hier oben rechts dem Ork zu. Wenn wir jetzt zur Hurt-Box zurückkehren, können wir hier das Punktobjekt des Statistik-Controllers verwenden und dann den Schaden P Schaden weitergeben Okay, das gibt dem Kampfsystem alles, was wir darüber wissen müssen wo der Text positioniert und wie viel Schaden dem Text zugewiesen werden soll. 21. Animieren von schwimmendem Kampftext: Jetzt brauchen wir den schwebenden Kampftext selbst. Also lasst uns hier eine neue Szene erstellen. Klicken Sie auf Plus und öffnen Sie die Benutzeroberfläche. Und wir werden dafür sorgen, dass der Basisknoten wie schwebender Kampftext aussieht. Aber den eigentlichen Text werden wir als untergeordnetes Label zuweisen. Und das hilft uns, wenn wir den Animations-Player zum Animieren verwenden , weil wir die Wurzelposition nicht ändern wollen Wir wollen nur die Position des Textes relativ zum Stamm des schwebenden Combat-Textsteuerelements ändern relativ zum Stamm des schwebenden Combat-Textsteuerelements Klicken Sie also mit der rechten Maustaste hier, fügen Sie einen untergeordneten Knoten hinzu und suchen Sie nach einer Bezeichnung. Und dann klicken wir mit der rechten Maustaste auf den schwebenden Combat Text Adhild Animation Player Okay, ich denke, das brauchen wir hier, also kontrollieren wir S. Und wir können das speichern. Vielleicht erstellen wir einen Ordner für UI. Das ist immer noch eine Art Benutzeroberfläche. Lassen Sie uns also einen neuen Ordner erstellen. Ich gebe UI ein. Okay. Und dann schwebender Kampftext Punkt TSC und du kannst direkt da rein gehen Dann geh auf Nummer sicher. Okay. Und jetzt brauchen wir hier ein Skript, das an unseren Root angehängt ist. Ich klicke mit der rechten Maustaste auf den schwebenden Kampftext, hänge ein Skript an und wir erstellen es im UI-Ordner, schwebender Kampftext Punkt gD. Wir benötigen einen Verweis auf das Label, damit wir es hier manipulieren können. Also kontrolliere var label label. Also werden wir das Label hier zuweisen. Und wir wollen eine Art initialisierte Funktion erstellen. Wenn Sie Gado benutzt haben, wissen Sie wahrscheinlich, dass es hier eine Funktion Underscore und Knit gibt es hier eine Funktion Underscore und Diese Funktion wird verwendet , wenn ein Knoten in der Szene erstellt wird In diesem Fall müssen wir jedoch warten, bis das Objekt tatsächlich bereits erstellt wurde. Deshalb müssen wir erstellen. Wenn Sie Gadot also eine Weile benutzt haben, wissen Sie vielleicht, dass es eine Funktion namens Underscore und eine IT-Funktion gibt eine Funktion namens Underscore und eine IT-Funktion Das ist also eine überschreibbare Funktion, mit der Code ausgeführt werden kann , bevor alle Eigenschaften festgelegt wurden Sie könnten sie verwenden, um optionale Parameter zur Einstellung dieser Eigenschaften zu übergeben , wenn Sie einen Knoten aus einem Funktionsaufruf erstellen anstatt innerhalb einer gepackten Szene wie hier zu existieren , was Sie normalerweise tun, Sie würden einfach die Szene einrichten und dann die Szene aus einer Szene mit hohem Tempo instanzieren Also das ist eigentlich nicht das , was wir tun wollen. Wir versuchen nicht, die initialisierte Funktion anzupassen. Wir versuchen, den schwebenden Kampftext laufen zu lassen , wenn er schon in der Szene ist Also wollte ich da nur diesen Unterschied machen. Okay, was wir in dem schwebenden Kampftextskript tun wollen dem schwebenden Kampftextskript ist die Möglichkeit zu haben, den Text auf dem Label festzulegen, und das machen wir einfach direkt mit einer Art Delegiertenfunktion hier mit Funktionssatztext Also setzen wir den Text auf das Label, machen das aber über den schwebenden Kampftext des Wurzelknotens Geben Sie also Text ein und sagen P-Text, was eine Zeichenfolge ist. Wir geben void zurück und nehmen den Text mit dem Label-Punkt und setzen ihn auf P-Text. Ein Grund, das zu tun, ist unser Okay, also werden wir das natürlich immer dann setzen wollen, wenn wir die schwebende Kampftextszene instanzieren. Sie können hier also einen Klassennamen angeben , damit wir diese festgelegte Textmethode problemlos abrufen können. Also Klassenname, schwebender Kampftext, wir drücken dort auf Steuerung. Und jetzt wollen wir in unserem Kampfsystem, wann immer wir einen Treffer melden, wann immer wir einen Treffer melden, unsere schwebende Kampftextszene instanzieren. Nehmen wir an, der Vara-Text ist vom Typ schwebender Kampftext. Und das erreichen wir, indem wir die schwebende Kampftextszene instanzieren die schwebende Kampftextszene Also eingeben und dann instanziieren. Okay. Und das wollen wir als Kind hinzufügen. Und jetzt wollen wir den Text nicht wirklich als untergeordnetes Element des P-Ziels hinzufügen , denn wenn das P-Ziel aus der Szene gelöscht wird, wie die Todesanimation abgespielt wird, würden auch seine untergeordneten Knoten entfernt wie der schwebende Kampftext. Da wir also dieses globale System haben, das Kampfsystem, um den Text zu verarbeiten, denke ich, dass wir vielleicht damit durchkommen könnten, einfach Kind hinzufügen auf dem System selbst auszuführen und dann den Textknoten hinzuzufügen. Jetzt müssen wir die globale Position auf die Position des P-Ziels setzen . Der Text Globale Position entspricht also der globalen Position des p-Zielpunkts Und wenn dieser Teil nicht funktioniert oder wir auf andere Probleme stoßen, erhalten wir vielleicht einen Verweis auf eine Leinwandebene, die eigentliche Benutzeroberfläche und die Position dort unter einem übergeordneten Objekt, ähnlich wie die eigentliche Benutzeroberfläche und die Position dort unter einem übergeordneten wir es mit einem Projektil gemacht haben, also brauchen wir nur ein übergeordnetes Element , das den gesamten Text Aber die Position sollte dort sein, wo der Feind Schaden genommen hat, ist die Idee hier. Jetzt wollen wir den Text nehmen und seinen Text festlegen. Setzen Sie den Text also auf eine Zeichenfolge mit P-Schaden. Der P-Schaden ist also eine Ganzzahl. Wir konvertieren es in eine Zeichenfolge, indem wir STR sagen und dann den P-Schaden in die Klammern Und dann setzen wir den Text auf diesen Zeichenkettenwert. Wenn wir hier also die schwebende Textszene für das Kampfsystem einrichten, also schaue ich mir jetzt die Singleton-Szene an , das Kampfsystem, können wir hier rüber gehen und unseren schwebenden Kampftext schnell laden Wir haben also den Verweis auf die gepackte Szene hier auf der rechten Seite, also sollte sie instanziiert werden Lass uns auf Play klicken und es versuchen Okay, wir werden also dafür sorgen, dass der Schaden angerichtet wird. Okay, ja, das erwarten wir gewissermaßen. Und sehen Sie, sehr wichtig wenn der Orch aus der Szene entfernt wird, entfernt sich der Text nicht von selbst Okay, jetzt kümmern wir uns nur noch um die Animation für den schwebenden Kampftext Also haben wir das im Animations-Player gemacht. Erstellen Sie unten eine neue Animation . Neu. Und lass uns sehen. Wir können es nennen, wie wir wollen. Ich nehme Float Up und dann müssen wir einige Eigenschaften zur Animation hinzufügen Fügen Sie also die Spurbezeichnung der Spureigenschaft hinzu, insbesondere die Bezeichnung, weil wir diese Offset-Position wollen Lassen Sie uns hier also nach der Position suchen. Okay. Nun, wir können nichts sehen weil es keinen Standardtext auf dem Etikett gibt, also klicke ich auf das Etikett und sage hier einfach DEF als Standard. Möglicherweise möchten wir einem Thema auch eine neue Standardschrift zuweisen , die etwas besser zu unserem Pixar-Spiel passt Das können wir also tun, indem wir auf den schwebenden Combat-Text klicken. Gehe zum Thema auf der rechten Seite. Erstelle ein neues Theme, erweitere das, wähle eine Standardschrift aus und ich wähle das aus, was wir zu Beginn des Projekts bereits installiert haben, fünf x sieben, was du siehst, eine nette Pixar-Schrift ist Also und dann, ob wir dieses Thema wiederverwenden wollen, was wir wahrscheinlich tun Ich klicke mit der rechten Maustaste und speichere das im Projekt, und die Benutzeroberfläche klingt gut. Also sagen wir einfach Spielthema. Punkt TRS vorerst. Okay, wenn wir das schließen, können Sie sehen, dass es jetzt durch den Dateinamen referenziert wird. Okay, jetzt ein paar Dinge. Auf dem Wurzelknoten, dem schwebenden Kampftext, können wir sehen, dass er im Grunde diese riesige Box hat. Wir brauchen es eigentlich nicht, dass es so groß ist. Gehen Sie also zum Layout. Und dann ändern wir das anstelle von Anchors Preset Full Rect auf Reset Jetzt ist das Steuerelement nur noch ein kleiner Punkt hier oben, und das Etikett hat seine eigene Größe als Kind Dann noch etwas zum schwebenden Kampftext. Ich möchte die Maus nehmen und den Filter so ändern , dass er ignoriert wird, nur damit Mausklicks weiterhin auf dem Bildschirm angezeigt werden, auch wenn sie diesen schwebenden Kampftext berühren. Ich möchte, dass Mausklicks ignoriert werden. Wenn also eine Benutzeroberfläche auf dem Bildschirm angezeigt wird, wird das Drücken der UI-Taste nicht beeinträchtigt. Das ist ziemlich wichtig. Und jetzt kehren wir zu unserem Animations-Player zurück und geben der Position Keyframes Also werde ich unten hineinzoomen. Klicken wir mit der rechten Maustaste auf die Position als Keyframe und verschieben wir sie an die gewünschte Startposition Die 00 ist also der Punkt, an dem unser Feind Schaden erlitten hat. Ich glaube, ich möchte nur sichergehen , dass es irgendwo darüber anfängt. Also gehe ich nach w, um den Text zu verschieben. Ich verschiebe ihn hierher und dann geben wir der Position hier einen Keyframe Gehen Sie also zum Layout auf der rechten Seite und dann zur Transformation und Keyframe-Erstellung der Position Ich habe es also bei negativen 15 Pixeln auf dem Y. Und dann können wir uns überlegen, wie lange das dauern soll Vielleicht eine halbe Sekunde. Sie können auch Snapping aktivieren, wenn das hilft Okay, also 0,5 Sekunden. Und dann lass es uns hierher verschieben. Also irgendwie so und dann wieder Keyframes auf der rechten Seite, einfach mit der Keyframe-Taste Okay, und jetzt wird es zwischen diesen beiden Punkten animiert Wenn ich also zum Start gehe und spiele, kannst du sehen, dass es diese Positionsbewegung animieren wird Wir können die gesamte Dauer auch auf 0,5 Sekunden ändern. Und wenn wir wollen, könnten wir es am Ende einfach klären , indem wir die add track call method track im schwebenden Kampftext-Root ausführen . Und dann klicken Sie hier mit der rechten Maustaste, fügen Sie Quarre ein und geben Okay, das stellt sicher, dass der Text von selbst bereinigt, nachdem er in dieser Szene fertig ist, ohne dass Sie noch etwas anderes programmieren müssen Wir können es einfach von der Animation aus aufrufen. Nun, das würde wahrscheinlich funktionieren, genau, genau jetzt, aber es ist wirklich einfach. Lass es uns testen. Stellen Sie einfach sicher, dass es funktioniert. Okay, ja, ich habe die Animation nicht abgespielt. Das liegt also daran, dass ich Autoplay hier nicht eingestellt habe. Also unten rechts im Animation-Player Autoplay beim Laden Okay, jetzt drücken wir erneut auf Play und wir bekommen unsere Animation Okay, das funktioniert also auf einer sehr einfachen Ebene. Es ist überhaupt nicht schlecht. Aber wenn wir schon hier sind, warum machen wir es nicht interessanter? Ich kann also eine Spur zur Eigenschaftenspur des Labels hinzufügen, und wir werden, sagen wir, skalieren. Okay, so können wir es Laufe der Zeit vergrößern oder verkleinern Lassen Sie es uns also so gestalten, wie es zum Zeitpunkt 00 ist. Sagen wir etwa 0,15 Sekunden oder ich schätze, ich gehe auf 0,16 67 Es ist hier nicht wirklich wichtig. Und Sie können Ihr Snapping übrigens unten rechts ändern, übrigens unten rechts ändern, wenn Sie ein besser anpassbares Keyframe-Snapping haben möchten ein besser anpassbares Keyframe-Snapping Gehen wir also zu Label und transformieren dann die Skalierung. Wir nehmen seine Größe und vergrößern es. Also vielleicht 1,5 oder vielleicht sogar zwei. Wir können damit beginnen und es bei Bedarf herunterskalieren. Also werde ich das mit einem Keyframe versehen. Also jetzt wird es von der Größe 1,0 auf 2,0 steigen. Und wenn es dann ausgeblendet wird, wollen wir, dass es wirklich klein Also nehmen wir es auf, sagen wir, eine Größe von 0,1 und geben dann einen Keyframe Okay. Wenn wir jetzt unsere Animation abspielen, ist es ungefähr so. Vielleicht ist die Skala bei diesem zweiten Keyframe etwas zu groß, also nehme ich sie einfach auf , sagen wir 1,5 Ich denke, das ist richtig. Drücke auf Play. Okay, das funktioniert ziemlich gut. Und wir können die Position auch nehmen und sie vielleicht nach rechts verschieben, wenn sie diesen Spitzengrößenpunkt erreicht. Nehmen wir also die Position hier mit dem W-Bewegungsmodus und verschieben sie nach rechts oder so , um sie dann mit einem Keyframe zu versehen. Okay, und jetzt spielen wir wieder. Jetzt können wir also sehen, wie Text nach rechts und dann wieder nach oben links zurückkehrt Eine andere Sache, die wir tun könnten, wäre, die Farbe oder das Alpha im Laufe der Zeit zu ändern Fügen wir also eine Spur zur Eigenschaftsspur des Labels hinzu, und wir sorgen dafür, dass sich diese selbst moduliert Es wirkt sich also nur auf dieses Label aus, nicht auf untergeordnete Knoten Also moduliere ich das Etikett selbst. Klicken wir zu Beginn mit der rechten Maustaste auf Schlüssel einfügen . Das wird also unser Standardweiß mit vollem Alpha-Wert sein. Gehen wir zu 0.15 oder wo auch immer unsere Keyframes einrasten und fügen einen Schlüssel ein 0,0 1667 für mich. Und dann lass uns die Farbe auf Rot oder so ändern , weil das für beschädigten Text ist Und dann lass uns hier bis zum Ende gehen. Klicken Sie mit der rechten Maustaste auf Schlüssel einfügen, und wir ändern ihn, sagen wir, auf Null Alpha. Kann es spielen. Also jetzt ist es irgendwie so. Ich denke, es könnte sinnvoller sein, wenn wir den ersten Keyframe und diesen austauschen Also werde ich das auf die Timeline ziehen. Ich ziehe die linke Seite bis zum Punkt 0,0 1667. Das geht hier drüben hin. Jetzt fängt es bei Rot an und wird weiß. Und wir könnten es auch mit einer weißen Farbe enden lassen. Also klicke ich hier, gehe zu dem Wert und ändere ihn auf 255 für Grün und Blau. Es endet also weiß, obwohl es vollständig transparent ist. Wenn ich hier ein paar Mal spiele, fühlt es sich sehr gravierend an. Ich meine, das liegt wirklich daran, dass wir im Laufe der Zeit einfach von einer Farbe zu einer anderen Farbe Der Farbverlauf wäre also so von links nach rechts. Es geht sozusagen von Rot zu Weiß über, wenn es sich über den Bildschirm bewegt, außer dass wir es jetzt im Laufe der Zeit tun Es liegt also ganz bei dir, wie es dir hier gefällt. Du könntest das auch so ändern, dass es rot ist. Es ist also die ganze Zeit nur rot. Das einzige, was sich ändert, ist die Transparenz. Dann müssten Sie auch den dritten Key-Frame-Punkt festlegen , quasi so. Vielleicht würden wir stattdessen wollen, dass es mit der Zeit dunkler wird, also könnten wir die Werte hier nehmen und es wie ein dunkles Rot machen und schauen, wie sich das entwickelt. Ja, das sieht ziemlich gut aus, denke ich. Vielleicht ist das Rot ein bisschen zu lebendig, also nehme ich vielleicht das erste und mache es so. Und vielleicht kann es auf dem Gipfel etwas heller sein. Lass es uns versuchen, okay, dunkler bis hell und dann wieder dunkel. Also, das scheint ziemlich gut zu funktionieren. Ich mag es irgendwie. Das ist rein eine künstlerische Sache mit persönlichen Vorlieben. Also wirklich, was auch immer du willst, mach das. Okay, also lasst es uns spielen und testen, und wir werden unsere Schadensnachricht haben sobald wir die Feinde getroffen haben. Und für mich sieht es so aus, als würde es sich einfach viel zu schnell bewegen. Also müssen wir vielleicht die Dauer dieser Animation verdoppeln . Wenn wir also auf den Animation-Player klicken, können wir diese Keyframes einfach verschieben, und das ist einer der großen Vorteile einen Keyframe-Animationseditor zu verwenden, anstatt ihn, Sie wissen schon, fest zu codieren Es ist einfach einfacher , ihn zu iterieren und kleine Änderungen vorzunehmen, um ihn an die gewünschte Position anzupassen Nehmen wir also diese Keyframes für Kframe. Setze das hier am Ende auf 1,0. Das sollte auch auf 1.0 gehen. Und Sie können ein Feld über mehrere Keyframes ziehen und sie alle auf einmal so verschieben Ich kann also ein Feld hierher ziehen und das verschieben, wir könnten versuchen, 0,5 Sekunden, was auch immer. Okay. Also, das ist ziemlich langsam da. Also vielleicht wollen wir, dass das eher Frontloader ist. Bringen wir das da rüber. Drücke auf Play. Okay. Ich meine, ich bin mir nicht sicher. Wir müssen es versuchen und sehen, wie es auf dem Bildschirm tatsächlich aussieht. Es scheint, als ob das Ausblenden etwas zu lange dauert. Also vielleicht gehört das eher dorthin. Etwas weiter. Und vielleicht sind 1,0 Sekunden zu lang. Ich ziehe es einfach dahin. Also egal, welcher Keyframe-Punkt 0,8 Sekunden ist, das ist die Dauer des Clips Vielleicht ist der Text auch zu klein. Ich denke, eine Möglichkeit, uns ein Bild zu machen, besteht darin, eine Kopie auf die Weltbühne zu bringen , damit wir sie hier so sehen können, wie sie ist. Okay, da ist also unser Daf-Text. Ich denke, wir können tatsächlich hier klicken und editierbare Kinder erstellen, und dann können wir auf den Animations-Player klicken und ihn einfach testen und hier sehen Wenn wir zu Float Up wechseln, funktioniert das? Ja, tut es irgendwie. Okay. Ja, das hilft sehr. So kannst du wirklich sehen, wie es im eigentlichen Gameplay aussehen wird , weil wir hier die Mock-up-Szene haben. Okay, vielleicht nehmen wir die Position hier ein, und ich werde das ein bisschen nach unten verschieben . Und es sieht so aus, als könnten wir hier auch Keyframes erstellen, das ist also gut Also bekommt das tatsächlich 28 minus 31? Lassen wir es etwas schneller ausblenden. Also habe ich es noch nie speziell auf diese Weise versucht. Es scheint, als ob Sie Keyframes auf dem Etikett erstellen können, aber Sie können den Animation-Player nicht direkt anpassen den Animation-Player nicht direkt wenn Sie von dieser anderen Szene aus bearbeiten Hier gibt es also einen kleinen Kompromiss. Ich könnte die Selbstmodulation beim ersten Frame ändern. Und gebe dort Keyframes ein. Okay, das funktioniert also Das aktualisiert den Animations-Player. Und dann kann ich in die schwebende Kampftextszene springen. Und ich möchte die modulierte Farbe nehmen und sie einfach viel weiter nach links verschieben Es wird also schneller rot, aber ich mochte es nicht wirklich, als es die ganze Zeit rot war Okay, und dann gehe ich hierher und füge ein weiteres Schlüsselbild hinzu. Und dabei werde ich für volle Transparenz sorgen. So wird es länger auf dem Bildschirm sichtbar sein. Es wird erst gegen Ende der vollständigen Animation ausgeblendet . Lass uns spielen und ich werde es noch einmal versuchen. Vielleicht möchte ich hier auch, dass die Farbe weiß ist. Also werde ich das tun. Also blitzen Sie einfach rot auf. Eine letzte Sache unten rechts Wenn Sie hier den Interpolationsmodus verwenden, können Sie ihn auf kubisch ändern Und das mache ich für die Position, die Skala und die selbstmodulierenden Eigenschaften Wenn Sie hier also ganz genau hinschauen, ergibt sich dafür eine kleine Kurve auf der linken und rechten Seite Wenn das also wie andere Timeline-Editoren funktioniert, was meiner Meinung nach der Fall ist, dann bedeutet das, dass es hier eher eine Kurve zum Ein- und Auslassen sein wird als ein linearer Übergang für die Animation. Lassen Sie uns das hier testen und sehen, ob das der Fall ist. Das würde ich von anderen Dingen wie dem DaventirSolt-Videoeditor erwarten anderen Dingen wie dem DaventirSolt-Videoeditor Und diese Lockerung scheint es hier zu geben . Also werde ich es ganz schnell wieder ändern, nur um es zu vergleichen. Wir nehmen das linear. Ja, jetzt ist die Geschwindigkeit einfach konstant. Also habe ich meine Annahme geschrieben. Das kann uns der Animation etwas mehr Schwung verleihen , weil sie jetzt ihre langsamen Momente und ihre schnellen Bewegungen hat ihre langsamen Momente und ihre schnellen Bewegungen Wenn wir auf Play klicken, werden wir das hier noch einmal testen, und ich denke, das funktioniert momentan richtig Also drücke ich auf Play. Wir werden es testen. Ich habe das Gefühl, dass die Animation hier etwas lang ist. Es muss nur diesen Moment geben, in dem wir es deutlich lesen können Okay, also noch einmal, ich werde die Animation hier ein wenig kürzen Ich ziehe dort alle Keyframes auf 0,7. Die Animation endet bei 0,7. Lass uns noch einmal spielen und es testen. Ich denke, ich werde es danach einfach beenden. Okay, das Verblassen ist jetzt sehr schnell. Okay, und für die Position, an der es ausgeblendet wird, möchte ich das auch verschieben Also lass mich das hier rüberziehen, damit ich es sehen kann. Klick auf das Etikett, Schwein ist vielleicht da. Ich mache einen Keyframe für die Position und ziehe diesen Punkt dann zurück nach rechts Ich denke, dadurch wird die Animation nur etwas subtiler Okay. Ja, jetzt, wo es ausgeblendet wird, bewegt es sich nicht mehr ganz so weit Und ich finde, das ist etwas sanfter anzusehen. Also könnten wir noch lange so weitermachen. Ich denke, du verstehst die Idee. Passen Sie die Animation einfach so an, dass sie sich Ihrer Meinung nach in Bezug auf Farbe, Maßstab, Transparenz, Positionierung usw. gut anfühlt . Die wichtigsten Dinge für dieses Tutorial sind jedoch, was den Code angeht, nur sicherzustellen, dass Sie über das Kampfsystem verfügen . Es wird automatisch geladen. Sie sagen ihm, dass er den Schaden melden soll, und bei diesem Schadensbericht Sie den Kampftext und fügen ihn nicht als untergeordnetes Element des Zielknotens hinzu , der den Schaden erlitten hat, sondern als irgendein Systemknoten oder einfach als persistenter Knoten, der sich niemals selbst entfernen wird. Und Sie entfernen den schwebenden Kampftext in der Animation, indem Sie Q free aufrufen. Und das ist im Grunde der Kern alles andere sind eher künstlerische Details 22. P21 Feindbewegung mit Spielerverfolgung in Godot 4: Projektile haben bereits die Fähigkeit , einem Feind Schaden zuzufügen und ihn zu töten, aber unsere Feinde laufen nicht wirklich auf Damit sich Orks also auf den Spieler zubewegen können, benötigen sie zunächst einen Hinweis auf den Es wäre etwas schwierig, zunächst einen direkten Bezug zwischen dem Ork und dem Spieler zu haben einen direkten Bezug zwischen dem Ork und dem Spieler , da sie Beginn des Spiels nicht in derselben Szene existieren Wenn wir Feinde in die Spielwelt spawnen, kommen sie aus der überfüllten Szene Sie existieren hier also erst, wenn sie vom Spawnsystem tatsächlich in die Szene gesetzt werden. Was wir stattdessen tun könnten, ist eine Referenzressource zu haben, wir könnten sie Spielerkontext nennen, wo sich der Spieler selbst auf die Ressource festlegt, und dann wird jeder Ork auf diese Ressource verweisen, um das Spielerziel zu sobald er in der Spielwelt erscheint Das hätte einige zusätzliche Vorteile da wir, sagen wir, das Spielerziel gegen alle Gegner austauschen sagen wir, das Spielerziel gegen alle könnten, indem wir die Ressource einmal austauschen Wir könnten sogar das Kampfsystem als Referenz verwenden, sobald eine Kopie des Orks in der Spielszene Das Spawnsystem könnte also im Grunde entscheiden , auf welchen Spieler jeder Ork abzielt, und das kann einige zusätzliche Vorteile haben, als es nur aus einer einzigen Zehnerreferenz zu machen, was Sie in diesem Fall sicherlich für den Spieler tun könnten in diesem Fall Aber das würde dich auch strikt an ein Einzelspieler-Spiel binden , was für diesen Kurs in Ordnung ist Aber ich werde versuchen zu zeigen, wie Sie das mit der Ressourcenmethode erreichen können . Also unten links in unserem Dateisystem wird alles zusammenbrechen. Gehen wir nun zu den Charakteren über, und ich werde hier mit der rechten Maustaste klicken und ein neues Skript erstellen. Nennen wir das Spielerkontext. Und was Erbschaften angeht, machen wir es zur Ressource. Okay, erstelle das neue Skript und stelle sicher, dass du es im Skript-Editor öffnest, um dem Klassennamen den Spielerkontext zu geben Klassennamen den Spielerkontext Okay, das ist einfach so eingerichtet, dass es im Grunde ein gemeinsamer Verweis auf einen bestimmten Spieler im Spiel ist. Also, was wir hier brauchen, ist ein Var Player. Und wenn wir eine Spielerklasse haben, werden wir dafür sorgen, dass sie diese erweitert. Var Player ist also vom Typ Player, und das könnte eigentlich alles sein, was wir hier wirklich brauchen. Für diese Ressource. Gehen wir jetzt zum Player-Skript, und innerhalb des Players werde ich einen Verweis auf den Kontext exportieren. Lassen Sie uns also einen Export var-Kontext erstellen, und ich nenne ihn vom Typ Spielerkontext, Steuerelemente zum Speichern. Und wir können im Moment sehen dass wir einen Platz für Ressourcen haben. Lassen Sie uns also unsere neue Ressource erstellen. Und dann möchte ich mit der rechten Maustaste darauf klicken und es im Projekt speichern. Wir speichern es in, sagen wir, Zeichen. Wir könnten es in den Player integrieren, wenn wir wollen, also warum nicht? Und dann nenne ich es Spielerkontext hier Punkt TRS, was für Ressourcen steht. Vielleicht möchtest du auch den Spielerkontext bei GD in das Spielerverzeichnis von Character Slash verschieben GD in das Spielerverzeichnis von Character Slash Okay. Und jetzt brauchen unsere Orks ein Ziel Also können wir zum Ork-NPC gehen. Du kannst bei Bedarf hier drüben klicken. Wir sagen bei Export var target ist ein Typ Spielerkontext. Bei Bedarf könntest du es auch wie einen Zielkontext machen, wenn du dafür nur einen Schritt generischer vorgehen musst , aber sie werden immer nur ein Ziel haben. Ich denke also, es könnte für unseren speziellen Fall etwas besser sein, es spezifischer zu machen, indem wir es Spielerkontext nennen könnte für unseren speziellen Fall etwas besser sein, es spezifischer zu machen, indem wir es Spielerkontext . Aber du kannst es gerne zu einem Zielkontext machen , wenn du möchtest, dass Feinde hinter leblosen Objekten oder NPCs oder ähnlichem Und das wird den Hinweis auf das Spielerziel enthalten, das dieser NPC Stellen wir es also einfach direkt im Inspektor ein. Also klicken Sie auf OC und dann auf der rechten Seite, wir müssen ihm den Spielerkontext geben. Also klicke ich hier. Schnelles Laden, Spielerkontext. Und ihr werdet feststellen , dass der Ork und der Spieler zwar der Ork und der Spieler zwei völlig unterschiedliche Szenen sind, wir sie aber auf dieselbe Ressource und unser Projekt verweisen lassen können Ressource und unser Projekt Die Ressource ist im Dateisystem vorhanden, sodass wir sie innerhalb unserer einzelnen gepackten Szenen referenzieren können unserer einzelnen gepackten Szenen Wenn sie also tatsächlich derselben Spielwelt-Szene hinzugefügt werden , haben sie beide dieselbe Referenz. Der Spieler wird sich also selbst als Spieler auf den Spielerkontext festlegen selbst als Spieler auf den Spielerkontext und dann alles andere, die NPCs werden daraus lesen Und so werden sie über diesen Kontextvermittler miteinander umgehen über diesen Kontextvermittler miteinander Das NPC-Skript wird hier also nichts direkt bewirken Das werden wir im Chase State einrichten lassen. Aber das Letzte, was wir tun müssen, bevor wir zum Chase-Status gelangen , ist , zur Spieler-Szene zurückzukehren und das Innere von Player on Ready zu betrachten. Zunächst wollen wir sicherstellen, dass der Kontext nicht null ist, weil er für unser Spiel irgendwie benötigt wird. Bestätigen Sie also den Kontext, sodass die Kontextressource hier gesetzt werden muss, damit der Spieler sich selbst zum Spieler des Kontextes machen kann . Und dann nehmen wir den Kontext-Punkt, der Spieler ist gleich sich selbst Eigentlich wird das sowieso ausgestrahlt , sobald wir keinen Kontext haben, weil dieser nicht Null sein kann Diese Behauptung wird also möglicherweise nicht einmal benötigt. Wir können es einfach dort streichen und die Redundanz reduzieren. Solange wir also diese Zeile haben und der Spieler zuerst lädt, der Spieler im Kontext festgelegt ist und wir dann alle anderen NPCs laden, können wir sie ihren Have-Status verwenden lassen, um sich jetzt auf den Spieler zuzubewegen Also gehen wir innerhalb von Ok in den Status Chase. Also im Chase-Staat müssen wir diesen Hinweis auf den Spieler bekommen. Also können wir das als Verweis auf den Ork nehmen, und dann hat der Ork hier den Spielerkontext Es wurden also ein paar Schritte entfernt. Also lass uns sehen. Vielleicht sagen wir hier etwas wie VR Target, Node Two D. Wir haben also diese lokale Variable. Und wenn wir dann den Chase-Status eingeben, erhalten wir einen Verweis auf dieses Ziel. Sie können es sogar bei der Installation machen, wenn Sie möchten, dass es nur einmalig ist. Ich gebe es in Enter ein. Jedes Mal, wenn wir den Status eingeben, erhalten wir das neue Ziel aus dem Spielerkontext. Das Unterstreichungsziel entspricht hier dem Punkt des Agenten, dem Zielpunkt des Spielers Weil wir nicht wissen, welcher Agententyp ein NPC ist, wissen wir nicht, ob er das Ziel hat und wir wissen nicht, ob das Ziel einen Spieler hat Okay, dieser Teil ist ein bisschen fragil, weil er im Grunde davon ausgeht , dass der Agent ein NPC ist, und es geht davon aus, dass das Ziel gesetzt ist, und es geht davon aus, dass der Spieler in diesem Spielerkontext immer noch die Eigenschaft ist , das Ziel erreicht Also gerade diese Zeile könnte ziemlich leicht kaputt gehen , wenn du einige deiner anderen Klassen änderst. Vielleicht möchten Sie hier nur einige Asserts einrichten auch um als Frühwarnzeichen Wir könnten also sagen: Assert the Agent Dot Target und vielleicht Assert Agent Dot Target Dot Player Ändern wir das von Agent Dot Target zu Agent Dot Target ist ein NPC Okay, und ich denke , das ist gut genug. Es deckt nicht alle Fälle ab, aber wenn wir diese Klasse auf etwas völlig anderes ändern würden , denke ich, dass diese beiden Zeilen das auffangen würden. Lass uns auf Play klicken und schauen, ob es uns immer noch gut geht oder ob wir hier ein Problem haben. Es wurde also erwartet , dass der Agent ein NPC sein würde. Vielleicht will ich Agent Target als NPC. Vielleicht verwende ich da nur das gebundene Schlüsselwort. Also hier möchte ich eigentlich überprüfen , ob der Agent ein NPC ist Der Agent Dot Target ist der Spielerkontext. Also stellen wir sicher , dass der Agent ein NPC ist , damit wir ihn einsetzen können Und wir haben jetzt keine Probleme. Also das ist gut. Und das Letzte, was wir tun müssen, ist die Bewegung in Richtung dieser Zielposition einzufügen, und das werden wir beim Update der Funktion Underscore tun Lassen Sie uns das also umsetzen . Okay, wir müssen also die Zielposition ermitteln. So weit Zielposition. Okay, das wird also von der globalen Position des Unterstrichs des Zielpunkts zugewiesen globalen Position des Unterstrichs des Zielpunkts Und dann haben wir die Position unseres Agenten. Also die Position des Agenten. Das entspricht der globalen Position von Agent Dot. , ein Agent kann technisch gesehen ein normaler Knoten Ich denke, ein Agent kann technisch gesehen ein normaler Knoten sein, und deshalb wird er hier nicht angezeigt. Position als Savara-Agent. Der Grund, warum der Typ nicht abgeleitet werden kann ist, dass wir nicht mit Sicherheit wissen, ob der Agent über diese Eigenschaft für die globale Position verfügt Also müssen wir es dort als Vektor zwei deklarieren. Okay, und dann wollen wir die Richtung zwischen diesen beiden Orten herausfinden. Savara-Richtung entspricht der Zielposition minus der Agentenposition Und dann normalisieren wir diesen Vektor , um nur eine Richtung zu erhalten Es normalisiert also den XY-Wert auf eine Skala von 1,0. Es wird so etwas wie die Entfernung nicht mehr haben. Es wird nur die Richtung des Gegenübers sein, was sehr ähnlich aussehen würde, wenn Sie Vektorwert für die Tastatureingabe eingeben würden. Das wäre auch auf einer Skala von 0-1 für X und Y. Okay, jetzt, wo wir die Richtung haben, müssen wir uns nur noch in der Geschwindigkeit bewegen, die wir zuweisen Jeder unserer Charaktere wird also eine Geschwindigkeit im Spiel haben, und wir werden diese Geschwindigkeit von unserem Statistik-Controller abrufen von unserem Ich denke also, eine gute Möglichkeit, es einzurichten, wäre die Verwendung von Blackboard Wenn ich also auf Enemy HSM klicke, können wir zum Blackboard-Plan übergehen und die Verwaltung übernehmen und eine Variable hinzufügen Sehen wir uns die Statistiken an. Dies kann ein Knotenpfad sein, und dann weisen wir den Statistik-Controller zu. Jetzt können wir das, sagen wir, in unserem Chase-Skript verwenden und die Geschwindigkeit daraus ziehen. Also beim Setup wollen wir diesen Statistik-Controller haben. Wir könnten also var sagen, underscore stats ist ein Statistik-Controller, und wir werden sagen, dass underscore stats gleich Blackboard Dot Git var ist, und wir suchen nach der Von dort aus wollen wir also die Geschwindigkeit ermitteln. Also var-Geschwindigkeit hier unten wieder unten, was ein Float ist, entspricht dem Unterstrich von Stats Dot Get speed Oder wenn wir das noch einfacher machen wollen, könnten wir einfach Punktgeschwindigkeit sagen Jetzt brauchen wir also eine Laufzeitgeschwindigkeit für unsere Charakterstatistiken. Also gehen wir in den Statistik-Controller und lassen uns hier eine Geschwindigkeitseigenschaft erstellen. Was die Geschwindigkeit angeht, entspricht ein Float also 100,0. Das ist also im Grunde die Laufgeschwindigkeit für den Charakter zur Laufzeit Wir haben noch keine Definitionsressourcen eingerichtet, um im Grunde zu kontrollieren, wie die Startstatistiken jedes Charakters wie des Orks oder der Dame aussehen werden, die in ein Skelett eingefügt werden Also bauen wir das einfach Schritt für Schritt auf. Also jetzt im Chase State haben wir unsere Richtung, wir haben unsere Geschwindigkeit, wir haben unser Delta, also müssen wir den Charakter nur um ein bestimmtes Maß bewegen. Wenn Sie also den Körper eines Charakters um zwei D bewegen, gibt es mindestens zwei Möglichkeiten, dies zu tun. Eine wäre, Move and Slide aufzurufen, und das wäre auf dem NPC Also diese Sache mit Agenten ist NPC hier oben, ich denke, es wäre besser, wenn wir Var NPC vom Typ NPC Und stattdessen sagen wir, Unterstrich NPC ist gleichbedeutend mit Agent als NPC Und dann behaupten wir, dass dieser NPC nicht Null ist. Dadurch wird sichergestellt, dass der Agent ein NPC ist, aber wir haben auch einen Verweis auf den NPC, sodass wir seine Klassenfunktionen verwenden können Das macht es einfacher, hierher zu kommen und Dinge wie NPC, Punkt, MOV und Slide zu sagen Dinge wie NPC, Punkt, MOV Du kannst das benutzen, und das hätte auch die Fähigkeit, bei Kollisionen, auf die die Gegner stoßen , mitgleiten Kollisionen, auf die die Gegner stoßen , mitgleiten Aber in diesem Spiel werden wir dafür sorgen, dass unsere Gegner Kollisionen ignorieren , zum einen, weil man dadurch mehr Gegner auf den Bildschirm drängen kann, man dadurch mehr Gegner auf den Bildschirm drängen kann, und zum anderen, weil es so einfach ist, aber ich werde hier tatsächlich NPC Dot Translate machen Auf diese Weise können Sie sich bewegen, ohne Kollisionen zu berücksichtigen Es hat also den Nachteil, dass deine Charaktere nicht in der Lage sein werden, an Kanten wie Wasserrändern oder Bäumen oder ähnlichen Dingen entlang zu rutschen Kanten wie Wasserrändern oder Bäumen oder ähnlichen Dingen entlang Bäumen oder , die dir im Weg stehen Es hat aber auch den Vorteil dass die Bewegung so einfach wie möglich ist, was bedeutet, dass Sie mehr Feinde gleichzeitig auf den Bildschirm drücken können gleichzeitig auf den Bildschirm Und ich denke, dass das vielleicht ein bisschen besser zu einem Vampir-Survivor-Stil passt bisschen besser zu einem Vampir-Survivor-Stil Also werden wir unsere Feinde einfach hirntot machen unsere Feinde einfach hirntot Also pc dot translate, wir bewegen es nur um einen bestimmten Betrag in eine bestimmte Richtung. Also machen wir Richtung mal Geschwindigkeit mal Delta. Nun, das würde gut funktionieren, aber vielleicht möchten Sie das Bit in einer weiteren Variablen weiter oben herausnehmen und unseren Zug speichern , der vom Typ Vektor zwei ist, und wir setzen das hier auf dieses Bit. Also rechnen wir außerhalb des Funktionsaufrufs und rufen sie dann für den Bewegungsvektor zwei auf , sobald wir den haben. Das würde auch beim Debuggen helfen , weil Sie dort einen Breakpoint setzen können und dann würde es Ihnen zeigen, was der Move-Wert tatsächlich erreicht hat, bevor Sie translate aufrufen Andernfalls wüsstest du nicht, was mit dem Übersetzungsaufruf passiert, wenn du das einfach da eingibst , es sei denn, du würdest hier reinspringen Also ein bisschen sauberer, ein bisschen einfacher. Okay, also ich drücke auf Play und wir werden sehen, wo wir uns befinden. Die Orks rennen auf den Spieler zu, und wo auch immer der Spieler auf dem Bildschirm ist, sie werden versuchen, dorthin zu gelangen, was genau das ist, was wir erwarten würden Jetzt bewegen sie sich allerdings ziemlich schnell, also gehe ich vielleicht zu Stack Controller und setze die Standardgeschwindigkeit auf etwa, sagen wir, 40,0, und Okay, und ich denke, das ist ein bisschen passender. In den meisten Fällen sollte sich der Feind langsamer bewegen als der Spieler, damit der Spieler zumindest die Möglichkeit hat, ihm auszuweichen. Wir können sehen, dass sie sich alle übereinander stapeln Okay, also drücken wir auf Play und wir werden sehen , dass die Orks auf den Spieler zurennen Diese Bäume haben keine Kollisions-Setups, aber selbst wenn, würden sie trotzdem direkt durch den Körper des Spielers laufen Jetzt kollidiert der Spieler auch immer noch mit den Orks. Und das liegt daran, dass die Orks immer noch eine Kollisionsform und einen Kollisionskörper haben und der Spieler sich mit Move und Slide bewegt Es liegt also an uns, wohin wir von hier aus wollen. Wir könnten alle Orks auf eine andere Kollisionsebene bewegen , indem wir hier Kollision verwenden Und das würde ich wahrscheinlich jetzt tun. Lassen Sie uns einige Kollisionsebenen einrichten. Bearbeiten Sie also die Ebenennamen. Wir sagen, eins ist Welt, zwei ist Spieler, drei ist Feind, vier ist Projektil, und das sollte vorerst gut sein. Wir werden das schließen Also wollen wir unsere Feinde auf die feindliche Ebene verschieben und die Maske ausschalten, damit sie im Moment nicht darauf aus sind , mit irgendwas zu kollidieren Wenn wir jetzt also auf Play drücken, kann unser Spieler direkt durch die Feinde hindurchgehen, würde aber trotzdem mit allem anderen kollidieren Also ich mag es eigentlich nicht , dass sie sich übereinander stapeln Also, obwohl Translate die schnellste Funktion wäre , die hier für Chase State ausgeführt werden könnte. Und das ist definitiv der Satz von Codezeilen , der der Leistungsblock für das Projekt sein wird weil Sie Hunderte von möglicherweise sogar Tausenden von Feinden haben möglicherweise sogar Tausenden von , die versuchen, sich mit diesem Aktualisierungsskript gleichzeitig zu bewegen . Und denken Sie daran, dass fast jeder Feind die ganze Zeit im Verfolgungsmodus sein wird die ganze Zeit im Verfolgungsmodus , bis er tatsächlich besiegt ist, und zwar nur für eine Sekunde. Sie sprechen also dass sich alles gleichzeitig im Verfolgungsstatus befindet , während das Update in jedem Frame ausgeführt wird. Das ist also der Teil , in dem, wenn Sie etwas optimieren müssen, es hier sein würde. Fügen wir die Kollision für die Orks wieder hinzu. Wir lassen sie mit sich selbst kollidieren und wir werden sehen, ob wir dadurch ein besseres Dass die Orks alle übereinander liegen, ist nicht wirklich ideal Also legen wir das wieder rein. Also statt NPC Dot Translate zu machen, sagen wir, dass Underscore NPC Velocity gleich diesem Bit ohne Delta sein wird gleich diesem Bit ohne Delta Also werde ich das Delta loswerden und wir sagen Okay. Und dann setzen wir die alte Geschwindigkeit auf die neue Geschwindigkeit. Und statt NPC Dot Translate aufzurufen, nennen wir NPC Dot Move and Slide Ich möchte noch einmal wiederholen, dass für meine Tests etwa doppelt so viel Rechenleistung benötigt etwa doppelt so viel Rechenleistung Wenn ihr also 5.000 Gegner gleichzeitig auf dem Bildschirm haben könntet , bevor die Verzögerung zu groß wird, wären es jetzt etwa 2.500 Aber wenn du die Feinde im Weltraum haben kannst, brauchst du vielleicht nicht 2.500 Gegner gleichzeitig auf dem Bildschirm , weil sie alle eine völlig andere Position einnehmen. Also vielleicht ist das der richtige Weg. Also lasst uns zur Veranda gehen und wir werden sie so gestalten, dass sie den Feind maskiert Es wird hier auch mit dem Spieler kollidieren. Es schaut also auf den Spieler, den Feind. Und machen wir es auch zur Welt, aber nicht zu Projektilen. Okay. Und dann wollen wir jetzt zum Player gehen, wo wir eigentlich mit verschiedenen Kollisionsebenen arbeiten , und wir werden seine Kollisionsebene , die sich unter Kollisionsobjekt zwei D befindet, auf Spieler einstellen . Und dann wollen wir, dass es mit der Welt kollidiert. Und eigentlich denke ich genau das. noch einmal darüber nachdenke, die Orks, vielleicht möchte ich nicht, dass es mit dem Spieler kollidiert Ich möchte vor allem, dass der Spieler in der Lage ist, durch Feinde hindurchzugehen, damit er tatsächlich entkommen kann Die Feinde werden also mit den Feinden und der Welt kollidieren und wir werden von dort aus auf Play klicken Irgendwann könnten wir sogar die Welt ausschalten. Es hängt irgendwie davon ab, was wir wollen. Okay, lass uns sehen. Es sieht so aus, als ob sich die Feinde nicht übereinander stapeln, was wahrscheinlich auch gut ist Sie werden nicht genau den gleichen Raum einnehmen. Wenn wir wollen, dass sie noch weiter voneinander entfernt sind, würden wir einfach die Größe dieser Kollisionsform vergrößern Hier, wenn ich das Spiel ganz schnell pausiere und wir zum Editor für sichtbare Kollisionsformen gehen, können wir hier wieder reingehen Oh, dafür müssen wir das Spiel wohl neu starten. Okay, wir starten neu und dann können wir die Kollisionsformen sehen. Also das hier unten, das ist die Kollisionsform des Orks. Der große ist der Trefferradius, also können wir sie von oben treffen, aber sie können nur an den Füßen kollidieren , weil wir die Kollisionsformen zuvor so definiert haben Aber ja, mit diesem Setup werden sie etwas weiter voneinander entfernt sein. Und ich glaube, ich mag es 23. P22 Gegner auf einer Zeitkurve erzeugen: Du kannst sehen, wie unsere Feinde arbeiten. Sie werden eine kleine Kollision miteinander haben. Was, weißt du, nachdem ich mir das angeschaut habe, definitiv der richtige Weg ist, und nicht die Methode der Übersetzung. Allerdings haben wir immer noch nur vier Orks gleichzeitig. Wir wollen in der Lage sein, eine ganze Menge mehr Typen zu spawnen, und wenn wir uns für diesen Survivor-Stil entscheiden, wollen wir, dass sie außerhalb des Bildschirms erscheinen und sich dann auf den Spieler zubewegen dann Also fast kreisförmig, müssen sie einfach außerhalb des Bildschirms erscheinen und dann den Spieler einfach in der Mitte des Bildschirms anschwärmen Dafür brauchen wir also ein Spawnsystem. Gehen wir in die Welt und fügen hier einen neuen Systemknoten Ich klicke mit der rechten Maustaste auf Einen untergeordneten Knoten als Knoten hinzufügen und benenne ihn dann in Spawnsystem oder SponnorSystem um , wenn Sie Klicken Sie mit der rechten Maustaste darauf und hängen Sie ein Skript an. Also nennen wir es Sponsorsystem Punkt gD und ich werde es im Systemordner speichern Und dann müssen wir für unser Spawner-System eine ganze Reihe verschiedener Eigenschaften deklarieren Reihe verschiedener Eigenschaften , die als Exportbalken dienen damit Sie sie im Inspektor anpassen können Also zuerst benötigen wir den Spawn-Rand, ein Float ist , und ich lasse ihn standardmäßig auf zehn setzen. Hab das Auto dort vergessen Okay, der Spawn-Abstand ist also der Mindestabstand zum Bildschirm , den die Charaktere spawnen können Das ist in Pixeln. Ich werde das so nennen , weil es tatsächlich Charaktere sind und auch Charaktere da oben. Wir haben vielleicht eine Welt , in der wir NPCs spawnen, nicht unbedingt nur Feinde Es hilft also, generischer zu sein, wenn du dir nicht sicher bist dein Script letztendlich verwendet werden soll, weil du vielleicht möchtest, dass es flexibler ist, als nur Feinde zu erledigen Okay, als Nächstes wollen wir die Spawn-Extra-Reichweite. Okay, also bei Export VR Span Extra Range lasse ich das auf 100 gehen Okay, das ist also die zusätzliche Entfernung , die ein Feind zusätzlich zur Spannweite vom Bildschirmrand entfernt spawnen kann vom Bildschirmrand entfernt . Wenn Ihr Spawnabstand also zehn ist und Ihre zusätzliche Reichweite 100 beträgt, dann bedeutet das, dass der Pixelabstand vom Rand der Kamera zehn bis 110 Pixel betragen wird Dann brauchen wir die Definitionen für unsere Feinde, die wir spawnen werden Das sollte also im Grunde ein Setup sein besagt, was unter welchen Bedingungen spawnen kann Sagen wir also beim Export von Var-Zufallsdefinitionen, was ein Array von Spawning-Definitionen ist. Okay, jetzt haben wir diese Klasse nicht definiert. Es wird ein Ressourcentyp sein. Es ist eine Definition, die wir im Editor eingerichtet haben und die wir während des Spiels verwenden. Eine Ressource ist also der perfekte Typ für diese Art von Daten. Okay, das wird uns einen Fehler geben , weil wir den Klassennamen der Spawning-Definition nicht definiert haben Lass uns das machen. Gerade jetzt. Ich gehe ins Stammverzeichnis unseres Projekts und des Dateisystems. Nehmen wir an, das gehört vielleicht in Systeme, weil es Teil des Spawnsystems ist Ich klicke mit der rechten Maustaste, erstelle einen Ordner und wir sagen Spawnen Und dann klicke ich hier mit der rechten Maustaste, erstelle ein neues Skript und ich sage hier, dass die Underscore-Definition erzeugt wird, was vom Typ Ressource ist Okay, erstelle das und öffne dann das Skript. Okay, und wir müssen einen Klassennamen und eine Spawning-Definition hier oben angeben , und wir werden uns später darum kümmern , das einzurichten Um also mit dem Spawn-System fortzufahren, brauchen wir ein übergeordnetes Element für den Ort, an dem wir unsere Objekte tatsächlich spawnen Bei Export ist var spawn parent also eine D-Referenz für Knoten zwei, das Elternteil für jedes Objekt, das vom System erzeugt wird. Und dann wollen wir die Frequenz. Also werde ich daraus eine Kurve machen , damit wir den Timer steuern können. Im Laufe der Zeit verwenden wir einfach eine Kurve und nehmen dann anhand der Kurve Stichproben Anstatt also zehn verschiedene Zeiträume festzulegen, nach 30 Sekunden alle 0,5 Sekunden Und dann, nach 60 Sekunden, alle 0,4 Sekunden Spa Wir können es einfach als Kurve haben. Und dann, egal wann es spawnt, bezieht es einfach seinen nächsten Timer-Betrag aus dieser Kurve Wenn Sie also viele Werte haben wollen, ist es einfacher, eine Kurve mit einer Steigung zu definieren , als eine nach der anderen zu gehen und zu sagen, dass X dann Y eher und zu sagen, dass X ein Wörterbuchstil Ich sage also Export var span frequency, was vom Typ Kurve ist. Okay. Darauf kommen wir im Inspektor zurück. Okay, das nächste, was wir brauchen werden, ist eine Laufzeitvariable. Ich nenne es var random span stats. Und das wird vom Typ Wörterbuch sein. Ich möchte dem Wörterbuch einen Schlüsseltyp und einen Wertetyp geben. Und der Wertetyp ist Spawn Stats. Das entspricht also der Art des Spawns mit den Statistiken für das Spawnen in einem Verhältnis von eins zu eins zur Laufzeit Das ist also laufzeitspezifisch und das ist editorspezifisch Und die Spawn-Statistik wird verfolgen , wann wir das letzte Mal ein Objekt erzeugt haben und wie oft wir mit diesem System gespawnt haben Lassen Sie uns also unser Spawn-Statistik-Objekt erstellen. Ich klicke mit der rechten Maustaste auf Spawnen und erstelle ein neues Skript. Wir nennen es Spawn-Statistiken. Wir werden diesen Extend-Ref tatsächlich zählen lassen. Jetzt können wir zu Span Stats springen, und hier oben gebe ich ihm den Klassennamen Spatts Und die beiden Dinge, die ich hier verfolgen möchte , sind die Spawn-Anzahl, die eine Ganzzahl ist, die bei Null beginnt , und die letzte Spawnzeit, die ein Float ist, und wir beginnen mit Enfinit Dies wird das letzte Mal sein, dass das Objekt erzeugt Okay, jetzt haben wir in unserem Spawnsystem diese Beziehung Wenn wir also das Spawnsystem starten, wollen wir die Definitionen verwenden und für jede Definition neue Span-Statistiken erstellen für jede Definition neue Span-Statistiken Das behandelt also die Laufzeitdaten. Dies behandelt die Editor-Details für unser Eins-zu-Eins-Setup hier. Wenn wir also die Span-Statistiken abrufen möchten, können wir einfach auf die Span-Definition verweisen, und es werden sofort die Span-Statistiken ausgegeben, die dem entsprechen Und so funktionieren Wörterbücher auf den Punkt gebracht . Sie haben einen Schlüssel, und er gibt Ihnen einen Wert, und er ist sehr nützlich, um zwei verschiedene Objekte miteinander in Beziehung zu zwei verschiedene Lassen Sie uns also unsere Systembereitschaftsfunktion einrichten. Nehmen wir an, die Funktion underscore ready gibt den Wert void zurück Und wir wollen zur Definition in zufälligen Definitionen sagen, wir wollen die zufälligen Spawn-Statistiken nehmen und wir wollen den Definitionsschlüssel unserem Wert zuweisen , der eine neue Spawn-Statistik sein wird Spawn-Statistiken sind also nicht okay. Und jetzt haben wir eines dieser Objekte für jede Definition, und sie sind eins zu eins verknüpft, wobei Spawning-Definition als Schlüssel und die Span-Statistiken als Wert verwendet Jetzt ist es also sehr einfach, die Spawn-Statistiken für die Definition nachzuschlagen Spawn-Statistiken für die Definition nachzuschlagen Okay, und nehmen wir an, dass die nächste Spawnzeit der Spawn-Frequenz entspricht, also die nächste Spawnzeit der Kurve , und wir nehmen anhand der Kurve die Zeit ab, die seit dem Start des Spiels vergangen ist Zeit ab, die seit dem Start des Spiels vergangen Also brauchen wir hier oben noch ein paar Variablen. Wir benötigen die verstrichene Zeit, also die Zeit, seit das Spawnsystem in die Spielwelt eingeführt wurde Wir können eine Timer-Variable erstellen. VarsPawTR ist also ein Float vom Typ Null, Null. Da dies ein interner Timer sein wird, ist es in Ordnung, wenn ein Knoten seine eigene Zeiterfassung verwaltet Also werden wir versuchen, das mit einem Span-System zu machen, anstatt echtes Timer-Objekt in der Spielwelt zu erstellen. Das Spawnsystem wird also für diese Instanz sein eigenes Timing Und dann wird die nächste Spawnzeit im Grunde davon abhängen, wie lange wir auf dieses nächste Spa warten Lassen Sie uns hier die Timer-Funktion einrichten, Funktion underscore process, und das wird Delta als Parameter sein, gibt void zurück Wir nehmen die verstrichene Zeit und fügen das Delta hinzu, das ist die Zeit seit dem letzten Verstrichene Zeit plus entspricht also Delta. Und dann wollen wir den Spawn-Timer nehmen und Plus ist auch gleich Delta, da wir verfolgen, wie lange es her ist, dass der Spawn wie lange Und wir sagen, wenn der Spawn-Timer größer oder gleich der nächsten Spawnzeit ist, dann machen wir ein zufälliges Also zufällige Spanne hier, und danach nehmen wir den Spawn-Timer Und anstatt das direkt auf Zal zu setzen, setze ich Minus gleich der nächsten Spawnzeit, weil es ein bisschen Restzeit geben könnte, vor allem, wenn wir zu sehr kleinen Zeitintervallen kommen Also ich denke, es ist ein bisschen besser, es so genauer zu machen Und dann sagen wir, dass die nächste Spawnzeit eine Stichprobe aus der Frequenzkurve sein wird Das entspricht der Punktstichprobe mit der Spawn-Frequenz, und wir nehmen die verstrichene Zeit der XY-Kurve handelt es sich also im Grunde um ein Diagramm, bei dem X angibt, wie viel Zeit vergangen ist , seit das System Und dann gibt Y an, wie lange auf die nächste Zeitspanne gewartet werden muss. Unabhängig von der verstrichenen Zeit wird es also einen neuen Wert geben, den wir aus der Kurve abrufen können , um unsere nächste Spawnzeit festzulegen Okay, noch ein paar Zeilen, und lassen Sie uns unsere Zufalls-Spawn-Funktion ausführen, bisher Zufallsspanne bisher Gibt den Typ von Leere zurück. Was wir also tun müssen, ist unsere Spawn-Definition zu finden , die wir spawnen wollen Das wird also eine zufällige Auswahl sein, die auf einer Gewichtung der einzelnen Definitionen basiert einer Gewichtung der einzelnen , um zu bestimmen , welches Objekt spawnen soll oder nicht Okay, ich werde hier vorerst aufhören, weil die Logik für das Spawnen etwas komplizierter werden wird etwas komplizierter werden Ich will es nur so machen, dass wir zumindest vorerst sehen können , dass es in der Spielwelt funktioniert also zurück in die Zwei-D-Ansicht, nehmen wir das Spawner-System und weisen diesen Bon-Parent dem gegnerischen Knoten zu. Okay? Also so, es sollten Feinde sein. Diese Bindungsfrequenz wird eine neue Kurve sein. Gehen wir also mit dieser Kurve fort und wir können Werte definieren. Also, wenn Sie hier hineinzoomen können, wird das helfen. Die Min-Domain in der Max-Domain wird im Grunde die Anzahl der Sekunden angeben, die wir im Spiel haben. Du könntest also so etwas wie 300 Sekunden oder 120 Sekunden sagen . Egal, wie lang das Level deiner Meinung nach sein sollte , du würdest es zur Max-Domain machen wollen. Wenn Sie also eine letzte Zeit für Ihr Level haben und danach das Level endet, dann wäre das perfekt für die Max-Domain hier. Der X-Y-Wert, wir immer dann erhalten wollen, wenn wir den X-Wert abtasten. Wie lang sollte es also zwischen den Spawns sein? Vielleicht zwei als Maximalwert dann gehen wir hier hoch zur Kurve und wir klicken mit der linken Maustaste, um einen Punkt zu setzen, und das kontrollieren wir einfach irgendwie Im Allgemeinen möchtest du also am Anfang eines Levels weniger Spawns haben als am Ende Also wenn wir das hier hochziehen und sagen, vielleicht nur alle 1,5 Sekunden erscheint ein Charakter, und dann gehen wir nach rechts und wir klicken mit der linken Maustaste und wir ziehen diesen Keyframe runter, zeigen wir auf so etwas, wo wir sagen können alle vielleicht nicht Oh, vielleicht sogar 0,2 Sekunden. Also kann alle 0,2 Sekunden ein Feind erscheinen. Und wir haben quasi diese Kurve von hier nach hier. Sie können auch auf die Punkte klicken, und es gibt einen Kurvenanpasser, falls Sie ein bisschen schick damit Wenn wir es jetzt ausprobieren würden, sagen wir 75 Sekunden nach Beginn des Spiellevels, würde das bedeuten, dass die Spawnzeit hier etwa 1,2 betragen würde Wir können das von der Stelle aus sehen, an der sich XY auf der Linie überschneidet. Wenn wir also bis 225 gehen würden, dann läge zwischen der Spawn-Frequenz der Gegner etwa eine halbe Sekunde Spawn-Frequenz der Gegner Der Schwierigkeitsgrad wird also mit zunehmendem Level immer schwieriger. Und wir können das einfach anpassen . Sie können bei Bedarf sogar einen dritten Punkt in der Mitte setzen. Vielleicht musst du es für eine Weile flach machen und dann richtig hart Drücken Sie E, um es rückgängig zu machen. Und ich denke, Sie können mit der rechten Maustaste auf einen Knoten klicken , um ihn aus dem Diagramm zu entfernen. Höchstwahrscheinlich sind zwei Punkte gut genug, weil Sie das mit den Griffen irgendwie kontrollieren können , wenn Sie die Geschwindigkeit ändern müssen Geschwindigkeit ändern , mit der es schwieriger wird. Aber das könnten wir irgendwie machen. Nun, ich persönlich werde diesen Weg hier nach links nehmen, weil ich bei unseren Tests nicht wirklich länger als hier nach links nehmen, weil ich bei unseren Tests 2 Minuten testen möchte. Ich möchte es einfach schnell machen, damit ich zeigen kann , wie es später funktionieren wird Aber in deinem eigentlichen Spiel kannst du gerne eine viel längere, ausgedehntere Spawn-Kurve Im Moment, nach 120 Sekunden hier, wird es für den Rest einfach flach sein Und das ist momentan in Ordnung für mich. Okay, lassen Sie uns jetzt eine Spawn-Definition erstellen. Hier oben. Wir fügen einen hinzu. Wir müssen eine neue Ressource für die Spawning-Definition erstellen Also neue Spawn-Definition, wir klicken mit der rechten Maustaste und speichern Gehen wir zu den Charakteren und Feinden über. Und ich kann das in den gleichen Ordner legen, in dem sich der Ork befindet weil wir es Ork-Spawning nennen Definition oder einfach nur Ork-Spawnen. Ich denke, das Laichen von Orks ist in Ordnung. Dot TR, ja, wir speichern es. Aber damit ist natürlich noch nichts verbunden. Also müssen wir hinzufügen, welche vollgepackte Szene wir tatsächlich instanziieren werden, wann immer wir den Ork spawnen Okay, also in der Spawning-Definition, im Skript . Fügen wir den vR-Export der Szene hinzu, was eine Art gepackter Szene ist Und wir können auch ein Export-Variablengewicht hinzufügen, das einem Gleitkommawert von 1,0 entspricht. Wir haben also die Szene, die erzeugt werden soll, und die Präferenz , diese Szene als zufällige Spawn-Wahl auszuwählen als zufällige Spawn-Wahl Wenn wir also nach dem Zufallsprinzip auswählen, haben wir vielleicht drei Typen, und sie haben jeweils ein anderes Gewicht Wenn also einer ein Gewicht von drei hat und der andere ein Gewicht von eins, dann hat derjenige, der ein Gewicht von drei hat , die dreifache Wahrscheinlichkeit, als derjenige ausgewählt zu werden , der ein Gewicht von eins hat. Und das ist nur eine Möglichkeit, wie wir die Zufälligkeit etwas verzerrter gestalten können Zufälligkeit etwas verzerrter Es ist also nicht völlig zufällig. Es ist so, dass jede Wahl ein Gewicht hat, und das Gewicht bestimmt die Chancen. Im Schema der Zufallsauswahl. Also klicken wir jetzt auf Spawnsystem. Ok Spawning wird jetzt eine Szenenreferenz haben, also laden wir schnell unsere Ok-Szene Okay, das gibt uns jetzt, was wir brauchen. Also, was zufälliges Spawn angeht, werde ich es jetzt so einfach wie möglich machen, indem die erste Definition in der Liste verwende und sie dann instanziere. Bisher entspricht die Instanz, die ein Nein-Zwei-D sein wird , den zufälligen Definitionen an Position Null Und wir werden uns die Szene holen und wir werden sie instanziieren. Okay, wir haben jetzt unseren Arzt. Das ist die Nullposition und der Ork spawnt. Also nehmen wir das und fügen es dem zufälligen Elternteil oder dem Spawn-Elternteil Also spawnen Sie den übergeordneten Punkt Ad child der Instanz, wir lassen die Instanz vorerst einfach auf Position 00 gehen auf Position 00 Wir werden uns später um ihre zufällige Positionierung kümmern. Und dann können wir sehen, dass das Span-Management hier draußen bereits außerhalb der Zufalls-Spawn-Funktion verwaltet Also ehrlich gesagt, das könnte eigentlich alles sein, was wir brauchen. Zu Testzwecken nehme ich das und mache es hier auf etwa 10 Sekunden, nur damit wir wirklich sehen können, wie nur damit wir wirklich sehen können das Spawnen hochfährt, wenn es funktioniert, und wir drücken auf Play. Also lass uns sehen Haben wir irgendwelche Charaktere, die um 00 Uhr kommen? Oh ja, ja, ich kann sie genau dort sehen. Okay, hier sind unsere Orks. Sie können sehen, dass es mit der Zeit immer schneller spawnt . Wir haben also quasi schon den Höhepunkt erreicht, wo Orks spawnen, und unsere Speere können sie einfach durchschneiden, weil unser Speer keine maximale Trefferzahl hat, also ist es momentan sehr einfach, dieses Spiel zu gewinnen Aber du kannst sehen, wie die Kurve es macht, sodass wir das Spawnen im Laufe der Zeit leicht erhöhen können , und das ist einfach ein cooles Feature, das mir Es ist viel besser , damit zu arbeiten, als in etwa 10 Sekunden zu definieren, jetzt ist die Spawn-Rate 1,0, und nach 20 Sekunden ist sie jetzt 0,9 Jetzt können Sie einfach alle Werte für die ganze Zeit, im Grunde genommen nach dieser Kurve verwalten, und es ist einfach viel einfacher, sie irgendwie zu bearbeiten Sie verlieren an Präzision, aber es wird viel einfacher, Ihnen einen allgemeinen Eindruck davon zu vermitteln, was Sie für diese Werte benötigen. Und Sie können immer noch, Sie wissen schon, klicken und absolute Werte festlegen. In den Punkten hier können Sie also sehen, dass Sie die exakten XY-Positionen für diese Punkte festlegen können die exakten XY-Positionen für , wenn Sie wirklich technisch werden müssen. Aber in den meisten Fällen, wie ich schon sagte, reichen nur zwei Punkte auf einer Kurve aus. Es gibt also noch viel zum Spawnsystem hinzuzufügen, aber das ist ein ziemlich guter Anfang für das, was wir brauchen 24. P23 Auslösen außerhalb des Bildschirms mit berechnetem Offset: Okay, unser Spawnen funktioniert also bereits. Aber das Problem ist , dass die Charaktere gerade an dem 00-Punkt spawnen, wo wir eigentlich wollen, dass sie außerhalb der Kamera spawnen , wo auch immer unsere Kamera hinschaut Es sieht also immer so aus, als würden sie von irgendwoher kommen, sehr weit weg, aber in Wirklichkeit kommen sie nur von etwas weiter weg von dem, was wir sehen können Und dann werden sie den Spieler überschwemmen anstatt im 00-Punkt zu spawnen Also lass uns daran arbeiten. Okay, also in unserem Spanner-System-Skript werden wir nach dem Zufallsprinzip wieder darauf zurückkommen Im Moment ist zufälliges Spawn also nicht sehr zufällig. Lass uns daran arbeiten, den Feind vom Bildschirm zu spawnen. Also brauchen wir einen neuen Ort, an dem wir die Instanz spawnen Lassen Sie uns hier unten eine Var-Spawn-Position hinzufügen . Also das wird ein Vektor zwei sein. Und das holen wir uns von Get Spawn Position aus der Kamera Also wollen wir eine Span-Position erzeugen , die außerhalb der Kamera Das erfordert also etwas Mathematik und den aktuellen Viewport der Kamera selbst Lassen Sie uns also unsere Funktion Get Span Position außerhalb der Kamera erstellen Get Span Position außerhalb der Kamera Das Erste, was wir tun müssen, ist, die Kamera TD zu bekommen, die gerade aktiv ist, also das, was unser echter menschlicher Spieler auf dem Bildschirm betrachtet , damit wir uns beim Spawnen davon fernhalten können Unsere Kamera entspricht also Get Viewport. Im Grunde schauen wir uns also an, was der Spieler gerade sehen kann, und wir werden die Kamera zwei D bekommen, die der Spieler benutzt, um das Viewport zu betrachten Wir haben also Zugriff auf diese Kamera, vielleicht macht es sogar Sinn, sie als Kamera zwei D zu markieren vielleicht macht es sogar Sinn, sie als Kamera zwei D zu markieren. Also könnten wir einen Wachmann überprüfen lassen, wenn wir wollen, sagen, dass, wenn die Kamera Null ist , was wahrscheinlich nie passieren sollte, aber theoretisch , wenn es könnte, dann wollen wir einen Fehler ausgeben, dass keine Kamera, keine Kamera zwei D im Viewport gefunden wurde. Vielleicht könnte das passieren, wenn Sie aus irgendeinem Grund eine Drei-D-Kamera verwenden und es einfach keine Zwei-D-Kamera gibt. Ich denke, das würde dazu führen, dass es einen Fehler auslöst . Es ist also möglich. Okay, also wenn das passiert, dann gibt es ein großes Problem im Spiel. Wir geben einfach den Vektorpunkt Null zurück. Das passiert und wir geben den Fehler weiter und lassen den Entwickler herausfinden : Oh, warum gibt es keine Kamera im Spiel. Okay, aber vorausgesetzt, wir haben eine Kamera, können wir tatsächlich rechnen. Also wollen wir zuerst die Mittelposition der Kamera ermitteln. Lassen Sie uns sagen, dass die Mitte der VR-Kamera ein Vektor zwei ist, und dafür wollen wir die globale Position des Kameradoks und dafür wollen wir die globale Position des Kameradoks. Ja, einfach so. Und dann wollen wir die Größe der Kamera. Also, wie groß ist die Kamera in der X-Dimension und der Y-Dimension. Das sollte also ein weiterer Vektor zwei sein. Wir sagen also, dass die VR-Kameragröße von Vektor zwei gleich der Größe von Vektor zwei sein wird, und wir erhalten die Größe des Darstellungsfensters Ermitteln Sie also die Punktgröße des Ansichtsfensters, und dann wollen wir diese durch den Kamerazoom teilen Okay, der Grund dafür ist, dass unsere Kamera, besonders in einem Zwei-D-Pixar-Spiel, wenn ich hier oben auf Kamera zwei D klicke und wir dann hier auf den Zoom schauen, dann kannst du sehen, dass unser Zoom tatsächlich den Viewport nimmt und ihn vier- oder fünfmal skaliert ihn vier- oder fünfmal , sodass wir unseren Pixar gut sehen können Deshalb müssen wir sicherstellen , dass unsere Kameragröße tatsächlich auf diese neuen Werte basierend auf dem Zoom herunterskaliert wird, selbst wenn wir etwa 12 80 mal 720 Pixel betrachten , selbst wenn wir etwa 12 80 mal 720 Pixel , wenn wir um den Faktor fünf unsere Kameragröße tatsächlich auf diese neuen Werte basierend auf dem Zoom herunterskaliert wird heranzoomen. Deshalb müssen wir diese Anpassung vornehmen. Als Nächstes haben wir also die VR-Kamera Rect , also eher vom Typ Rect Two D oder Rect Two. Und das ist eine rechteckige Form, die die Grenzen unserer Kamera darstellt Es basiert auf der Größe. Für die Mathematik hier konstruieren wir also ein neues Rechteck, indem wir Rechteck zwei und dann Klammern machen Und unser erster Parameter ist Kamerazentrum minus Kameragröße Und dann multiplizieren wir das mit 0,5. Und für die zweite Dimension haben wir nur die Kameragröße. Das gibt uns also das entsprechende rechteckige Feld , das die Kamera auf dem Bildschirm darstellt. Als Nächstes wollen wir nach dem Zufallsprinzip eine Kante auswählen, an der wir die Feinde spawnen Unsere Kamera ist also eine Kiste, sie hat also vier Kanten, und wir können unsere Feinde im Grunde oben, unten, links oder rechts spawnen unten, links oder rechts Also wollen wir einfach einen dieser Kanten auswählen, und weil wir eine gleichmäßige Verteilung wollen, machen wir das einfach nach dem Zufallsprinzip. Und dann gibt es kein Warten mehr. Also, im Wesentlichen sollte es nur bedeuten, dass sie ziemlich konsistent aus allen Richtungen kommen. Wenn wir also var edge sagen und das ein Integer-Wert sein lassen, dann entspricht er Rand I für Integer. Wir geben ihm Prozent vier? Das Prozentzeichen hier bedeutet Rest, also ist es der Rest, wenn wir es durch vier teilen, was bedeutet, dass es entweder Null, Eins, Zwei oder Drei ist, und diese stellen unsere vier Kanten dar. Okay, dann brauchen wir einen Offset. Wie weit vom Rand entfernt wollen wir unseren Feind tatsächlich spawnen lassen Wir wollen nicht , dass sie direkt am Rand spawnen , weil er dann auf dem Bildschirm sichtbar wäre wenn er die Spielwelt betritt, und das würde irgendwie funky aussehen Sagen wir also var offset, und das wird, glaube ich, eine Gleitkommazahl sein, Abstand zwischen Unterstrich und zufälliger Gleitkommazahl entspricht Okay, also wir generieren hier im Grunde eine zufällige Gleitkommazahl und wir werden das mit dem Span Extra-Bereich multiplizieren Zufälliges F kann also 0-1 0,0 sein. Ein Wert von Null mal unserer zusätzlichen Spanne ergibt uns also Null mal unserer zusätzlichen Spanne eine zusätzliche Spawn-Entfernung von Und wenn es 1,0 ist, ergibt das 100 , weil wir es auf die Eigenschaft span extra range gesetzt haben auf die Eigenschaft span extra range Und wenn wir etwas dazwischen haben, dann erhalten wir einen Wert von 0 bis 100 Pixeln Zusätzlich zu unserer Spannweite erhalten wir den gesamten Offset Okay, also sagen wir var spa position, und das wird hier einem Vektor 20 zugewiesen. Bei Null wird die Konstante eher großgeschrieben. Okay. Füge noch ein paar Zeilen hinzu. Und wir sagen, wenn die Kante kleiner oder gleich eins ist, dann behandeln wir das als Ober- oder Unterkante. Dann nehmen wir unsere Kante und machen daraus eine Match-Aussage, sodass wir Position des Sohnes anhand der Kante, die wir tatsächlich verwenden, berechnen können . Sagen wir also, Match Edge und Standard, wir geben einen bearbeiteten Fehler an. Kantenzahl, Prozent als Prozent Kante. Das zu haben, ist einfach hilfreich, wenn wir aus irgendeinem Grund vergessen , einen der Koffer einzureichen. Jetzt können wir die Edge-Ganzzahl tatsächlich einem Enum-Wert zuordnen , wenn wir hier etwas verbaler sein wollen . Wenn wir also von hier nach oben gehen, deklariere ich eine Aufzählung, sagen wir enum edge, und wir werden oben als Null, unten als eins, links als zwei und rechts als drei haben unten als eins, links als zwei und rechts als drei Okay, wenn wir jetzt hier runter gehen und den Rand mit diesen Werten abgleichen, könnten wir Edge Dot Top sagen, wenn ich mich nicht Warte eine Minute. Scheint, als ob es hier ein kleines Problem gibt. Trotzdem muss ich hier das Gleichheitszeichen für die Kamera rechts setzen . Okay, das wird also funktionieren. Jetzt können wir zu dem Punkt kommen, an dem wir den Enum-Matching gemacht haben, und wir wollen den Code hier eingeben Die Spawn-Position X für oben wird also einem zufälligen Float aus einem Bereich entsprechen Also sagen wir Rnf-Unterstrichbereich, und wir gehen vom Punkt X des Kamerarechtecks zum Punkt X der Kamerapunktposition plus Punkt X. Bei einem rechteckigen Tutti wird die Position X also immer hier oben sein Wenn du also die Größe X hinzufügst, dann würdest du hier auf der rechten Seite ankommen Wenn wir also nach oben streben, wollen wir uns irgendwo zwischen hier und hier positionieren. Deshalb nehmen wir den Zufallswert der Position und dann die Position plus die Größe. Das ermöglicht uns also, genau hier irgendwo zwischen dieser Linie zu kommen . Und dann müssen wir natürlich die Y-Position nehmen. Die Spawn-Position Y wird also der Kamera Rect entsprechen. Punktposition, Punkt, Y. Abzüglich des Offsets. Abzüglich des Offsets Wir subtrahieren also den Offset denn wenn Sie einen Y-Wert subtrahieren, gehen Sie auf dem Bildschirm nach oben Wir haben also die Y-Position, die die Oberseite unseres Rechtecks ist Also, lassen Sie mich hier Farbe holen. Die Y-Position ist hier oben, richtig? Genauer gesagt wäre es der Y-Wert , der uns zum 00-Punkt auf dem Rechteck bringt. Dann nehmen Sie den Offset , der hier oben ein zufälliger Wert sein wird. Unser Feind wird also, , in diesem Bereich spawnen, grob gesagt , in diesem Bereich spawnen, und das hängt davon ab, wie hoch der Y-Offset zufällig generiert wurde Wir haben also unseren Rand von zehn Pixeln und dann haben wir 110 Pixel hier oben als zusätzlichen Plus-Randbereich, und dann können unsere Feinde irgendwo darin spawnen, um den höchsten Wert zu Okay, hoffentlich macht das Sinn. Und dann machen wir einfach dasselbe für alle anderen Kanten. Also Kantenpunkt unten. Also genau diese Reihe wird hier oben sein. Und dann wird die Spannposition Y etwas anders sein. Wir wollen also, dass der Spawnpositionspunkt Y dem Kamera-Rect-Punkt-Positionspunkt Y plus dem Punkt Y der Kamera-Recht-Punktgröße entspricht Kamera-Rect-Punkt-Positionspunkt Y plus dem Punkt Y . Damit erreichen wir den unteren Rand des Rechtecks Denn jetzt fügen wir die Y-Größe hinzu, wodurch wir in diesen unteren Bereich herunterziehen Und dann fügen wir einfach den Offset hinzu. Also plus Offset und beachten Sie, dass wir den Offset hinzufügen , weil wir weiter unter die Kamerabox gehen wollen , aber oben subtrahieren wir den Offset Das ist sehr wichtig. Jetzt machen wir einfach dasselbe mit links und rechts. Also Kantenpunkt links, was unsere beiden Enumerationen Und das bedeutet, dass der Spawn-Positionspunkt X gleich ist, Kamera-Recht-Punkt-Positionspunkt Y abzüglich des Offsets, weil wir unserer Box nach links gehen, also wollen wir einen Offset nach Das ist es für die Spa-Position X, und es ist Spa-POS, nicht Spa-Position. Das habe ich abgekürzt Also, Spa-Post Y wird jetzt gleich sein, und wir nehmen einen zufälligen F-Bereich zwischen dem Kamerarechteck, Punkt Y. Das wird also der obere Rand unserer Box sein Und dann wird die andere Seite des Zufalls der Boden unserer Box sein Das sind dann Kamerawrack-Punkt-Positionspunkt Y plus Kamerawrack-Punktgröße Punkt Y. Wenn wir also die Größe noch einmal hinzufügen , gehen wir nach unten Unsere vertikale Spannweite für links und rechts befindet sich also irgendwo auf dieser Linie Und dann, endlich, Randpunkt rechts, alles in Großbuchstaben. Es wird die Spannposition X der Kamera haben . Rechtes Punktpositionspunkt X plus Kamera, wir haben die Größe des Punkts X plus den Offset. Also dasselbe. Wir haben hier eine Kiste und hier eine Kiste, und wir wollen sie nach rechts oder links verschieben, wenn wir links oder rechts spawnen Lassen Sie mich das noch einmal überprüfen . Okay, Position X plus Größe Punkt X plus Offset. Okay, das sieht richtig aus. Natürlich werden wir es im Spiel testen. Und dann sollte die Spannposition Y dieselbe sein, weil wir es immer noch mit dieser Vertikalen zu tun haben, die einen zufälligen Punkt zwischen hier und hier und hier und hier für eine für die linke und rechte Generation auswählt und hier und hier für eine . Okay, das sollte also im Grunde unser Span-Positionscode sein. Und dann wollen wir die Span-Position zurückgeben. Diese Funktion ist also in Ordnung, so wie sie ist. Es ist nicht so schlimm. Wenn es ein bisschen größer würde, würde ich es wahrscheinlich einfach für eine andere Funktion verwenden. Ehrlich gesagt könnten wir das, weil ich das Bedürfnis verspürte , diesen Kommentar in den Code aufzunehmen. Also, wenn ich wollte, könnten wir sagen Funktion, Unterstrich, Final Spawn berechnen, was als Vektor zwei zurückgibt Und dann fügen wir das hier anstatt es standardmäßig auf Vektor zwei zu setzen und das alles Und wir reduzieren das auf unsere neuen Funktionen, also refraktorieren wir es Und dann benötigen wir natürlich einige Parameter, damit diese Funktion funktioniert Also zuerst brauchen wir, sagen wir, Camera Rect, was ein Rechteck zwei ist, und dann brauchen wir Kameragröße, das ist ein Vektor zwei Control S. Und dann wollen wir die Position des Sohnes innerhalb von hier zurückgeben. Die Var-Spawn-Position ist also eine Art von Vektor zwei. Wir gehen nach unten und bringen die Spa-Position von hier zurück Okay? Hier oben wollen wir diese Parameter übergeben, also Camera Rect und Kameragröße. Und dann brauchen wir das hier drüben. Schließlich brauchen wir auch den Offset. Also gib den Offset hier oben ein. Okay. Und dann brauchen wir Offset als Parameter. Also Offset, und ich glaube, das war auch ein Vektor zwei. Okay? Also war Control S eigentlich nur ein Flow? Oh, es war ein Festwagen. Okay. Also ein Float in eine Richtung. Und sobald Sie diesen gespeichert haben, sollten die meisten dieser Fehler verschwinden. Also müssen wir bis zum Rand zusammenpassen und dann müssen wir zurückkehren. Wir könnten auch diesen Kantenparameter eingeben. Also Kante, was vom Typ sein wird. Wir könnten die Aufzählung hier einfach verwenden. Es sollte gut funktionieren , da Integer soweit ich weiß, einer Aufzählung einfach automatisch zugewiesen werden können Wenn wir also hier rauf gehen und dann den Rand passieren, okay, das wird hier reinkommen und es wird als Aufzählung funktionieren, was wir erwarten, dass es hier unten abgeglichen wird erwarten, dass es hier unten abgeglichen Um ein bisschen durch Aufzählungen zu gehen: Ein Enum ist im Grunde eine Liste von benannten Werten, die der Ganzzahlposition innerhalb dieser Aufzählung entsprechen Also die Null, weil dies die erste ist, ist die Nullposition Es ist also wie das erste Element in einem Array. Man könnte es sich fast so vorstellen. Und dann ist unten eins, links ist zwei und rechts ist drei. Ich denke, in einigen Sprachen können Sie einem Eenum benutzerdefinierte Integer-Werte zuweisen einem Eenum benutzerdefinierte Integer-Werte Ich weiß nicht, ob du das in GDCRip machen kannst, aber das ist im Grunde die Idee Wenn du dich nicht damit anlegst, dann ist Null einfach top. Eins ist gerade unten, zwei ist gerade links und drei ist genau richtig. Aber das bietet Ihnen den Vorteil , dass, wenn Sie eine Funktion wie diese erstellen, statt Null, Eins, Zwei, Drei zu sagen, was für das, was das eigentlich darstellt, sehr unklar ist , was eine Null ist? Sie können das einfach durch Edge Dot Top ersetzen, was dem Wert Null entspricht, aber für jemanden, der den Code liest, ist es viel klarer , was das eigentlich bedeuten soll Okay, lass uns sehen. Also haben wir unsere Position zum Spawn-Abrufen außerhalb der Kamera, und das hatten wir hier in zufälliger Zeitspanne Jetzt müssen wir also tatsächlich die Position für die Instanz festlegen die Position für die Instanz globale Position der Instanz wird also der Spawn-Position entsprechen Dieser Teil ist einfach. Lass uns auf Play klicken und sehen, ob es tatsächlich funktioniert. Weil das ziemlich viel Code war. Okay, unsere Charaktere erscheinen also nicht auf dem Bildschirm. Ich sehe sie von außerhalb des Bildschirms kommen. Mal sehen, oder irgendwelche, die von unten und von rechts kommen. Ich sehe nichts von oben oder links kommen, und das beunruhigt mich ein bisschen. Also werde ich sehen, ob ich sie finden kann. Okay. Und ich denke, was wir tun sollten, um das zu testen. Ich werde das Spiel jetzt beenden, also hier runter gehen und wir haben sie oben und links vermisst. Also fügen wir hier einen Breakpoint und hier einen Breakpoint hinzu. Wenn also tatsächlich Charaktere versuchen, von oben und von links zu spawnen, dann sollten sie sie treffen. Und dann können wir die Werte überprüfen , die sie tatsächlich erreichen. Also habe ich vergessen, das Spiel zu beenden, also wird es automatisch diesen Breakpoint erreichen Drücke auf Play und schau, ob wir einen von links bekommen können. Okay, da habe ich tatsächlich einen von oben kommen sehen. Okay, und einer kommt angeblich von links. Also scheint es irgendwie zu laufen, richtig. Vielleicht ist es mit Sicherheit einfacher zu erkennen, wenn ich die Spawnrate ein bisschen erhöhe Also lass uns in die Welt gehen. Haben wir das Schraubenschlüsselsystem? Ich nehme das gleich hier . Ich werde mir den Wert merken. Also waren es 0,66 und 1,5, und ich werde einfach hier runter fallen , damit wir im Moment sehr schnell spawnen können Moment sehr schnell spawnen Lass uns auf Play klicken und ich werde testen. Also werden wir einfach ein paar Typen sehen, die sehr schnell spawnen, oder wir sollten Und ja, okay, das sieht größtenteils richtig aus. Können wir einen Typen von unten links herholen? Weil ich will, dass das auch passiert. Okay, ja, ja, endlich, endlich. Wir haben ein paar Leute da drüben. Okay, ich denke, es funktioniert richtig. Wenn es ein Problem gibt, ist es möglich, dass die Mathematik nicht doppelt überprüft wurde, um richtig zu sein, aber ich denke, es läuft so, wie es sollte. Wenn nicht, ist es etwas schwer zu sagen. Aber ja, ich sehe sie aus allen Richtungen kommen . Also ich denke, wir sind gut hier. Diese Mathematik wäre allerdings leicht falsch zu machen, also werde ich sie noch einmal auf den Bildschirm bringen, falls Sie das noch einmal überprüfen müssen. Wir haben also unsere Spawn-Position. Wir bekommen das von der G-Spawn-Position außerhalb der Kamera. Das ist unsere Funktion genau hier. Wir ermitteln also die Kamerazentrale aus der globalen Kameraposition, die Kameragröße ergibt sich aus der Größe des Darstellungsfensters, und dann dividieren Sie das durch den Kamerazoom Das Kamerarechteck wird aus der Kamerazentrale minus der Kameragröße multipliziert mit 0,5 berechnet, und der Y-Wert dafür entspricht nur der Kameragröße Die Kante ist eine zufällige Ganzzahl, und Sie erhalten den Rest von Vier, was Ihnen Null bis Drei ergibt. Der Offset entspricht dem Randbereich der Spanne plus dem zufälligen F multipliziert mit dem zusätzlichen Bereich der Spanne. Das ist also irgendwo 0-1 Punkt mit Dezimalstellen, und dann fügen wir den zusätzlichen Bereich der Spanne als einen gewissen Prozentsatz davon Berechne die endgültige Spanne anhand all dieser Eigenschaften, wir haben gerade den Kamerarecut, die Kameragröße, den Offset und die Kante eingerichtet die Kameragröße, den Offset und die Kante Also nehmen wir das hier mit hinein. Wir passen am Rande zusammen. Also Null, Eins, Zwei und Drei. Und dann erstellen wir für den X-Wert oben und unten einen zufälligen Bereich zwischen der linken und der rechten Seite. Mit dieser Mathematik. Für die Y-Position nehmen wir die Y-Position oben und subtrahieren dann den Offset oder für die untere Position addieren wir die Größe, um nach unten zu gelangen, und fügen dann den Offset Und dann machen wir für links und rechts dasselbe in umgekehrter Reihenfolge Für X machen wir also die linke Seite abzüglich des Offsets, sodass wir weiter nach links gelangen. Und dann fügen wir für die rechte Seite die Größe zur Position X hinzu, um die rechte Seite zu erhalten, und dann fügen wir den Offset , um von dort aus weiter nach rechts zu gehen. Dann erstellen wir für die Spannposition Y einen zufälligen Bereich zwischen der Position, die die Y-Nullposition ist, und der Position plus Größe, wodurch wir die Position der unteren Ecke auf der Y-Achse erhalten. macht es so, dass das linke und rechte Spa irgendwo zwischen dem oberen Teil unseres Bildschirms vertikal und dem unteren Teil unseres Bildschirms vertikal liegen. Aber die Position ist vom Bildschirm entfernt, sodass wir sie nicht wirklich spawnen sehen werden. Und wir haben die Span-Position zurückgegeben , damit wir sie in dieser anderen Funktion verwenden können, und damit ist das Ganze quasi abgeschlossen 25. P24 Zufällige Gegnerspawnung mit Gewichts- und Zeitbedingungen: Unser Spawnen außerhalb des Bildschirms funktioniert im Wesentlichen. Es gibt ein paar Dinge, die ich bereinigen möchte, und dann fügen wir einen Skelettfeind hinzu , sodass wir Wartesystems zufällig auswählen können , welchen Feind wir anhand eines Wartesystems zufällig auswählen können , welchen Feind wir spawnen Also lasst uns das Spiel beenden. Und zuallererst können wir dieses Label hier sehen, die schwebende Kampftext-Instanz. Das brauchen wir nicht mehr, weil wir mit der Bearbeitung der Animation fertig sind. Also werde ich diesen Knoten löschen. Und dann habe ich auf dem Spawnsystem zur Demonstration den Wert deutlich niedriger gewählt als zuvor Also hier beim ersten Punkt, ich wollte das auf das Original zurückbringen, was, ich glaube, ursprünglich waren es 0,66 Sekunden und dann 1,5 Ich mache das auf 0 Sekunden und dann 1,5 Sekunden als Spawnzeit. Also können wir einfach hier runtergehen und 1,50 eingeben. Eingabetaste, wenn Sie bei der Konfiguration präzise sein möchten, und Sie können sehen, dass der Punkt, solange er ausgewählt ist, 0 Sekunden und dann 1,5 Sekunden als Spawnzeit anzeigt und dann 1,5 Sekunden als Spawnzeit 0 Sekunden ist hier die verstrichene Zeit, wenn du dich erinnerst. Ich denke, diese vier Arbeitsfeinde könnten wir einfach vom Tatort entfernen Also werde ich sie löschen. Also werde ich sie auswählen und auf Okay klicken. Du kannst auf Play klicken, nur um zu testen, ob alles noch funktioniert, und wir sollten dafür sorgen, dass die Feinde aus dem Bildschirm erscheinen, auf uns zukommen Wir haben nicht, dass du auf Play klicken kannst, wenn du noch einmal nachschauen und sichergehen willst einmal nachschauen und sichergehen , dass die Gegner immer noch spawnen Wir brauchen diese ersten Feinde einfach nicht , weil die Feinde erst kommen, wenn , weil die Feinde erst kommen, das Spiel beginnt Wir wollen dem Spieler ein paar Sekunden geben, um sich, du weißt schon, mit der Steuerung usw. vertraut zu Okay, um den Skelettfeind zu erschaffen, klonen wir zuerst den Ork in mir Also werde ich nach Ork und dem Projekt suchen. Wir gehen runter zu Orc Dot TCN. Ich werde mit der rechten Maustaste klicken und es klonen, also duplizieren. Ich nenne es Skeleton Dot TCN. Und dann suchen wir das Projekt nach der Skelett-Szene , die wir gerade erstellt Doppelklicken Sie darauf. Und dann zoomen wir hier rein. Also werde ich das Sprite hier nehmen und es in das Skelett-Sprite umwandeln Also lass uns schnell nach rechts laden und wir werden nach einem Idol suchen, und da sollte es eines für und da sollte es eines für Wir müssen vielleicht ein bisschen heranzoomen. Für einen Skelettfeind sollte es hier einen geben. Und dann können wir oben rechts schnell laden, und du musst vielleicht ein bisschen hineinzoomen, um es zu finden, aber gib Idle ein und wir suchen nach dem Skeleton-Spritesheet Es ist vielleicht etwas schwer zu erkennen, aber ich werde dieses hier auswählen Wenn Sie es nicht finden können, können Sie einfach im Dateisystem navigieren und es finden. Es befindet sich wahrscheinlich im Skeleton Base-Ordner. Okay, lassen Sie uns jetzt den Stammknoten in Skeleton umbenennen. Und wir müssen den Animations-Player so einrichten , dass er die Animationen von Idle Skeleton und dann auch Ron Skeleton und Skeleton Death abspielt Animationen von Idle Skeleton und dann auch Ron Skeleton . Gehen wir also zum Animations-Player. Und dann unten rechts müssen wir im Grunde die Textur für jeden von ihnen ändern. Die Reset-Textur wird also nach oben rechts verschoben und dann wird das Idle-Spritesheet, das wir gerade ausgewählt haben, schnell geladen Im Moment ist es bereits vorausgewählt, also können wir es auswählen Und vielleicht möchtest du spielen und sicherstellen , dass es aktiviert ist, auf das Skelett zurücksetzen und dann auch die Textur für die anderen Animationen ändern. Also im Leerlauf klicken wir auf Textur und gehen nach oben rechts. Schnelles Laden, wähle das Spritesheet zum dritten Mal aus. Okay, und klicken Sie auf Play. Und dann stellen Sie sicher, dass das korrekt abgespielt wird. Sieht gut aus. Gehen wir zur Todesanimation. Wählen Sie hier die Textur aus. Und weil es oben rechts viele Frames gibt, ist es etwas schwierig zu erkennen, was vor sich geht, noch schwieriger als bei der Animation im Leerlauf. Ich denke also, es wäre einfacher, einfach zur Grafik zu navigieren und dann Pixel Crawler Free Pack, Entity, Mobs, Skeleton Crew, Base Death zu finden Mobs, Skeleton Crew, Base Death und dann das Todesblatt einfach so nach oben rechts zu ziehen so nach oben rechts zu Okay, drücke auf Play und vergewissere dich , dass es richtig abgespielt wird Es scheint also, als ob es hier acht Animationsbilder gibt. Also müssen wir ein bisschen heranzoomen und sicherstellen , dass H-Frames oben rechts auf acht gesetzt werden. Okay, dann klicken Sie auf Play. Ja. Okay, das sieht richtig aus Und jetzt müssen wir den siebten und achten Keyframe hinzufügen den siebten und achten Keyframe Also klicken Sie mit der rechten Maustaste auf das Bild nach 0,6 Sekunden und drücken Sie die Taste einfügen, klicken Sie darauf, gehen Sie nach oben rechts, ändern Sie es auf sechs, machen Sie dasselbe bei 0,7 Du kannst dort nicht einrasten, weil wir die Animation erweitern müssen. Machen Sie die Animation also 0,8 Sekunden lang. Klicken Sie auf 0,7, S, den Keyframe und ändern Sie ihn auf sieben, damit die achte Position ist, was wir wollen. Okay, lass uns auf Play klicken Spiel noch einmal. Da ist unsere Animation. Jetzt verschiebe ich den Todeszustand beendet nach 0,8 Sekunden bis zum Ende, und da ist unsere Todesanimation. Okay, wir wollen also weglaufen. Sollte schneller sein. Klicke auf Textur. Und dann unten links, wo Skeleton Base steht, wählen Sie den Run-Ordner, das Runsheet oben rechts. Wirf das rein. Drücken Sie auf Play und wir können sehen, dass unsere Laufanimation abgespielt wird. Es hat dieselben Altersstufen, das ist also alles, was wir ändern müssen. Okay, das sind die Grundlagen unseres Skeletts. Wir können zum Stat-Controller gehen. Abgesehen von der Zuweisung von Statistiken ist es wie Laufgeschwindigkeit und HP usw. für unser Skelett und benutzerdefinierte Werte für unsere Orks und CD, das ist die Grundkonfiguration für unsere beiden Charaktere Gehen wir also zurück in die Welt, und dann werden wir das Spawner-System haben , richtig? Also haben wir unsere zufälligen Definitionen hier auf der rechten Seite. Wir wollen eine weitere zufällige Definition hinzufügen, und dann werden wir eine neue erstellen. Also neue Spawn-Definition. Nehmen wir an, das Skelett wiegt 0,5, also bekommen wir halb so viele Skelette wie Orks Und lassen Sie uns schnell die Skelett-Szene laden, okay? Und dann schauen wir uns einfach das Skript des Sponsorensystems an. Also öffne das und wir werden die zufällige Auswahl hier sehen. Im Moment generiert es also nicht die Szene mit der Zufallsauswahl. Es wird nur die erste im Array ausgewählt. Also brauchen wir entweder ein bisschen Code oder eine Funktion, um auszuwählen, welche Szene wir tatsächlich instanzieren wollen. Lassen Sie uns die Ansicht vergrößern, und ich werde sagen var-Szene eine vollgepackte Szene ist, und wir werden den zufälligen Spawn aus einer Liste von zufällig auswählbaren Definitionen auswählen wollen den zufälligen Spawn aus einer Liste von zufällig auswählbaren Also sagen wir zufällige Definitionen, speichern Sie sich das. Und dann müssen wir diese Select Random Spawn Funktion erstellen diese Select Random Spawn Funktion Also mache ich Function, Control V, um es einzufügen Und dann werden wir sagen, dass P-Definitionen ein Array von sind, lassen Sie uns sehen, wie sie es als Spawn-Definition bezeichnen Und wir werden eine einzige vollgepackte Szene zurückgeben. Wenn die P-Definitionen also leer sind, können wir Null zurückgeben , weil es nichts zur Auswahl gibt. Andernfalls berechnen wir anhand aller Gesamtgewichte und generieren dann nach dem Zufallsprinzip einen Wert zwischen Null und dem Gesamtgewicht um zu bestimmen, welche Szene wir tatsächlich auswählen. Das ist also eine zufällige Auswahl, aber es ist eine gewichtete Zufallsauswahl. Nehmen wir an, unser Gesamtgewicht ist eine Gleitkommazahl und beginnt bei 0,0. Und dann nehmen wir für Definitionen oder D- und P-Definitionen das Gesamtgewicht und erhöhen es um das Definitionsgewicht. Okay? Also machen wir das für jede Definition. Jetzt haben wir das Gesamtgewicht und müssen einen Wert zwischen Null und dem Gesamtgewicht generieren . Nehmen wir an, der Zufallswert ist ein Float. Und wir nehmen ein zufälliges F. Das ist also Null bis eins, oh, alles inklusive, einschließlich Dezimalzahl, und es wird das Vielfache des Gesamtgewichts sein. Das gibt uns also einen Zufallswert zwischen Null und dem Gesamtgewicht. Und dann nehmen wir an, dass der Gewichtsfluss nach V gleich 0,0 ist. So viel Gewichtswert haben wir versucht zu übergeben, bevor wir den zufälligen Wert erreicht haben. Sobald wir den Zufallswert erreicht haben, geben wir die Szene oder die Definition zurück , in der wir uns gerade befinden Für die Definition in P-Definitionen werden wir also sagen, dass das markierte Gewicht plus der Definitionspunktstärke entspricht Und wenn das überprüfte Gewicht über dem Zufallswert liegt, geben wir die Szene zurück Geben Sie also den Definitionspunkt CM zurück. Okay. Und wenn wir zum Ende kommen und immer noch nichts gefunden haben, ist das ein Problem, also können wir einen Fehler melden. Okay, also hier schiebe ich einen Fehler hoch. Konnte keine Definition für den Gewichtswert in Prozent finden , wobei das geprüfte Gesamtgewicht Prozent war Und dann ersetze ich diese Prozentsätze durch den Zufallswert und das Das zeigt also, was wir überprüft haben, wo wir hingekommen sind, und es zeigt an, dass wir nicht wirklich einen Wert gefunden haben, der über dem Zufallswert lag, was immer passieren sollte, weil der Zufallswert nur das Gesamtgewicht ausmachen kann Das sollte also nicht passieren, aber wenn doch , haben wir eine Fehlermeldung. Und am Ende können wir einfach return null sagen, weil es keine richtige Definition finden konnte. Das macht also am meisten Sinn. Es wird wahrscheinlich sofort etwas kaputt machen , was darauf hindeutet, dass bei dieser Funktion etwas mathematisch repariert werden muss . Ich möchte noch einmal betonen, dass dies niemals passieren sollte. Wenn unsere Mathematik korrekt ist. Okay, also wählen wir den zufälligen Spawn aus unserer Definitionsliste aus, und das kümmert sich um das Gewicht und die zufälligen Berechnungen Also, wenn ich das Spiel jetzt so laufen lasse, wie die Dinge sind, dann sollten wir dann sollten wir halb so viele Skelette haben wie Orks Aber lass uns sehen. Bekommen wir beide? Weil wir beide bekommen sollten. Wir haben also ein paar Orks, die laichen. Okay, es stellte sich also heraus, dass der Code für ausgewählte zufällige Spawns einwandfrei funktionierte für ausgewählte zufällige Spawns einwandfrei funktionierte Ich habe nur vergessen, die Szene zu benutzen. Also wollen wir die Szene hier aufnehmen. Und statt Random Definition Zero Instanziate verwenden wir einfach Send Instantiate . Okay, jetzt können wir zurück zum zufälligen Spawn gehen und die Prince-Debug-Nachricht entfernen Okay? Und wenn wir spielen, sollte es gut funktionieren. Es sollte eigentlich den verwenden, den wir zufällig ausgewählt haben, immer den ersten im Array. Wir sollten also halb so viele Skelette wie Orks haben, aber da ist Und mit der Zeit wirst du wegen der Wartezeit eine Menge mehr Orks und dann Skelette sehen wirst du wegen der Wartezeit eine Menge mehr Orks und dann Skelette sehen. Okay, das ist also Und das ist im Grunde die Idee dort. Okay, als letztes für diesen Teil, vielleicht möchtest du verschieben, wie lange es dauert, bis eine Feinddefinition tatsächlich im Spiel erscheinen kann Zum Beispiel hast du zu Beginn vielleicht nur Orks, aber nach einer Weile kannst du Skelette hinzufügen Wir haben also schon die verstrichene Zeit. Wenn wir also eine Start - und Endzeit in Bezug auf die verstrichene Zeit sagen , in der eine Definition erzeugt werden kann, dann können wir kontrollieren, wann die Orks spawnen können und wann die Skelette spawnen können spawnen Wenn ich also zur Spawn-Definition übergehe, können wir hier eine Export-Variable oder die Startzeit einen Float hinzufügen können wir hier eine Export-Variable oder die Startzeit einen Float hinzufügen, und dieser Wert kann standardmäßig 0,0 sein. Und dann wird die Endzeit auch standardmäßig auf 0,0 gesetzt. Was wir also mit diesen beiden machen wollen, ist, eine Methode zu erstellen, die quasi erzeugt werden kann Wir könnten also sagen, dass eine Funktion erzeugt werden kann, was natürlich einen echten falschen Booleschen Wert zurückgibt Und dafür wollen wir eigentlich die verstrichene Zeit weitergeben , weil das Teil der Bedingung ist Wir müssen eher überprüfen, wie viel Uhr es im Spiel ist oder wann das Spawner-System tatsächlich erstellt wurde Und dann werden wir das verwenden, um zu überprüfen, ob die verstrichene Zeit innerhalb der Startzeit oder der Endzeit liegt der Startzeit oder der Endzeit Wenn also die abgelaufene Zeit vor der Startzeit liegt, geben wir Falsch geben Wenn die Endzeit nicht gleich 0,0 ist, oder besser gesagt, wenn die Endzeit größer als 0,0 ist, ist das meiner Meinung nach etwas einfacher zu lesen Dann wollen wir überprüfen, ob die Endzeit tatsächlich überschritten wurde. Wenn die Endzeit also Null ist, ignorieren wir sie einfach. Wenn also die verstrichene Zeit über der Endzeit liegt, geben wir Falsch zurück Andernfalls haben wir alle Bedingungen erfüllt, sodass wir true zurückgeben können Das ist also im Grunde alles, was wir für einen zeitbasierten Spawner tun müssen , und wir prüfen einfach, ob er gespawnt werden kann Und wenn er nicht gespawnt werden kann, entfernen wir ihn aus der Liste, die wir für die zufällige Auswahl Betracht ziehen Du würdest etwas sehr Ähnliches tun. Wenn Sie auch, sagen wir, eine maximale Anzahl haben wollen, bei der sie erzeugt werden können, geben Sie einfach die Zahl ein, die erzeugt wurde, und prüfen, ob sie über oder gleich der maximalen Anzahl liegt, die die Spawn-Definition zulassen würde erzeugt wurde, und prüfen, ob sie über oder gleich der maximalen Anzahl liegt, die die Spawn-Definition Das wäre hilfreich für so etwas wie einen Boss, der nur einmal spawnen kann Also kannst du einfach nachschauen, Oh, es kann einmal spawnen. Wie oft spawnt es? Ist es eins oder größer als „Spawnen Sie es nicht“. Wir werden sehen, ob wir darauf zurückkommen, aber das sollte alles sein, was wir jetzt zum Schreiben brauchen Jetzt, zurück im Spawner-System, wollen wir Spawnb im Grunde genommen aus den zufälligen Definitionen herausfiltern im Grunde genommen aus Also werde ich einen Funktionsfilter spawnb erstellen , der eine Reihe von Definitionen mit P-Definitionen verwendet, und das ist Reihe von Definitionen mit P-Definitionen verwendet Waffe. Das ist eine Spawning-Definition Und dann werden wir unsere gefilterten Definitionen zurückgeben. Geben Sie also ein Array mit Spawn-Definitionen zurück. Also erstellen wir hier unsere gefilterte Liste. Var hat ein Array von Spawning-Definitionen gefiltert, und das entspricht einem leeren Array Und dann werden wir für DF - und P-Definitionen prüfen, ob DEF erzeugt werden kann Ich schätze, wir brauchen hier die verstrichene Zeit, aber das ist Also können wir es einfach direkt daran weitergeben. Also verstrichene Zeit, weil wir sie nicht als Parameter für diese Funktion angeben müssen , weil sie Teil des Zustands des Objekts ist, nämlich des Spawnsystems Wenn es also erzeugt werden kann, fügen wir es der gefilterten Liste hinzu Also gefilterte Punktstift-Definition. Und am Ende geben wir einfach gefiltert zurück, also hier in zufälliger Spanne, wir machen var spanable und das entspricht filter spanable , der unsere zufälligen Definitionen als Parameter verwendet Und anstatt zufälligen Spawn aus zufälligen Definitionen auszuwählen , wählen wir zufälligen Spawn aus unserer gefilterten spanable-Variablen aus unserer Okay, das gibt uns im Spawner-System die Fähigkeit, wenn wir zu den Spawning-Definitionen übergehen, können wir Startzeit, Endzeit sagen Sagen wir einfach, Orks sind immer aktiv. Aber was das Spawnen von Skeletten angeht, können wir Skelette erst nach 15 Sekunden spawnen, aber sobald wir Skelette spawnen können, haben wir ein Gewicht von zwei, sodass wir am Ende viele Skelette sehen viele Skelette Dann können wir spielen. Und wenn die Mathematik stimmt, sollten wir zunächst nichts als Orks sehen Aber dann, nach 15 Sekunden, könnte es hilfreich sein, die Spielzeit zu beenden oder so, um zu sehen , ob wir das brauchen Dann, nach 15 Sekunden, können wir sehen, dass die Skelette anfangen zu spawnen, weil sie jetzt spanbar sein dürfen, weil die Startzeit von 15 Okay, jetzt kannst du sehen, wie die Skelette reinkommen. Also haben wir unsere zweite Welle von Feinden, und wir könnten die Skelette einfach härter machen Der Schwierigkeitsgrad nimmt also im Laufe des Spiels zu, weil wir stärkere Gegner hinzufügen Und natürlich erhöhen wir im Spawnsystem auch die Spawn-Rate auf diese Weise Du kannst dir also irgendwie vorstellen, wie das funktionieren würde. Das liegt in der Natur der Kontrolle des zufälligen Spawnens unseres Spawnsystems. Das ist das meiste, was wir hier tatsächlich brauchen. Gute Arbeit, mit allem bisher Schritt zu halten. Okay, wir könnten später hier und da ein paar Optimierungen vornehmen, wenn wir es brauchen, aber in den meisten Fällen ist das unser Spawner-System Also sollten wir jetzt anfangen den Kampf ein bisschen mehr zu konkretisieren und dafür zu sorgen, dass unsere Feinde unseren Spielern tatsächlich Schaden zufügen können wäre ein gutes nächstes Video. Lassen Sie uns also von dort aus weitermachen 26. P25 Player Hurtbox und Enemy Hitbox einrichten: Ein Teil unserer grundlegenden Kampfmechaniken wird darin Feinden die Fähigkeit zu geben, unseren Spieler zu treffen bestehen, den Feinden die Fähigkeit zu geben, unseren Spieler zu treffen. Dazu gehört auch die Einrichtung einer Trefferbox für die Feinde, wenn sie auf den Spieler treffen, und wir müssen sicherstellen, dass der Spieler auch eine Hurt-Box hat Und wir werden wahrscheinlich eine Unbesiegbarkeitszeit hinzufügen , nur um sicherzugehen, dass wir nicht zu viele Treffer bekommen, wenn wir von so einem Feind gemobbt werden Okay, also auf unserem Spieler, wir werden unsere Hurt-Box-Knoten erstellen. Also klicke ich mit der rechten Maustaste auf die Spielerroute, füge einen untergeordneten Knoten und lass uns nach HRT Box zwei D suchen. Enter, füge ihn hinzu. Wir weisen unserem Spieler den Statistik-Controller zu , den wir noch nicht hinzugefügt haben, sodass wir mit der rechten Maustaste auf den Spieler klicken und einen untergeordneten Knoten, den Stat-Controller, hinzufügen können . Okay. Und dann wollen wir ein paar Aufgaben erledigen. Objekt für den SAT-Controller wird also der Player-Root sein. Und dann wollen wir in der HRT-Box den Stat-Controller zuweisen. Also unsere HRT-Box, wie Sie am Warnschild erkennen können, benötigen wir auch eine Kollisionsform. Also lasst uns mit der rechten Maustaste darauf klicken und ihm einen untergeordneten Knoten geben. Kollisionsform zwei D. Und dann oben rechts machen wir das wahrscheinlich wie einen Kreis. Okay, es erscheint also diese Kreisform. Wir wollen das auf die Größe reduzieren, damit wir unseren Spielern Schaden zufügen können Je nachdem, wie wir es machen wollen, können wir es also etwas kleiner oder etwas größer als unsere Kollisionsform Ich werde es vorerst groß machen, und dann können wir es verkleinern, wenn wir das für die Spielbalance oder das Spielgefühl brauchen das für die Spielbalance oder das Spielgefühl Das gibt uns also bereits die Möglichkeit , dem Spieler Schaden zuzufügen Jetzt müssen wir den Feinden die Möglichkeit geben , dem Spieler Schaden zuzufügen. Also lasst uns in unserer Ork-Szene mit der rechten Maustaste auf Ork klicken, einen untergeordneten Knoten hinzufügen und Box zwei D drücken Und dann wird dafür eine Kollisionsform benötigt. Also klicken Sie mit der rechten Maustaste, fügen Sie einen untergeordneten Knoten , Kollisionsform zwei D, und dann machen wir es oben rechts zu einem Kreis, und dann verkleinern wir ihn so dass der Ork Ziele treffen kann Also mache ich es etwas größer als die Hauptkollisionsform für die eigentliche Kollision Wenn wir dann in unserer RT-Box zwei D das Skript überprüfen, können wir sehen, dass wir das Treffersignal von der Trefferbox erhalten , die auf eine RT-Box trifft. Um also Schaden anzurichten, benötigen wir tatsächlich ein anderes Skript das dem getroffenen und ausgestrahlten Signal Schaden zufügt. Vorher fügen wir jedoch die Kollisionsebenen für unsere Hit-Box und unsere Hurt-Boxen hinzu. Die Trefferbox zwei D auf der Kollisionsebene wird also der Kollisionsebene wird für die Spielerebene maskiert Also Maske der zweiten Ebene , weil das die Spielerebene ist. Für die Ebenen, auf denen diese Hüftbox existiert, können wir einfach Ebene eins ausschalten, oder wir könnten Ebene drei für Feind festlegen, wenn wir wollen. Aber ich werde „ Überwachbar“ wahrscheinlich ausschalten, weil es sich hier um ein Einweg-Hip-Box handelt Es muss nur erkennen. Wenn es eine Hip-Box findet, muss sie nicht von anderen Knoten im Spiel überwacht werden können , zumindest derzeit Gehen wir also zum Spielen und ich mache das Gegenteil für ihre Box Two D. Hier drüben schalten wir die Überwachung aus und nehmen die Kollision Wir werden die Ebene als Spieler erstellen. Das ist sehr wichtig, Ebene zwei , wir können die Maske ausschalten. Dann klicke ich hier mit der rechten Maustaste auf Hit Box zwei D und füge einen neuen Knoten hinzu, füge einen untergeordneten Knoten hinzu. Das wird ein Knoten zwei D sein. Und lassen Sie uns das in etwas wie Kollisionsangriff umbenennen . Wenn der Ork also mit dieser Trefferbox zwei D mit einem anderen Feind kollidiert , wird er allen Schaden als Kollisionsschaden anrichten Viele klassische Spiele haben solche Dinge bei denen ein Feind einfach auf dich trifft und du Schaden erleidest Also müssen wir hier mit der rechten Maustaste klicken und ein neues Skript erstellen. Also lasst uns Feinde mit Kollisionsangriffen angreifen . Ich denke , das passt. Erschaffen. Ich benenne es hier oben in Class Name Collision Attack Exportieren wir einen Verweis auf die Hit-Box. Hit Box hat also den Typ Hit Box zwei D. Und wenn die Funktion dann bereit ist, Funktion unter dem Punktestand bereit, gibt sie den Wert void zurück. Wir nehmen Hit Box und stellen eine Verbindung zum Treffersignal her. Also Punkt, Punkt verbinden, und wir werden bei Treffer eine Verbindung herstellen. Also jetzt brauchen wir, sagen wir, den AT-Export-Var-Schaden , der eine ganze Zahl sein wird. Wir können es standardmäßig auf zehn setzen. Lassen Sie uns also den Callback für den Treffer abrufen, wobei die Funktion bei einem Treffer einen Unterstrich beim Jetzt müssen Sie mit der rechten Maustaste auf Hit klicken und die Signalparameter überprüfen Wir haben hier also die Hurt-Box zwei D. Okay, damit haben wir auch Zugriff auf die Statistiken. Also, zurück zum Kollisionsangriff. Also haben wir die P-Hurt-Box, die vom Typ Hurt-Box zwei D ist. Sie wird als ungültig zurückgegeben, und dann werden wir den Spieler treffen. Okay, also weiter mit P Hurt-Box zwei D, wir wollen die P-HRT-Box nehmen und wir wollen ihr Schaden zufügen, und wir werden den Schaden weitergeben Und das ist so ziemlich alles weil wir das schon in die Verletzungskiste geschrieben Die Hurt-Box kümmert sich also bereits um die Berichterstattung. Ich kümmere mich bereits um die Einstellung der HP Dadurch wird das Signal für die Änderung der HP ausgegeben, falls wir das benötigen. Und es macht die Berechnung. Es übernimmt auch die Bewachung, um sicherzustellen, dass wir das Ziel treffen können Es macht also Sinn, dass wir diese Logik wo anwenden. Solange wir einen Kollisionsangriff haben, weisen wir die Trefferbox hier oben zu und legen unseren Schaden fest. Wir können sehen, ob das funktioniert. Also werde ich einfach versuchen, auf einen Feind zu stoßen und sehen, ob unser Spieler den darüber liegenden Schaden erleidet. Okay. Ich muss mir nur sicher sein. Oh, okay, ja. Da haben wir's. Unser Spieler wurde zehn Mal getroffen. Wir wissen, dass es der Spieler ist und nicht der Feind , weil der Speer derzeit 100 Punkte hat Derzeit scheint es ein Problem zu geben, nämlich dass ein Feind , der bereits tot ist , den Spieler immer noch treffen kann Es hat schon 100 gedauert. Ich ging in den Death State und der Kollisionsangriff war immer noch aktiviert. Also könnten wir das auf ein paar Arten handhaben. Eine wäre, dass wir einfach den Stat-Controller überprüfen und sicherstellen, dass der Stack-Controller auf dem Orc der HP, über Null ist oder der Orc noch am Leben ist Ansonsten ignorieren wir diesen Angriff einfach komplett. Das wäre ein anständiger Weg. Eine andere Möglichkeit wäre, ihn in den Todeszustand zu versetzen und dann alle Trefferboxen zu deaktivieren sobald unser Ork als tot gilt Ich denke, das ist vielleicht zu viel Verantwortung für den Todeszustand Ich denke, es gehört etwas besser hierher in den Kollisionsangriff. Also werden wir eine Referenz auf unseren Stat-Controller exportieren, V-Stat-Controller exportieren. Was wir dazu sagen werden ist, wenn nicht Stats Dot Live, dann kehren wir zurück. Sonst richten wir Schaden an. Also, solange der Charakter nicht am Leben ist , kann er nicht angreifen, aber wenn er am Leben ist, dann betrachten wir den Kollisionsschaden als gültig, wenn wir diese Verbindung herstellen. Wenn wir jetzt wieder ins Spiel kommen, können wir auf einen Feind zugehen, gerade besiegt wurde, ohne Schaden davon zu nehmen. Okay, also ich muss das richtige Timing haben. Okay, ich stoße darauf und wir sehen, dass wir es geschafft haben, aber ich habe vergessen, die Statistiken einzustellen. Also könnte es ein guter Zeitpunkt für eine Behauptung sein. Bestätigen Sie also Statistiken. Die Statistik muss also so eingestellt werden, dass wir überprüfen, ob der Charakter am Leben ist. Und dann müssen wir im Grunde schon den Hit-Box-Soda-Fehler haben, falls wir vergessen, diesen im Inspektor einzustellen. Okay, so nah dran. Klicken Sie auf Kollisionsangriff. Lassen Sie uns die Statistiken zuweisen. Lass uns ins Spiel gehen. Wir machen das noch einmal. Finde einen Ork. Und du kannst sehen , dass wir keinen Schaden erleiden, wenn der Ork bereits besiegt worden wäre, ein weiteres Mal Ja, scheint gut zu funktionieren. 27. P26 Spieler-Unbesiegbarkeit-Timer und benutzerdefinierte Statistikdefinitionen: Okay, als letztes zu diesem Video wollen wir einen Zeitraum für Sicherheitslücken einrichten, speziell für unseren Spieler Also in Stat Controller können wir hier reingehen. Im SC-Controller können wir also einen Unverwundbarkeits-Timer erstellen Sagen wir hier unten V Invincible Time und wir können Es wird vom Typ Float sein. Es ist also die Zeit nach einem Treffer , in der das Objekt nicht beschädigt werden kann. Okay, da unsere unbesiegbare Zeit standardmäßig auf Null gesetzt ist, wird das für unsere Feinde in Ordnung sein Für einen Spieler mit vier Stunden möchten wir jedoch unseren benutzerdefinierten Wert für die Zeit für Unbesiegbar haben für die Zeit für Und wir wollen wahrscheinlich auch Dinge wie HP, Geschwindigkeit, maximale HP usw. anpassen können Dinge wie HP, Geschwindigkeit, maximale HP usw. anpassen . Wir sind also wirklich an dem Punkt angelangt, an dem wir eine Art Statistikdefinition einrichten müssen, an der wir definieren können, wie die Startstatistiken für jeden Charakter aussehen werden Also, wenn wir dafür ein neues Skript erstellen könnten, das unserer Waffendefinition sehr ähnlich sieht, wo wir nur Eigenschaften über den Charakter und seinen Statistikblock definieren . Also, auf dem Foto des Charakters, in Ordnung, klicken Sie auf Neues Skript erstellen und wir nennen es Stat Underscore Definition Das geht von der Ressource aus und klickt auf Erstellen, okay? Suchen Sie dann nach dem Skript , das wir gerade Statistikdefinition erstellt haben, und doppelklicken Sie darauf. Und wir werden hier nach oben kommen. Also Klassennamen-Statistikdefinition. Das wird also Standardstatistiken für einen Objekttyp definieren. Die Statistiken, die wir wollen, werden also im Grunde das widerspiegeln, was wir auf dem Statistik-Controller haben Gehen wir also in den Statistik-Controller und ich kopiere sie für den Moment einfach in unsere Statistikdefinition Ich werde diesen ganzen Setter-Code entfernen. Weil wir nur editierbare Exporteigenschaften definieren wollen , die im Grunde keinen zusätzlichen Code ausführen Es sind nur reine Daten, die im GIDOeditor gespeichert werden Wir brauchen also kein Alive, und wir werden einen Standard für HP und FenciBT HP und MAX HP wollen HP und FenciBT HP und MAX HP Also lassen Sie uns all das beim Export für MaxHP beim Export für HP exportieren Hier machen wir den Export aus Gründen der Geschwindigkeit und den Export aus Gründen der Unbesiegbarkeit Vielleicht möchtest du ihnen auch ein paar Kommentare geben. Also MaxHP maximale Integrität für das Objekt, HP, Startzustand für das aktuelle Objekt Okay, und das wird es sein. Jetzt brauchen wir also eine Möglichkeit unsere Statistikdefinition auf den Statistikcontroller zu laden. Sie könnten entweder eine Ladefunktion in die Statistikdefinition einfügen , wodurch aus der Ressource etwas mehr wird als nur Peer-Daten. Nun, wir könnten sie auf den Stat-Controller legen und eine Art initialisierte Statistikmethode verwenden, bei der sie den Statistikdefinitionstyp kennt, und dann kann sie alle Werte von einem Objekt dieses Typs laden von einem Objekt dieses Typs Also werde ich es so machen. Und das bedeutet, dass wir hier unten eine neue Funktion erstellen müssen . Da der Stat-Controller sowieso initialize für die Stat-Definition aufrufen muss , weil dies der Knoten ist, den der Knoten handhaben wird , wenn er bereit ist , sich selbst einzurichten In jedem Fall würde es also eine geringfügige Abhängigkeit von der Stat-Definition geben Also werde ich die Funktion erstellen, Statistiken einrichten und dafür wird eine P-Definition benötigt, was eine Statistikdefinition ist. Nun, gib den Typ void zurück und lass mich hier ein paar Zeilen hinzufügen. In den Setup-Statistiken werden wir die Definition also einfach auf diesen Knoten spiegeln . Max HP wird der p-Definition MxHP entsprechen . HP wird dem Punkt P mit der Definition HP entsprechen. Schauen wir uns an, welche Geschwindigkeit sonst noch der Punktgeschwindigkeit der p-Definition entspricht , und die unbesiegbare Zeit entspricht Auflösung P Definitionspunkt Unbesiegbar T. Also müssen wir das jetzt einfach auf Bereit machen Also fügen wir unter unbesiegbare Zeit die Funktion underscore ready hinzu und wir sagen, Statistiken und wir sagen Wir müssen also eine Definition auf dem Knoten exportieren , damit wir das tatsächlich tun können Also oben machen wir Export VR Stat definition is a type statdefinition. Okay. Und dann benutzen wir das einfach, sobald wir bereit sind. Richten Sie also Statistiken mit der Statistikdefinition ein. Dadurch werden alle Statistiken in unseren Laufzeitwert geladen . Auf diese Weise können wir die Werte für die Basisstatistiken unserer Charaktere anpassen die Basisstatistiken unserer Charaktere wir etwas verwenden, das wir im Editor einrichten können. Wenn wir also auf Stat Controller klicken, gehen wir nach oben rechts. Ich kann hier eine neue Statistikdefinition für unseren Oc erstellen. Und nehmen wir an, dass der Mx HP 40 und 40 sein sollte und die Geschwindigkeit 25 ist. Also speichern wir das jetzt in dem Ordner, in dem wir die Orks haben. Klicken Sie auf Statistikdefinition, speichern unter und wir können das in den Ordner des Feindes legen Also ok, Statistiken. Klingt dort nach einem perfekten Namen. Speichern Sie es. Okay, und so ist die Definition von Ok Stat. Wenn es also geladen wird, wird es mit diesen Werten geladen , sobald der Charakter bereit ist. Okay, das ist im Grunde das für den Ork. Jetzt möchte ich auch dieses Hitbox-Setup auf das Skelett kopieren auf das Skelett Also gehe ich zu Control C, gehe zu Skeleton, Control V, füge es ein. Ich nehme den Kollisionsangriff und erhöhe den Schaden einfach auf, sagen wir, 25. Lassen Sie uns die Statistiken dem Statistik-Controller zuweisen, und wenn die Kollisionsform dieselbe ist, funktioniert das einwandfrei. Verwendet dieselben Kollisionsebenen. Es ist Stein in mir, wenn ich versuche, den Spieler zu treffen. Also alles andere ist eingerichtet und in Ordnung. Und dann müssen wir den Stat Controller einrichten. Also Stat Controller hier, geh nach oben oder rechts. Und erstelle eine neue Statistikdefinition. Nehmen wir an, das Skelett hat eher 50 Lebenspunkte , 50 Lebenspunkte , eine Geschwindigkeit von 40 ist in Ordnung. Also klicken wir mit der rechten Maustaste auf Speichern unter und sagen Skeleton Stats Dot TRS, Save. Jetzt müssen wir das für den Spieler erledigen. Gehe zum Spieler, klicke auf den Statistik-Controller, gehe nach oben rechts und mache eine neue Statistikdefinition. Nun, hier will ich uns in der unbesiegbaren Zeit haben. Nehmen wir an, ein Charakter ist 0,2 Sekunden lang unbesiegbar, nachdem 0,2 Sekunden lang Wir geben dem Charakter eine Grundgeschwindigkeit von, sagen wir, 100 und die maximale HP hat Ich denke, das lasse ich als Anfang stehen. Klicken Sie also mit der rechten Maustaste auf die Statistikdefinition. Speichern unter, und wir speichern das im Player-Ordner. Spieler tippen auf TRS, klicken Sie auf Speichern. Und jetzt sollten die Charaktere jeweils unterschiedliche Statistiken haben. Das Letzte, was wir tun müssen, ist den Unbesiegbarkeits-Timer zu verwenden Auf St Controller müssen wir Invincible also mit einem Methodenaufruf auslösen Lassen Sie uns hier also einen Funktionssatz Invincible erstellen , , Und dann haben wir eine lokale Variable dafür, ob sie unbesiegbar ist oder Die Variable invincible ist also ein boolescher Wert. Dies wird standardmäßig auf False gesetzt. Wenn der Wert wahr ist, kann das Objekt keinen Schaden nehmen. Okay, also für kann getroffen werden, wir wollen sagen, dass der Charakter am Leben ist und nicht unbesiegbar Also verwende ich das mit den Schlüsselwörtern und nicht mit dem Logiksymbol Ich denke, es macht es gewissermaßen ein bisschen einfacher zu lesen. Wenn der Charakter also lebt und nicht unbesiegbar ist, kann er getroffen werden Und wir wollen, dass unbesiegbar gleich wahr ist, aber wir wollen hier auch Und wir werden sagen, das entspricht einem neuen Timer, entspricht einem neuen Timer-Punkt . Und dann fügen wir das als Kind zu diesem Objekt hinzu, den Invincibility Timer, und wir stellen eine Verbindung zu Also Invincibility Timer, Punkt Timeout, Punkt Verbindung zu Invincible Timeout . Also Control sieh dir das an und füge es hier ein. Funktion bei Timeout für Unbesiegbarkeit. Diese Ouvertüre und Leere. Und wir werden sagen, dass unbesiegbar gleich falsch ist. Okay, jetzt müssen wir den Timer starten. Zeit der Unbesiegbarkeit oder Start, und wir sagen, dass die Zeit die unbesiegbare Zeit ist Das sollte die Logik regeln, ob wir treffen können oder nicht, weil der Charakter unbesiegbar ist Okay, also für Set Unbesiegbar könnten wir überprüfen, wenn HP gesetzt ist, dass wir die Unbesiegbarkeit auslösen wollen, wenn die HP fallen wir die Unbesiegbarkeit auslösen wollen Aber ich denke, was unsere Absicht verdeutlichen könnte, ist, eine Take-Damage-Funktion in dieser Definition eine Take-Damage-Funktion Also könnten wir so etwas wie eine Funktion machen , Schaden nehmen und lassen Sie uns hier als P-Schaden t übergeben. Wir tippen und stornieren, und das wird HP nehmen und es auf P-Schaden setzen. Und dann wollen wir den Charakter auf unbesiegbar setzen. Wir könnten sogar sagen, wenn die unbesiegbare Zeit größer als 0,0 ist, dann setzen wir An diesem Objekt. Und die HP werden hier tatsächlich minus gleich dem Schaden sein, weil wir ihren aktuellen Wert nehmen und ihn aktualisieren wollen. Das bedeutet also immer noch, dass Live gleich ist, dass HP hier größer als Null Wenn du es willst, könntest du get live sogar zu einer Funktion machen , die das überprüft, was auch in Ordnung wäre, anstatt dieses vorherige Setup zu machen Aber das hatten wir schon. Es funktioniert gut. Das machen wir. Also, wann immer wir Schaden verursachen, wollen wir auf dem Stack-Controller wirklich Take Damage nennen . Lassen Sie uns also herausfinden, wo wir Schaden anrichten, so wie es das Projektil haben könnte Okay, hier können wir sehen, dass alles auf die Rt-Box zurückgeht Also lass uns mit der rechten Maustaste klicken und loslegen. Und anstatt die HP direkt einzustellen, sagen wir, dass der Stat-Controller Schaden und wir geben den P-Schaden weiter. Wir können also diese Zeile wegschneiden und brauchen sie eigentlich nicht zu berechnen , weil diese Berechnung automatisch im Stat-Controller durchgeführt wird . Das verdeutlicht eher unseren Standpunkt , dass, wenn unser Statistikcontroller Schaden erleidet, er möglicherweise andere Dinge tut, wie zum Beispiel den Charakter unbesiegbar zu machen, weil unser Charakter Schaden erlitten hat Es geht nicht nur darum, dass wir den HP-Wert geändert haben. Es geht insbesondere darum, dass wir Schaden aus einer beschädigten Quelle erlitten haben. Okay, lass uns auf Play klicken und sehen, ob alles zusammenpasst. Wir müssen Schaden von einigen Feinden einstecken, und dann werden wir sicherstellen wollen , dass wir tatsächlich nur einmal alle Viertelsekunde Schaden erleiden können . Wenn ich also hier drüben schieße, brauchen wir noch ein paar Gegner, damit das funktioniert. Es könnte sogar einfacher sein, wenn ich die Projektile deaktiviere. Okay, also ich werde diese Typen treffen. Ich sollte nur einmal sehen, dass ein Schaden entsteht. Okay, 25. Ich glaube, es funktioniert. Wenn ich all diese Dinge durchgehe. Ich sehe nur einmal, dass Schäden auftreten. Aber für VLC muss ich auf jeden Fall das Projektil ausschalten Also werde ich die Speerwaffe vorübergehend aus der Szene hier drüben löschen Speerwaffe vorübergehend aus der Szene . Das musst du nicht tun Das führe ich nur vor. Okay, dann gehe ich einfach weiter zu den Feinden. Okay, wir werden also nur einmal beschädigt. Also, dieses Ding, das von einer Kollision getroffen wurde, tritt nur auf, wenn man das Gebiet betritt Wenn wir also auf dem Feind stehen, wir immer noch nur einmal getroffen Okay? Okay, obwohl uns ein Haufen Typen schlagen, werden wir nur einmal alle Viertelsekunden getroffen , oder so. Und unsere Charaktere sind schon fertig, also können wir nicht noch mehr getroffen werden. 28. P27 Periodischen Schaden für gegnerische Hitboxen implementieren: Behebt das Problem, dass die HIP-Box nur einmal nach einem anderen Bereich Schaden zufügen kann einmal nach einem anderen Bereich Schaden zufügen Das HipXTD betritt dieses Trefferfeld, aber nicht, wenn es darin verharrt Wir können einen Timer in unserer Hüftbox auf D stellen, um ständig zu überprüfen, ob sich die HIP-Box noch innerhalb des Bereichs befindet, und dann können wir ihr regelmäßig Schaden zufügen Okay, sobald wir den Treffer ausgegeben haben, kann ich ihn auch zu den Bereichen des Trakts und dem Drehbuch hinzufügen. Sagen wir also var targets, das wird ein Array von Hurt-Box zwei D sein , was momentan nichts ist. Und wir werden sagen, dass wir nach dem Treffer Ziele anhängen, den P-Bereich Okay, jetzt müssen wir uns mit dem Signal im linken Bereich verbinden . Also Gebiet verlassen, Punkt verbinden. Und wir werden den Rückruf bei Verlassen des Gebiets verwenden. Okay. Also funktioniere in dem Bereich, der verlassen wurde Wir bekommen den P-Bereich. Also wollen wir überprüfen, ob es ein HIT-Feld zwei D ist. Also die Bereiche vom Typ Bereich zwei D. Okay, also wir prüfen, ob P-Bereich Hurt-Feld zwei D ist , dann fahren wir fort. Jetzt werden wir überprüfen, ob der Zielpunkt einen P-Bereich hat, dann werden wir ihn aus den Zielen löschen. Ziele löschen den P-Bereich. Okay, jetzt werden die Ziele nur noch existieren, solange sich die Ziel-Verletzungsbox in unserem Trefferbereich befindet Wir können jederzeit überprüfen, ob wir dem Feind erneut Schaden zufügen müssen Okay, wir könnten das mit etwas machen, sagen wir, wir haben einen optionalen Timer, also bei Export var timer timer, und dann stellen wir eine Verbindung zum Zeit- oder Timeout-Signal Also Timer Punkt Timeout Punkt Knect und wir sagen Okay, also setzen wir den Anruf wieder hier hin, funktionieren pünktlich Das wird wieder ungültig sein und wir werden versuchen, das Gebiet zu erreichen. der Zeit oder dem Timeout für Ziel und Ziele treffen wir also genau einen Mt. Target Wenn sich die Objekte also nach ihrem ersten Treffer immer noch im Bereich befinden , werden sie nach jeder Zeit oder Periode erneut getroffen Also gehen wir zu Ok und schauen uns unsere Trefferbox zwei D an. Okay, und vielleicht möchten wir uns etwas klarer darüber informieren, wofür dieser Timer gedacht ist. Nehmen wir an, das ist tatsächlich ein Schadenstimer, und ich werde die Eigenschaft aktualisieren, sobald ich bereit bin. Okay, jetzt zu unserem Damage Timer, wir wollen mit der rechten Maustaste auf Hipbox Two D klicken und einen Timer hinzufügen Und dafür sagen wir, dass wir etwa 0,25 Sekunden machen. Das wird autosrt sein, und dann müssen wir nur noch darauf in der Hip Box zwei D verweisen . Ich benenne es in Damage Timer um , damit die Namen auch übereinstimmen Klicken Sie also auf Hit Box Two. Weist den beschädigten Timer zu. Das wird jetzt eine Verbindung zu dem Signal innerhalb des Skripts herstellen. Und für jedes Objekt oder Ziel , das sich in dem Bereich befindet, wenn der Timer abläuft, wird das ausgelöst Und weil es sich nicht um einen Schuss handelt, wird er automatisch wiederholt Also alle 0,25 Sekunden wird es so weitermachen und jedes Mal die Ziele überprüfen Also das ist wahrscheinlich gut dort. Wir brauchen nur das Skelett, um das Gleiche zu haben. Ich werde C kontrollieren und diesen Timer auf das Skelett kopieren . Und wir fügen ihn mit Control V in die Hip-Box zwei D Weisen wir ihm in der Hit-Box zwei D zu und weisen ihm oben rechts den beschädigten Timer zu, speichern und starten. Okay, und wir können sehen, dass auf einigen der Hipbox zwei Ds speziell das Projektil, das Speed-Projektil, das hat es nicht Also müssen wir uns darüber im Klaren sein, dass wir sagen, wenn der Timer beschädigt ist, dann stellen wir eine Verbindung zu Das ist also optional, und ich habe dort einen Kommentar geschrieben , um klarzustellen , dass dieser optionale Timer nach aussendet Ablauf einer bestimmten Zeit in regelmäßigen Abständen Treffersignale an die Ziele innerhalb des Hip-Box-2-D-Bereichs Okay, lass uns nochmal rennen. Und wir werden einfach sehen, ob ein Ork uns tatsächlich zweimal Schaden zufügen kann Nun, das wird ein bisschen schwierig mit den Speeren Lassen Sie uns auch den Speer deaktivieren. Also deaktiviere die Speerwaffe oder entferne sie vorübergehend. Gehen wir zurück zur Szene. Okay, und lasst uns einen Ork finden, der uns ein paar Mal Schaden zufügt. Okay, hier haben wir unser K. Mal sehen, wie oft wir Schaden einstecken können Ja, wir können definitiv mehrmals von demselben Ork getroffen werden mehrmals von demselben Ork Und das ist wahrscheinlich zu schnell, ehrlich gesagt . Also lassen Sie uns das zusammenfassen. Zuerst steuere ich Z, um die Speerwaffe wieder einzubauen Gehen wir zum Ork und ich setze seine Gewichtszeit auf 0,5 Sekunden Und wenn es so aussieht, als ob der Spieler zu viel Schaden erleidet , wenn sich mehrere Gegner um ihn gruppieren, kannst du immer noch den Unbesiegbarkeits-Timer erhöhen, sodass die maximale Anzahl an Treffern pro Sekunde um 5-4 sinkt, je nachdem, ob du es bei 0,2 oder 0,25 Sekunden schaffst kannst du immer noch den Unbesiegbarkeits-Timer erhöhen, sodass die maximale Anzahl an Treffern pro Sekunde um 5-4 sinkt, je nachdem, ob du es bei 0,2 oder 0,25 Sekunden schaffst. Wie auch immer du das anpassen möchtest 29. Niederlage für P28-Spieler: Dem Charakter gehen die HP aus, wir müssen in den Todeszustand wechseln, und ein Teil davon wird auch darin bestehen, die Angriffe zu verhindern. Und irgendwann werden wir ein Spiel über den Bildschirm einbauen, aber lassen wir es einfach, damit vorerst das Ende des Todeszustands erreichen. Also drüben in der Spielerszene haben wir unseren Zugstatus. Wir wollen in einen Todeszustand versetzen, und ich denke, wir können einfach zur Orgszene gehen und das vielleicht sogar einfach kopieren und wiederverwenden. Wenn ich mir das Death State-Drehbuch ansehe, sehe ich darin nichts, was wirklich ein Problem wäre , außer vielleicht das Quartal hier am Ende. Vielleicht wollen wir nur ein Spielsystem darüber informieren , dass der Charakter besiegt wurde. Also kopiere ich einfach das Drehbuch. Wir gehen rüber zum Spieler. Ich werde hier drüben klicken und einen neuen Limbo-State-Node hinzufügen Nehmen wir an, der Spieler hat den Status besiegt. Also den Status „Spieler besiegt“, klicken Sie mit der rechten Maustaste, hängen Sie ein Skript und dann erstellen wir es im Spielerordner. Ich füge das ein. Wir werden den Klassennamen hier oben in den Status „Spieler besiegt“ umbenennen . Okay, lassen Sie uns den Namen der Animation überprüfen und sicherstellen , dass er im Animation-Player ist. Also der Tod des Animationsspielers, das haben wir da. Okay, das ist also in Ordnung. Wenn wir in den Todeszustand wechseln, werden wir einen Track namens Method Track zu unserem Status „ Spieler besiegt“ hinzufügen wollen . Und wenn wir hier bis zum Ende gehen, aktivieren wir auch das Snapping unten rechts, falls das hilft Wechseln Sie also zu 0.6, klicken Sie dann mit der rechten Maustaste und sortieren Sie einen Schlüssel, und wir rufen im Skript beendet auf Okay, also ich bin versucht, das bereits existierende Kampfsystem zu verwenden und dann so etwas wie eine Niederlage über den Spieler zu melden Die Niederlage eines Spielers besteht eher darin, das zurückzusetzen oder das Spiel für beendet zu erklären . Es ist also nicht wirklich eine Funktion des Kampfsystems. Um die Probleme zu trennen, werde ich vielleicht einfach einen neuen Knoten für die Verwaltung des Spiels einrichten, eventuell auch das Speichern und Laden beinhalten könnte. Wir werden sehen. Wenn wir also zur Wurzel unseres Projekts und unserer Systeme gehen, würde ich sie hier erstellen wollen. Ich klicke mit der rechten Maustaste und erstelle ein neues, sagen wir, Skript, und wir nennen es Game Manager Dot gD. Ich denke, das funktioniert als Name. Okay. Und im Game Manager belassen wir es als Node, weil wir daraus einen Auto Load Singleton machen Warum verwenden wir nicht einfach eine Funktion Report Game Over, damit sie von überall aus aufgerufen werden kann , solange wir den Game Manager referenzieren. Und wenn wir das Spiel als beendet melden, drucken wir es einfach aus, wodurch Zeichenketten auf die Konsole gedruckt werden und wir sagen, Spiel ist vorbei, Spieler besiegt. Und später würden wir das durch eine Benutzeroberfläche ersetzen, sodass wir tatsächlich zu einem neuen Spiel wechseln oder uns das Spiel über Statistiken ansehen können usw. Aber das wird zumindest zeigen, dass es funktioniert. Okay, wir wollen also den Game Manager nehmen und eine Szene erstellen , damit wir Exportvariablen bearbeiten können , falls wir sie jemals benötigen. Also werde ich schreiben, indem ich auf Systeme klicke, um eine neue Szene zu erstellen. Das wird Game Manager Dot TSCN sein. Ich klicke hier mit der rechten Maustaste ändere den Knotentyp in einen Knoten Wir ziehen das Game Manager-Skript darauf. Okay. Und dann wollen wir es speichern, gehen wir zu den Projekteinstellungen. In Globals wollen wir die TCN-Anzeige des Game Managers des Systems automatisch laden, und jetzt ist es ein global referenzierbares Game Wenn wir das also verwenden wollen, können wir einfach zu unserem Spieler zurückkehren und der Spieler hat den Status besiegt und den Status besiegt Anstatt kostenlos in der Warteschlange anzustehen, lassen wir den Charakter dort. Und wir sagen, dass Game Manager das Spiel nicht meldet, und das ist alles, was wir tun müssen Ein Grund, den Spieler nicht aus der Szene zu entfernen , ist, dass, so wie die Dinge gerade sind, alle Feinde von der Existenz des Spielers abhängig sind , damit sie sich weiterbewegen können. Sobald du also den Spieler aus der Szene entfernst, werden alle feindlichen Drehbücher kaputt gehen. Nun, wenn du das komplett ausarbeiten und zulassen willst, dass der Charakter aus der Spielszene entfernt wird, dann musst du nur im Grunde jeden Durchlauf von, sagen wir, der C-Verfolgungsszene hier überprüfen im Grunde jeden Durchlauf von, sagen wir, der . Sie müssten nur sicherstellen, dass das Ziel immer noch gültig ist, und wenn es nicht gültig ist, würden Sie einfach zurückkehren. Das könnte etwa so sein, wenn Unterstrich Ziel gleich Null ist, dann kehrst du zurück, und dann bedeutet das nur, dass es sich einfach überhaupt nicht bewegt Also, weißt du, zum Spaß könnten wir tatsächlich zum Spieler gehen und in den Zustand Spieler besiegt Wir können sogar den Agenten Dot Q Free hinzufügen und wir könnten einfach sehen, wie das funktionieren würde. Wenn ich also das Häkchen hinzufüge , dass Targets Not Null für die Verfolgungsjagd sind, wird es dann kaputt gehen oder wird es hier funktionieren? Also lass es uns versuchen. Lassen Sie uns sehen, ob unsere Feinde immer noch funktionieren können ohne dass ein Spieler auf dem Bildschirm ist. Okay, wir werden also besiegt werden. Ich habe den Übergang für Spieler HSM noch nicht eingerichtet Übergang für Spieler HSM noch nicht also in Player-HSM Lassen Sie uns also in Player-HSM eine weitere Funktion erstellen und Übergänge einrichten Okay. Also das erfordert , dass wir einen Übergang vom Status „Verschieben“ in den Status „Besiegt“ hinzufügen, und zwar für das Ereignis „Besiegt“. Okay, also lassen Sie uns diese hier oben für den Spieler HSM im Status „ Export Var Move“ definieren den Spieler HSM im Status „ Export Var Move Das ist ein Limbo-Zustand im Status Export Var besiegt, was ein Limbo-Status ist Und dann erstellen wir eine Konstante für defeated, das ist eine Zeichenfolge, die dem Namen und Anführungszeichen entspricht Okay, jetzt müssen wir unsere Variablennamen hier aktualisieren , um einen Übergang hinzuzufügen Also Schlangenhäuschen für diese Variablen. Und wir sollten eigentlich nur in der Lage sein , vom Zug zum Sieg überzugehen , weil wir keine Wiederbelebungsmechanik im Spiel haben Wiederbelebungsmechanik im Spiel Sobald wir also besiegt haben, sind die Spiele vorbei und das wird in Ordnung sein Du könntest jederzeit einen Übergang zurück hinzufügen , wenn du irgendeine Art der Wiederbelebung hast Jetzt wollen wir innerhalb des Setup-HSM Einrichtungsübergänge aufrufen , dort Übergänge einrichten und wir können den Übergang bewältigen, indem wir Verbindung zum Spielerstatistiksignal Nachdem wir also bestätigt haben, dass die Spieler nicht Null sind, wollen wir eine Verbindung zum Signal auf dem Das wird also wirklich das Signal auf dem Statistik-Controller sein das Signal auf dem Statistik-Controller Es könnte entweder direkt auf den SAT-Controller verweisen oder über den Player eine Verbindung zum Statistik-Controller herstellen, obwohl das Setup noch nicht vorhanden ist. Also ich denke, in diesem Fall wäre es ein bisschen direkter , einfach auf ein Extra bei Export VR stats of the Stat Controller zu verweisen Okay, und dann sagen wir hier unten Stats Alive changed dot Connect, und es wird auf Alive changed sein. Lassen Sie uns also diese Funktion unten erstellen und zurückrufen. Und das wird den P-Wert haben, den neuen Wert des Live-Werts Das S gibt ungültig zurück. Wenn also der Wert P gleich False ist, wollen wir das unterlegene Ereignis auslösen Okay, damit wird der Übergang vom Status „Verschieben“ in den Status „Verloren“ ausgelöst der Übergang vom Status „Verschieben“ in den , wenn wir uns im Status „Verschieben“ befinden Wenn Sie am Ende eine Reihe anderer Staaten hinzufügen, haben hier auch die Möglichkeit , einen beliebigen Status zu erstellen. Das macht es also so, dass du, wenn die Charaktere besiegt sind, von jedem Zustand aus direkt in den besiegten Zustand übergehen kannst . Das ist vielleicht besser, wenn langfristig denkt, weil man vielleicht eine Art Angriffsstatus hinzufügen würde , in dem man eine andere Animation abspielt. Du möchtest immer noch sofort zu „Besiegt“ wechseln können , anstatt einfach von „Zug“ zu „Besiegt“ zu wechseln , wenn dieser Dispatch erfolgt. Andernfalls wird der Charakter möglicherweise nie in den Todeszustand versetzt, wenn du einen Dispatch ausführst, während er sich nicht im Status „Bewegung “ befindet. Also ich denke, das wäre generell der bessere Weg, das zu tun. Okay, jetzt müssen wir alles im Inspektor zuweisen . Also weisen Sie den Statistik-Controller zu, weisen Sie den Zugstatus und weisen Sie den Besiegten 30. P29 Testen und Verbessern des Verhaltens bei Spielerniederlagen: Um es schneller zu machen, klicke ich auf Stats Controller. Nehmen wir die HP und setzen sie auf zehn, und ich drücke auf Play. Wenn unser Charakter also einmal getroffen wird, wechseln wir sofort in den Todeszustand. Okay, also lasst uns einen Ork finden. Okay, da haben wir's. Okay, also haben wir den besiegten Staat erreicht. Aber wir können sehen, dass der Agent keine Statistiken hat , weil wir das für den Charakter nicht verlangt haben. Wenn wir also einfach konsistent sein wollen, dann ja, wir können dem Spieler Statistiken hinzufügen . Ich denke, es ist okay, Statistiken anhand des Spielers zu referenzieren weil wir im Allgemeinen verstehen würden , dass der Spieler Statistiken haben wird, besonders in einem RPG-Spiel Außerdem können wir diese Geschwindigkeitsvariable gleich hier loswerden. Ich kann sehen, dass der Spieler immer noch die Geschwindigkeit aus dem Basisskript verwendet die Geschwindigkeit aus dem Basisskript anstatt die Geschwindigkeit aus den Statistiken. Also ja, lassen Sie uns einen Verweis auf at Export var stats holen, was ein Statistik-Controller ist. Okay. Und wenn wir dann Geschwindigkeit haben, wollen wir Statistiken zur Punktgeschwindigkeit verwenden. Okay? Und lassen Sie uns das kopieren und dort unten auch ersetzen. verwenden es also konsequent in unserem Physikprozess für den Spieler. Okay? Wenn wir die Statistiken und den Inspektor zuweisen, können wir das genau dort machen. Und wenn wir uns dann das HSM ansehen, brauchen wir keinen direkten Verweis mehr auf die Statistiken, weil wir ihn bereits über den Spieler haben Also können wir player.stats.ai changed machen und wir stellen eine Verbindung zum Live-Stream her, der sich dadurch Es ist einfach etwas konsistenter, was die Art und Weise angeht, wie wir die Dinge in unseren Skripten machen, obwohl beide Optionen natürlich funktionieren, egal ob ihr es direkt mit dem Statistik-Controller oder über den Player macht dem Statistik-Controller oder über den Player Gehen wir also in den Spielmodus und lassen einen Charakter hier besiegen. Also die Charaktere wurden entfernt, und was passieren wird, ist, wenn neue Charaktere erstellt werden, neue NPCs, wir behaupten, dass der Zielspieler existieren muss, aber er existiert nicht Okay, also eigentlich werden wir diese Behauptung einfach entfernen, weil wir Charaktere in der Spielwelt erscheinen lassen können Charaktere in der Spielwelt erscheinen lassen , ohne ein Ziel zu haben Also, wenn das Null ist, denke ich, dass es tatsächlich immer noch laufen könnte Und dann wird es kein Ziel geben , weil der Charakter schon tot ist. Und dann kommen wir hier rein. Wenn das Ziel Null ist, tun wir nichts für den Chase-Status. Also drücke ich auf Play. Okay, das ist also da. Die Feinde hören einfach auf. Ja. Okay, Sie können also sehen, dass dort steht , dass versucht zuvor freigegebene Instanz zuzuweisen. Also, was wir hier brauchen, ist ein weiterer Scheck. Wir sagen, wenn Agent Punkt Punkt Punkt Spieler nicht gleich Null ist, dann werden wir es zuweisen. Okay, das scheint jetzt gut zu sein. Keine Fehler mehr. Jetzt laufen die Charaktere immer noch an ihrem Platz. Also können wir die Feinde sogar in einen Ruhezustand versetzen , wenn wir wollen, dass es ein bisschen glaubwürdiger ist, weil sie ihren Job erledigt haben jetzt nur noch herumsitzen Was wir hier bei Update also tatsächlich tun könnten ist, ein Event auszulösen Nehmen wir an, dies ist das inaktive Ereignis. Okay, also wir werden Idol aus dem Bundesstaat Chase schicken , richtig Wenn wir jetzt zu Ok Enemy HSM wechseln, wollen wir einen Übergang vom Chase-Status in einen Ruhezustand hinzufügen vom Chase-Status in einen Ruhezustand hinzufügen Sagen wir also Übergang hinzufügen. Vom Chase-Status in den Ruhezustand wechseln. Und das wird unter dem Event Idle stehen. Okay, wir brauchen also einen Idle-Status. Also mache ich das im Export var Idle State, was hier ein Limbo-Status ist Klicken wir mit der rechten Maustaste auf Hinzufügen in einem neuen untergeordneten Knoten im Limbo-Status. Okay, und das wird dem Todeszustand wirklich ähnlich sein Todeszustand wirklich ähnlich Ich gehe in den Death State und kopiere alles hier oben in den neuen Limbo-Zustand Also das wird hier der Idle-Zustand sein. Klicken Sie mit der rechten Maustaste, hängen Sie ein Skript an, Idol State. Und lassen Sie uns das in V einfügen, indem Sie diesen Idle-Status einfach umbenennen Wenn ich mehr Status erstellen würde, würde ich wahrscheinlich zu diesem Zeitpunkt darüber nachdenken, einen Basisanimationsstatus zu erstellen . Aber wirklich, es ist nicht so viel Code. Wir duplizieren hier, es ist also kein wirklich großes Problem. Und das ist der einfachste Weg, damit umzugehen. Zumindest kurzfristig gesprochen. Okay, also da das AlpiPaste für den Idol-Status eingefügt wurde, möchte ich die Animation hier nur in Idle umbenennen Die Animation wird bereits vom Blackboard abgespielt. Wir möchten diesen Teil herausnehmen, den Agenten so einzustellen , dass er nicht mehr am Leben ist, weil das nicht stimmt Im Grunde nur das. Wir haben eine Animation. Wir lassen die Animation vom Blackboard abspielen, und wenn wir sie betreten, spielen wir die Animation Und die Animation ist hier inaktiv. Jetzt wollen wir in Enemy HSM nur den Ruhezustand zuweisen Abgesehen davon sollte dies den Übergang regeln. Wir wollen den Übergang in den Todeszustand nehmen und ihn auf einen beliebigen Zustand umstellen. Egal, ob die Charaktere untätig sind oder ihr hinterherjagen, wir können in den Tod übergehen, wenn das Todesereignis eintritt. Das ist wichtig. Und dann wollen wir nur sichergehen, dass wir den Ruhezustand auf das Skelett kopieren. Füge es hier ein und weise es dem feindlichen HSM zu. Ordnen Sie es also dem rechten Ruhezustand zu. Und abgesehen davon sollte es gut sein. Also drücke ich auf Play und wir werden sehen, ob wir unseren Charakter besiegen können. Okay, also los geht's. Unser Charakter zum Idol gewechselt und das war's Sie brauchen also kein Ziel mehr. Sie verfolgen kein Ziel mehr. Sie sind einfach untätig in ihrem Ruhezustand. 31. F30 Erstellen einer Pickup2D-Szene: Jetzt werden wir mit der Erstellung von EXP-Pickups fortfahren , damit unser Spieler Erfahrungspunkte sammeln und aufsteigen kann Dazu werden also einige Schritte erforderlich sein einige Schritte erforderlich Der erste besteht darin unser grundlegendes Pickup-Skript, ein Pickup-Sammler-Skript, zu erstellen ein Pickup-Sammler-Skript, und dann sicherzustellen, dass unser Charakter diese auch erwerben kann, und dann den EP-Boost der aktuellen Erfahrung des Spielers zuzuweisen. Fangen wir also damit an, den eigentlichen 2-D-Welt-Pickup für das Spiel zu erstellen . Also werde ich hier eine neue Notiz erstellen. Wir verwenden zwei D-Szenen, und ich werde sie in Pickup Two D umbenennen . Also klicken wir mit der rechten Maustaste darauf und ändern den Typ, sodass er eine Basis von Area Two D ist . Und wenn wir jetzt auf die angehängte Skriptschaltfläche klicken, erhalten wir ein Pickup zwei D, das Area Two D erweitert . Sagen wir den Ordner Objects, und dann erstelle ich hier einen neuen Ordner. Wir nennen ihn Pickups. Dann kann ich den Pickup unter dem Quadrat mit zwei D-Punkten GD hier drin speichern und das Skript erstellen Und oben geben wir ihm den Klassennamen pickup two D. Wir speichern das im Objects-Ordner pickups sich tdt TACN ab. Also speichern Sie das dort Das wird also ein weltweiter physischer Knoten sein , der ein Gesamtobjekt darstellt , das aufgenommen und auf die eine oder andere Weise auf einen Charakter angewendet werden kann . Das könnte also bedeuten, es direkt auf die Statistiken anzuwenden , oder unter anderen Umständen, dass du es aufhebst und es dem Inventar eines Charakters hinzufügst . Wir werden kein Inventar für das Spiel haben, aber wir werden die Möglichkeit haben, Level zur Waffenausstattung hinzuzufügen oder eine neue Waffenausstattung für einen neuen Waffentyp zu erstellen eine neue Waffenausstattung für einen neuen Waffentyp Für das Pick-up Two D wollen wir eine T-Funktion erstellen, mit der wir das Objekt von der Spielkarte nehmen und es auf die Charaktere anwenden können Objekt von der Spielkarte und es auf die Charaktere anwenden Nehmen wir also die Funktion Tr take an, die ein Ziel benötigen wird. P-Ziel ist also ein D ohne zwei, und wir wollen Boolean zurückgeben ob das erfolgreich war oder Okay, also werde ich hier einen Fehler melden, der besagt, dass es sich um eine virtuelle Funktion handelt, implementiere ein erweitertes Skript Jetzt, in Gudo 4.5, werden sie abstrakte Klassen haben, was die Einrichtung konkreter macht , weil sie einige zusätzliche Schlüsselwörter dafür hinzufügen Aber weil wir auf Gudo 4.4 sind, der aktuellen stabilen Version, werden wir es einfach auf die alte Art machen, was im Grunde bedeutet, dass wir uns daran erinnern müssen , dass wir, wenn wir unsere Pickup-Two-D-Klasse erweitern , dies manuell mit einer neuen Version der Funktion selbst überschreiben müssen dies manuell mit einer neuen Version der Funktion selbst überschreiben der Funktion Mit den gleichen Parametern und dem gleichen Rückgabetyp. Für TriTek geben wir false zurück, weil wir versuchen, ein Objekt in dieser abstrakten Klasse zu verwenden, nämlich der Pickup Two D. also, dass die verschiedenen Pickups in der Spielwelt Wir möchten also, dass die verschiedenen Pickups in der Spielwelt alle ihre eigene benutzerdefinierte Methode haben, sie auf den Spieler oder Zielknoten anzuwenden Also müssen wir für jeden von ihnen ein benutzerdefiniertes Erweiterungsskript implementieren , L eines für EXP und dann eines für eine Waffenabholung, oder es könnte ein Upgrade-Pickup geben. Diese werden also alle ein bisschen anders funktionieren, also benötigen sie alle ihre eigene Tritak-Methode Okay, wir haben hier unser Pickup-Two-D-Skript. Lassen Sie uns mit der rechten Maustaste klicken und einen untergeordneten Knoten hinzufügen. Wir benötigen eine Kollisionsform. Für die Kollisionsform hier gehe ich einfach zu dieser Form oben rechts und mache daraus eine Kreisform. Sie möchten also wahrscheinlich auch hier Sprite als Standard verwenden. Also klicke ich hier mit der rechten Maustaste, füge einen untergeordneten Knoten hinzu, und wir wollen ein Sprite bekommen Also für ein Objekt , das immer und immer wieder eine Animation abspielt, ohne zu wechseln oder so, denke ich, dass animiertes Sprite Two D dort die bessere Option ist Wenn sich zum Beispiel eine Münze auf der Karte immer wieder dreht und Sie nur möchten, dass sie diese eine Animation automatisch abspielt, dann ist animiertes Sprite Two D perfekt Also wählen wir das aus und klicken auf Erstellen. Nun, was die Symbole im Spiel angeht, sind sie vielleicht nicht einmal wirklich animiert. Aber wenn wir das zur Standardvorlage machen wollen, möchte ich das als Möglichkeit eröffnen. Für unseren animierten Sprite gehen wir also zur Animation hier über. Wir werden eine neue Sprite-Frames-Ressource erstellen und diese öffnen Wir haben also unten links ein anderes Animationsfenster unten links ein anderes Animationsfenster Also könnte ich das einfach in Idol umbenennen , wenn ich will. Lass uns in die Kunst gehen. Wir wollen uns mit den Raven Fantasy-Icons und dem kompletten Sprite-Sheet befassen, schauen wir uns das an und schauen, ob wir etwas wollen Um also von diesem Animationsfenster aus richtig darauf zuzugreifen, gibt es dieses Symbol Werbeframes aus Sprite Also klicken Sie darauf. Dann geh zu Art Fantasy Icons, Sprite Sheet Herbst, 16 mal 16. Wirklich, du könntest einen größeren gebrauchen, wenn du willst. Vielleicht nehme ich einfach die 32 mal 32. Also als etwas mehr Auflösung und öffne es, und du kannst einfach die gewünschten Symbole auswählen. Okay, damit das richtig aufgeteilt werden kann, brauchen wir hier die richtige Anzahl von Zeilen und Spalten in unserem Spritesheet. Oder wenn Sie die Größe der einzelnen Symbole kennen, können Sie meiner Meinung nach einfach zur Größe hier gehen und einfach 32 30 eingeben. Ja Okay, das ist definitiv der schnellere Weg. Wenn Sie einen ändern, wird der andere automatisch berechnet. Wir haben also 16 horizontale. Wirklich, das sind die Spalten, und dann sind 128 vertikal die Zeilen. Anstatt das zu berechnen, wissen wir einfach, dass jede Zahl 32 mal 32 ist. Okay? Jetzt können wir ganz einfach das gewünschte Symbol daraus auswählen. Sie können also alles, was Sie wollen, als EXP-Gem verwenden . Ich glaube, im Vorlagenprojekt habe ich dieses hier verwendet Also irgendwie nur ein blauer Edelstein. Wir fügen diesen einen Rahmen hinzu. Und das wäre Autoplay, wenn wir einfach Autoplay da unten ankreuzen würden, aber Sie können sehen, dass das nicht einmal wirklich abgespielt werden muss Und es ist wahrscheinlich etwas performanter , wenn wir Autoplay ausschalten Es zeigt also nur diesen einen Frame und versucht nicht einmal, etwas zu wiederholen. Reine Vermutung meinerseits, aber lassen wir das einfach dort einstellen. Und das wird unser Standard-Spike für Pickup Two D sein . Also für den Root-Node Pickup Two D wollen wir wahrscheinlich auch die Kollisionsebenen einrichten Ich glaube also nicht, dass wir eine spezielle Ebene für Pickups haben. Fügen wir also eine neue Kollisionsebene hinzu. Machen Sie es einfach zu Ebene fünf und sagen Sie Pickups. Okay, nah dran. Und dann wollen wir natürlich den Tonabnehmer auf Ebene fünf legen und die Maske ausschalten. Wir schalten die Überwachung aus, weil das von irgendwas aufgegriffen wird. Es ist keine Überwachung von Abholungen. Dadurch kann der Spieler, der das Objekt aufhebt, die Erkennung durchführen Das ist also nur ein Monitor einer Schale mit Schicht fünf. Und das ist die Ausgangsszene für unseren Pickup 32. P31 Implementieren eines Experience Pickup-Systems mit Vererbung: Was wir unten links tun können ist erneut nach Abholung zu suchen. Daraufhin sollte der Pickups-Ordner angezeigt werden, und wir möchten mit der rechten Maustaste auf Pickup two D klicken und eine Szene mit der Übernahme erstellen. Das ist hier also ganz oben, neue geerbte Szene, was bedeutet, dass wir eine neue Szene auf der Grundlage dieser Szene erstellen, sodass sie dieselben Standardeinstellungen von unserer übergeordneten Szene erbt Wir erstellen also diese neue Szene und Sie werden sehen, dass einige dieser Knoten orange werden, was bedeutet, dass tatsächlich auf der übergeordneten Szene basieren Sie können zum übergeordneten Element springen, indem Sie hier klicken. Sie können also Szenen innerhalb von Szenen haben. Und wir wollen den Stammknoten umbenennen, sagen wir EXP pick two D. Weil wir genau angeben wollen, was wir tun Und speichern wir das als neue Szene. Also XP Pickup, Punkt TCN, speichern Sie das. Und dann klicken wir mit der rechten Maustaste auf den Stammknoten und erweitern dieses Skript Okay, das gibt uns unser EXP Pickup two D-Skript, das sich von Pickup zwei D erstreckt . Und dann gehen wir hier nach oben und sagen Klassenname EXP Pickup two D. Also wollen wir eine Variable dafür angeben wie viel EXP wir tatsächlich sammeln werden, wenn der Charakter Tri Take bei der Abholung benutzt Bei Export wird VR also eine Ganzzahl sein, und wir werden diese standardmäßig Und jetzt, wenn wir uns das Pickup-Two-D-Skript ansehen, wollen wir diese Funktion nehmen und sie korrekt in unser erbendes Skript implementieren Also werde ich das kopieren und wir werden zu EXP Pickup Two D übergehen. Ich werde es einfügen und wir unsere echte Tri-Take-Methode schreiben der EXP-Erfassung wird die Erfahrung also auf das Ziel angewendet, sofern das Ziel tatsächlich Erfahrung hat Nehmen wir an, wenn die Punktstatistik des Ziels gleich Null ist, dann geben wir hier Falsch zurück Andernfalls können wir sagen, dass var stats gleich ptarget dot stats ist Und weil wir nicht wissen, was diese Statistikvariable tatsächlich im Kontext jedes Skripts bedeutet, weisen wir ihr direkt den Stat-Controller-Hype Sobald also die Bedingung erfüllt ist, dass es sich um ein Ziel handelt , das einen Statistikblock hat, können wir sagen, dass Statistik Punkt Erfahrung plus Erfahrung ist, und dann geben wir wahr zurück Nachdem wir das Erlebnis aufgenommen haben, wollen wir nicht, dass es wieder nutzbar ist, also sage ich, überwachbar ist gleich falsch, und dann geben wir das Objekt wieder frei Wenn Sie also das Cue Free verwenden, wird es einige Zeit dauern, bis es tatsächlich endgültig aus der Szene entfernt wird Wir wollen also sichergehen, dass nichts anderes, das in diesem einzelnen Frame hineinläuft , versehentlich die EXP-Aufnahme ein zweites Mal aufnehmen könnte versehentlich die EXP-Aufnahme ein zweites Mal aufnehmen Deshalb setze ich hier monitorable auf Falsch , damit nichts anderes Nur als Sicherheitsmaßnahme, und dann entfernen wir es komplett vom Tatort Also das hier, ich möchte es wahrscheinlich für alle meine Tonabnehmer wiederverwenden Ich zerschneide das in Tonabnehmer zwei D und sage dann function remove, was dann void zurückgibt, und ich führe einfach diesen Nachbearbeitungsschritt Wenn ich jetzt zu EXP-Pickup zurückkehre, rufe ich einfach remove auf, was aus der Basisklasse stammt Diese Funktion ist also bereits in der Basisklasse geschrieben und wir können sie hier wiederverwenden Dann, ja, jedes Mal, wenn wir das Banale implementieren , wenn wir das wiederholen wollen, können wir es hier einfach entfernen Und damit das funktioniert, müssen wir die erfahrenen Statistiken zu unserer Statistikkontrolle hinzufügen die erfahrenen Statistiken zu unserer Statistikkontrolle Also werde ich im Set-Controller diese EXP-Eigenschaft erstellen Okay, wir werden also Vara-Erfahrung haben und der Boden wird standardmäßig auf Null als Okay, und im Einklang mit dem Take Damage, wo wir das Set unabhängig von der Einstellung der HP als unbesiegbar bezeichnen , würde ich es vielleicht vorziehen, hier keinen Setter zu machen geht eher um Funktion und Erfahrung, Es geht eher um Funktion und Erfahrung, und wir geben dem einen Betrag Also P-Betrag, das ist eine Ganzzahl und wir geben hier void zurück. Wir wollen also, dass das Plus der Erfahrung dem Betrag P entspricht. Und dann als Nächstes schauen, ob es einen Levelaufstieg gibt. Und wir können auch sagen, dass es hier Erfahrung gibt. Wir erhalten also die gesamte Erfahrung, wenn wir Gegenstände von der Karte in der Konsole sammeln. Und um dann die Anzahl der gesammelten Erfahrungspunkte dafür zu aktualisieren, möchte ich Statistiken hinzufügen und Erfahrungserfahrung hinzufügen Okay, wir sind also etwas expliziter. Diese Funktion impliziert also, dass alles, was mit Erfahrung zu tun hat und sich beim Hinzufügen von Erfahrung ändern muss , passieren wird, was bedeutet, dass wir nach einem Levelaufstieg suchen würden und so weiter. Und ich denke, das hätte einen gewissen Vorteil. Beispiel könnten wir den Erfahrungswert ändern, ohne automatisch einen Levelaufstieg auszulösen oder nach einem Levelaufstieg zu suchen , wenn wir das später benötigen Anstatt das immer zu tun , egal was passiert, wie wir es mit dem HP Setter gemacht haben, wo er dein Leben immer aktualisiert Beide Arten, Dinge zu tun, sind bis zu einem gewissen Grad gültig. Es geht irgendwie darum, wie Sie Ihre Absicht hier ausdrücken möchten. Und möchtest du die Tatsache verbergen , dass das Einstellen von Erfahrung auch einen Levelaufstieg auslösen würde auch einen Levelaufstieg auslösen indem du es in einen Erlebnis-Setter einfügst, oder möchtest du mit der Funktion „Erfahrung hinzufügen“ expliziter sein? mit der Funktion „Erfahrung hinzufügen 33. P32 Collector2D einrichten und Playeranimationen korrigieren: Um das Erlebnis vom Pickup Two D auf unseren Statistik-Controller zu übertragen, benötigen wir unseren Collector Two D-Node , der Pickups für unseren Spieler sammelt Pickups für unseren Spieler Gehen wir also zur Spieler-Szene. Ich klicke mit der rechten Maustaste auf Player. Wir fügen einen untergeordneten Knoten hinzu. Suchen wir nach einem Bereich zwei D. Also diesen Bereich zwei D, ich werde ihn hier in Collector Two D umbenennen . Und dann klicken wir mit der rechten Maustaste auf Skript anhängen. Das Drehbuch wird also so aussehen, es könnte in Zeichen sein, also werde ich es tatsächlich in Zeichen setzen. Es könnte einen Fall geben, in dem wir einem Feind die Möglichkeit geben , Objekte aufzusammeln, aber ich möchte nicht, dass das komplett spielerspezifisch ist. Also werde ich das Drehbuch dort ablegen. Lass uns kreieren. Dann geben wir ihm oben links den Klassennamen Collector Two D. Für den Kollektorbereich zwei D ist uns wichtig, wenn ein Pickup in das zwei D ist uns Leerzeichen eindringt. Wir sagen also, dass die Funktion underscore ready den Wert void zurückgibt, und wir sagen, eingegebener Bereich punktet mit eingegebenem Bereich verbinden Dann erstellen wir die Callback-Funktion Underscore den eingegebenen Bereich erhält einen P-Bereich , zwei D als Parameter und geben den Wert void Wenn P area also ein Pickup zwei D ist, dann machen wir P area dot Tri take auf unserem Wurzelknoten Unser Wurzelknoten ist also unser Spieler. Wir könnten unseren Wurzelknoten hier exportieren, bei Export Object Root ist Knoten zwei D, nehme ich an. Und dann schicken wir den Objektstamm hierher. Als das TriTek-Objekt, das wir durchgehen wollen Jetzt, in unserem Inspektor, signieren Sie den Player hier, und das könnte eigentlich alles sein, was wir brauchen Lasst uns also eine Kopie unseres EXP-Pickups zur Spielwelt hinzufügen unseres EXP-Pickups zur Spielwelt Wir werden wirklich ein paar reinlegen. Also klicke ich mit der rechten Maustaste auf World. Lassen Sie uns einen zweiten Knoten D erstellen. Ich benenne diese Tonabnehmer und füge dann der Spielwelt ein paar Pickups Also eins, zwei, drei, und dann lege ich sie alle auf die übergeordneten Tonabnehmer Wir können sehen, dass sie ziemlich groß sind. Für den Moment ist das in Ordnung, aber wir werden sie wahrscheinlich für den Rest unseres Spiels verkleinern. Bevor sie funktionieren , erinnere ich mich nur daran, dass wir den Collider noch nicht auf dem Player eingerichtet den Collider noch nicht auf dem Player Für Collector Two D klicken Sie mit der rechten Maustaste auf einen untergeordneten Knoten, und wir wollen hier Kollisionsform zwei D. Fügen Sie also auf der rechten Seite eine neue Kreisform hinzu und verkleinern Sie sie, bis sie vielleicht genau da ist, etwas größer als die normale Kollisionsform Gehe zu Collector TD und nimm die Kollision. Wir maskieren auf der Pickups-Ebene und schalten dann Maskenebene Eins-Welt und Kollisionsebene Eins-Welt Das sollte ein reines Überwachungsskript sein. Und mir ist gerade aufgefallen, dass diese hellen Rahmen für unsere Animationen unterschiedlich groß sind und daher nicht richtig in der Mitte angeordnet sind. Das Idol sieht gut aus, aber der Lauf ist vielleicht ein Pixel nach rechts, und dann ist der Tod auch ein bisschen falsch Eine Möglichkeit, das Problem zu beheben , um sicherzustellen, dass sie alle korrekt sind, besteht darin jedem der SprikeFrames eine Positionseigenschaft zuzuweisen, was ich hier anscheinend schon für die Todesposition getan hier anscheinend schon für Idle hat also seinen eigenen Wert. Lassen Sie mich sehen, was passiert, wenn ich diese Positionseigenschaften tatsächlich entferne. Also mach das für Death Idol und lauf weg, okay? Und dann entfernen wir es auch für den Reset, falls es da ist Okay, also ja, es sieht müssten wir das noch einmal anpassen. Okay. Fangen wir also mit dem Lauf an. Ich werde es genau hier bei minus 30 positionieren und das mit einem Keyframe in die Animation einfügen Wir gehen nach Idle. Ich drücke W und schiebe das nach unten. Es ist also ungefähr so, minus 13 und gib ein Keyframe ein. Okay, lass uns rennen gehen Gehen wir nach Idle. Es scheint, als ob Idle immer noch ein Pixel zu niedrig ist, also werde ich den Wert auf minus 14 erhöhen und es mit einem Keyframe versehen Ich glaube, das hatten wir schon einmal, aber ich werde den Lauf nehmen und ihn ebenfalls um eins nach links verschieben und einen Keyframe hinzufügen Also jetzt, wenn wir zwischen Leerlauf und Run wechseln. Okay, das sieht jetzt tatsächlich richtig aus. Lass uns in den Tod gehen und es hier nach rechts verschieben und es einrahmen. Das sind also zehn Pixel nach rechts. Und jetzt wechseln wir in den Leerlauf. Okay, der Tod ist ein Pixel nach rechts zu viel. Also das muss auf eine negative Neun gehen, Schlüsselbild. Also sind wir untätig. Okay, wir müssen also zwei weitere Pixel nach links gehen, um den Tod zu markieren und ihn mit einem Keyframe zu versehen. Also das ist eine Acht, und dann ist der Leerlauf Null für X. Okay, all das sieht aus, als würden sie sich jetzt aneinanderreihen. Okay. Also hier sind die tatsächlichen Werte. Acht minus 14 für den Tod. Idol ist Null negativ 14. Run ist minus eins und minus 30. Und dann der Reset, der dem Idol entsprechen sollte , der Null, minus 14 ist Der Reset wird also auf minus 14 reduziert. Minus 14 ist genau da, Keyframe drauf. Okay, und das sollte alle Animationsprobleme lösen, die wir mit diesen Spritesheets haben Okay, jetzt zurück zu Kollektor zwei D. Stellen Sie sicher, dass Sie Ebene eins und die Maske für Ebene eins auch ausschalten Ebene eins und die Maske für Ebene eins auch ausschalten Okay, und jetzt können wir auf Play klicken und schauen, ob wir diese kleinen Symbole tatsächlich aufnehmen können . Also haben wir den bekommen. Lassen Sie uns die Ausgabe überprüfen. Haben wir die Erfahrung gemacht? Ja, das haben wir. Wir haben dort eine Erfahrung gemacht. Wir gehen hier runter. Wir sammeln Erfahrung zwei. Nun, diese Erfahrung drei, sodass wir anhand unserer Konsolenausgabe überprüfen können, ob unsere Tonabnehmer funktionieren Und unser Charakter wurde im Hintergrund besiegt. Aber das ist gut , das zeigt, dass das Game Over-System auch tatsächlich funktioniert hat. 34. P33 Feindliche Abwurfmechaniken erstellen und die Größe von Pickups ändern: Unsere Pickups. Jetzt wollen wir sichergehen, dass Feinde sie auch fallen lassen, wenn sie besiegt sind Wahrscheinlich wollen wir auch schnell die Größe des Pickups D ändern, weil er zu diesem Zeitpunkt doppelt so groß ist wie unser Spieler In EXP Pickup Two D kann ich also entweder das animierte Sprite auf die 16x16-Version umstellen , was praktisch ist, weil wir das schon haben, oder ich nehme den Node und verkleinere Ich kann es also auf 0,50 bis 0,5 setzen. Und dann wäre das eine Möglichkeit, es schrumpfen zu lassen. Aber wenn wir bereits wissen, dass die Größe in unserem Spiel nicht einheitlich sein wird, wäre es vielleicht sinnvoller, in die Basisszene von Pick up Two D zu gehen das animierte Sprite zu ändern Und dann fügen wir dasselbe Symbol hinzu, aber aus dem 16x16-Pack Gehen Sie also zu den Kunstsymbolen, das ganze Sprite-Blatt, 16 mal 16. Nehmen Sie die Größe 16 mal 16 , da dies das kleinere Spritesheet ist Und dann steuern wir die Maus aus Metall, zoomen hinein, suchen das Sprite, fügen es hinzu und entfernen das große Wählen Sie also Null aus und löschen Sie das, und dann geht es runter zu Frame Null. Speichern Sie das. Und dann, zurück in dieser Szene, kannst du es auch speichern, und es sollte gut für das Weltbild sein Okay, jetzt hat es die passende Größe. Okay, gehen wir in die Orkszene und fügen die Möglichkeit hinzu, Gegenstände fallen zu lassen Also hier wollen wir ein Skript, das sich um Gegenstände kümmert, die wir ins Spiel werfen können, und wir möchten vielleicht zufällig aus einer Liste von Gegenständen auswählen, und wir können sie so gewichten, wie wir es getan haben, als wir darauf gewartet haben, dass der Feind erscheint. Also klicke ich mit der rechten Maustaste auf den Todesstatus, da dieser direkt mit dem Todesstatus verknüpft ist dem Todesstatus verknüpft in dem Sinne, dass wir Gegenstände beim Tod fallen lassen, und ich füge einen untergeordneten Knoten Also mach hier einen normalen Knoten. Dann benennen wir das in etwas wie Drops um . Klicken Sie mit der rechten Maustaste, fügen Sie ein Skript hinzu, und dann erstellen wir es hier. Also geben wir ihm den Klassennamen Drops. Also geben wir ihm den Klassennamen Drops. Okay, und in unserem Drop-Skript wollen wir im Grunde eine Liste von Objekten haben, die wir löschen können. Nehmen wir an, bei Export VR verwenden wir Drop-Definitionen, und das wird eine Reihe von Drop-Definitionen sein. also dem gleichen Muster wie zuvor folgen, wo wir eine vom Editor definierte Ressource haben, können wir das noch einmal wiederholen, also werden wir im Dateisystem irgendwohin gehen wollen , zum Beispiel in den Ordner Objects Pickups gehen den Ordner Objects Pickups und mit der rechten Maustaste klicken und ein neues Skript erstellen Und ich werde das Drop-Definition nennen. Und das wird von der Ressource ausgehen. Erschaffe das. Jetzt können wir die Drop-Definition öffnen und ihr den Klassennamen Drop-Definition geben. Und wir werden eine VR-Szene exportieren wollen , die eine vollgepackte Szene ist. Also, was werfen wir in die Spielwelt, den eigentlichen Item-Drop? Da es sich also um eine überfüllte Szene handelt, könnte es wirklich alles sein , was einen Knoten an der Wurzel hat. Du könntest Feinde fallen lassen , wenn du willst. Diese Verpackung macht es also einfach flexibel. Okay, und als Nächstes wollen wir ein Gewicht. Das Gewicht des Exportwagens ist also schwimmend. Wir setzen das standardmäßig auf 0,1, und das ist ein guter Anfang Also gehen wir wieder in das Drop-Skript und wir haben unser Array von Drop-Definitionen, und wir haben unser Array von sodass wir auf Drops klicken können. Und wenn Sie das Array hier oben und den Inspektor hier nicht sehen können , können Sie einfach zu Project gehen und das Projekt neu laden Okay, wenn du jetzt den Inspektor überprüfst, sollte er dort erscheinen solange du keine Fehler hattest Also werden wir unsere erste Drop-Definition erstellen. Also eine neue Drop-Definition, und wir können daraus ein EXP-Fitnessstudio mit einem Gewicht von eins machen, wenn wir wollen. Also schnelles Laden Und wir werden nach dem EXP-Pickup suchen, zwei D Enter, und das ist fertig Unser Ork wird also nur in der Lage sein, die EXP-Edelsteine fallen zu lassen, und das ist völlig in Ordnung für unseren Grundfeind Lage sein, die EXP-Edelsteine fallen zu lassen, und das ist völlig in Ordnung für unseren Damit wir funktionieren wollen, können wir unseren Todeszustand oder unsere Animation aufrufen , die in der Lage wäre, die Drops in der Spielwelt zu erzeugen Wir könnten also Funktion Drop sagen, wenn du willst, du könntest hier mehrere Male weitergeben, Beispiel P mal ist eine Ganzzahl, und das kann standardmäßig auf eins gesetzt werden, und das wird void zurückgeben. Wir könnten also sagen, viermal im Bereich Null bis P mal inkrementiert jedes Mal um eins Das heißt, wir beginnen bei Null und steigen einmal, bis wir das P-fache erreichen Wenn also P mal eins ist, wird es einmal ausgeführt, weil es Null erreicht, und dann trifft es P mal und stoppt. Also machen wir den Doppelpunkt dort. Okay, und dann, nachdem wir den Loop gemacht haben, müssen wir jedes Mal einen Drop generieren. Also wäre es wahrscheinlich am besten, das Gesamtgewicht einmal zu berechnen und es dann hier drin zu verwenden. Lassen Sie uns also das Gewicht generieren. Bevor wir also die Drops generieren, sagen wir vier DF- und Drop-Definitionen. Wir werden das Gesamtgewicht akkumulieren, also brauchen wir eine Variable, die darüber liegt. Bisher beginnt das Gesamtgewicht, es gibt einen Float, der bei Null, Null beginnt, und das entspricht dem Gesamtgewicht plus DF-Punktgewicht. Okay? Also haben wir das. Also, innerhalb dieser vier Schleifen am unteren Rand, durchlaufen wir sie jedes Mal. Wir möchten, dass unser ausgewähltes Gewicht zwischen Null und dem Gesamtgewicht liegt. Es wiederholt also quasi dieselbe Logik wie anderen Randomisierungen, die wir in diesem Kurs durchgeführt haben Nehmen wir an, das Gewicht von var ist gleich Rand F , also 00-1 0,0, und wir multiplizieren diesen Wert mit unserem Gesamtgewicht, wodurch wir unsere Auswahl wir an, das Gewicht von var ist gleich Rand F , also 00-1 0,0, und wir multiplizieren diesen Wert mit unserem Gesamtgewicht, erhalten Nun addieren wir für jeden der zu definierenden Drops in Drop-Definitionen das bisherige Gewicht Bisher sagen wir, dass das aktuelle Gewicht, das eine Gleitkommazahl ist und bei Null, Null beginnt , das aktuelle Gewicht plus dem Definitionsgewicht entspricht Okay, das gibt uns das, was wir bisher gemacht haben. Wenn dies größer als das gewählte Gewicht ist, wollen wir diesen Drop zurückgeben oder ihn einem Drops-Array hinzufügen. Wenn also das aktuelle Gewicht größer oder gleich dem ausgewählten Gewicht ist, dann ist es das Gewicht, das wir an ein Array anhängen wollen Lassen Sie uns also hier oben über den vier Schleifen ein Array erstellen, und wir sagen, var drops ist ein Array mit Drop-Definitionen Nun, das Wichtigste dabei ist, dass es mehrere Kopien derselben Drop-Definition geben kann . Es ist ein Array, nicht etwas anderes wie ein Hash-Set. So können wir bei Bedarf den gleichen Drop zwei - oder dreimal durchführen, was wichtig ist. Sagen wir, Drops Dot fügen die Definition an, und dann brechen wir aus dieser Vierer-Schleife aus, und dann geht es hier wieder los Sobald wir also den Punkt erreicht haben, an dem das aktuelle Gewicht gleich oder größer als das gewählte Gewicht ist, wählen wir den Drop aus und wiederholen jedes Mal, wenn wir das für dieses Drop-Setup benötigen Jetzt haben wir alle Drops hier unten, also wollen wir sie in die Spielwelt übernehmen. Sagen wir also, vier Drop-In-Drops. Wir werden eine Instanz erstellen, die Drop Dot Seen Dot Instantiate entspricht Und dann werden wir das als Kind einem Elternteil in unserer Spielwelt hinzufügen Elternteil in unserer Spielwelt Also in der Welt könnten wir diesen Pickups-Node einfach wiederverwenden, wenn wir wollen Also kann ich Abholungen annehmen. Gehen wir zu dem Knoten hier oben rechts und ich werde eine neue Gruppe hinzufügen Also sagen wir Pickups. Ich werde das global machen. alles, was ein Gegenstand ist, der von der Welt abgeholt werden soll, fügen wir ihn als Knotengruppe hinzu. Wenn es sich also in einer Knotengruppe befindet, ist es in unserem Skript sehr leicht zu finden Und wir können diesen Pickups-Node tatsächlich bekommen, sobald unser Ork geladen ist, sodass wir wissen, ob es ein Problem gibt Also sagen wir var pickups parent, und das wird Knoten zwei D sein, und wir sagen schon function und das wird Knoten zwei D sein, und wir sagen schon function underscore. Lass mich hier reinzoomen Das übergeordnete Objekt für Pickups entspricht Gtree dot Ermitteln Sie den ersten Knoten in der Gruppe, und wir suchen nach diesen Pickups sodass Sie in den Knotengruppen hier in den Inspektor-Knotengruppen sehen können, dass es bereits einen Pickups gibt, und dieser ist diesem Pickup-Knoten zugewiesen Solange der Pickups-Node also in unserer aktuellen Spielwelt existiert , wird er Wir könnten noch einen Schritt weiter gehen und das auf eine konstante Variable reduzieren Also sagen wir hier Pickup-Gruppe, alles in Großbuchstaben, und dann ist Constant Pickup Group ein String-Name, der gleich ist, und ich sage Ampersand, Control V, und fügen die Solange Sie dafür einen Knoten in der Pickups-Gruppe haben und diesen Knoten der Gruppe innerhalb Ihres Spielprojekts zugewiesen haben diesen Knoten der Gruppe innerhalb Ihres Spielprojekts zugewiesen der Gruppe innerhalb und er in der Szene existiert, funktioniert das einwandfrei Sie benötigen keine direkten Referenzen, was schwierig wäre, da der Ork in der Szene erst existiert , wenn er erzeugt wurde Das ist also eine gute Methode übergeordneten Knoten zu bekommen , dem wir ihn zuordnen können Wenn wir sichergehen wollen, können wir sogar sagen, Assert Pickups Parent ist und nicht gleich Null ist, und dann sagen wir, dass es einen Elternteil geben muss , damit Objekte gelöscht werden können. Okay, das ist ziemlich klar. Okay, also instanziieren wir jede der Szenen und wollen sie dann als Kind zum übergeordneten Objekt hinzufügen . Also übergeordnet Pickups AChildStance. Und der Ort, an dem sich der Drop befinden soll, wird auf Knoten zwei D basieren. Also müssen wir Drops nehmen und ihn in einen Knoten vom müssen wir Drops nehmen Typ D ändern Dann können wir hier unten sagen, globale Position der Instanz globalen Position aus dem Skript entsprechen wird. Okay, das heißt zurück in unsere Orgszene. Jetzt wollen wir diesen Knotentyp ändern Ich klicke mit der rechten Maustaste und ändere den Typ, suche nach Drops und du solltest ihn hier sehen. Doppelklicken Sie. Okay, klicken Sie auf Drops. Stellen Sie sicher, dass Sie im Inspektor immer noch Ihre Drop-Definition für das EXPJM haben Ihre Drop-Definition für das EXPJM Und wir müssen das wahrscheinlich von den HSM-Knoten hier entfernen den HSM-Knoten Da dies ein Knoten zwei D ist, möchten wir, dass er ein untergeordnetes Element unseres Hauptknotens zwei D ist, also werde ich das hier als Kind der Arbeit ansprechen Und das sollte wahrscheinlich gut sein. Also haben wir den Gegenstand oder was auch immer wir lassen die Instanz in die Spielwelt einbauen. Es wird ein untergeordnetes Element des Knotens der Pickups-Gruppe, und dann geben wir ihm die Position dieses Drops-Knotens, was, ist und dann geben wir ihm die Position dieses Drops-Knotens, was, wenn überhaupt, nur ein Offset von der Ork-Position Wir müssen es nicht ändern, aber wir könnten einfach eine Standardeinstellung wie Null oder Null haben . Das ist in Ordnung. Und jetzt können wir entweder Drops aus der Todesanimation oder dem Todeszustand aufrufen . Also, wenn ich hier zum Animation-Player gehe und wir die Todesanimation öffnen, mal sehen. Zustand des Todes. Also lass uns sehen. Wir nennen den fertigen Todesstaat. Wir könnten die Drops einfach hinstellen sobald der Ork zu sterben beginnt Ich denke, das ist vielleicht eher die Art und Weise, wie die meisten Spiele laufen, wo man die Schleife sieht bevor sie von der Szene abstürzen Rufen Sie also bei einem Track die Methode auf dem Drops-Node auf. Dann hier unten beim ersten Bild. Lass uns reinzoomen. Ordnung, klicken Sie auf Schlüssel einfügen. Wir machen Drops. Sie können sehen, wie die Parameter im Animation-Player funktionieren. Also oben rechts haben wir Namen unserer Drop-Methode. Habe das Argument. Das erste Argument und das einzige Argument ist also der Wert int. Also, wie oft wollen wir Drops aufrufen? Wir könnten zum Spaß 50 sagen, und lassen Sie uns auf Play klicken und sehen, ob das tatsächlich funktioniert. Das wird also eine Menge dieser EXP-Juwelen in die Szene setzen , wenn es funktioniert, aber zumindest werden wir definitiv wissen, ob es funktioniert Also lass uns sehen, was passiert. Okay, ich glaube, sie spawnen einfach alle an derselben Stelle Also werde ich das durchgehen. Und ja, du kannst sehen, dass wir 50 Edelsteine gesammelt haben. 35. P34 Erstellen zufälliger Artikel-Ablagepositionen: Ly, wenn der Ork 50 dieser Gegenstände fallen lässt, sind sie alle übereinander gestapelt , wenn ich mir die Ausgabe ansehe Also haben wir dort 50 XP. Und ich denke, was wir tun wollen , ist , dass wir dem Objekt, wenn es erscheint, entweder einen Offset geben oder es vom Objekt wegbewegen Es fällt von ein bisschen ab. Ich denke, der schnellste Weg, dies zu tun, wäre eine zufällige Offset-Position zu generieren, und diese wird eine bestimmte Anzahl von Pixeln in zufälliger Richtung vom Zeichen entfernt Also können wir das einfach für das Drop-Skript hinzufügen. oben gehe ich beim Export unserer Drop-Max-Distanz, die ein Float sein wird. Und lassen Sie uns standardmäßig mit zehn Pixeln arbeiten. Dies gibt an, wie weit vom Drops-Knoten entfernt ist. Das ist dieser spezielle Knoten, an dem wir gerade arbeiten, an dem das Objekt spawnen kann, und das ist eine maximale Anzahl, es können also effektiv 0-10 Pixel sein Also hier unten werde ich eine neue Funktion erstellen. Ich nenne es Function, Underscore, Get Span, Offset Und das wird in einer maximalen Entfernung von P übergeben, was eine Gleitkommazahl ist, und wir können Standardeinstellung für die maximale Entfernung Wir müssen also keinen Parameter übergeben. Es kann einfach das standardmäßig sein. Und dann wollen wir zu Vektor zwei als Offset zurückkehren. Um also einen endgültigen Offset zu erhalten, benötigen wir die Richtung und dann die Größe, die Größe ist genau hier in der P-Max-Entfernung. Nehmen wir an, var-Richtung wird ein Typ sein, der aus Vektor zwei abgeleitet wird, und wir werden einen neuen Vektor zwei erstellen, also setzen wir ihn hier in Klammern, wir benötigen ein X und ein Y. das zu erreichen, müssen wir also im Grunde eine zufällige Richtung zwischen minus eins und 1,0 erzeugen eine zufällige Richtung zwischen minus Also werde ich Rand F sagen, und ich denke, wir brauchen hier einen Bereich, weil wir einen negativen Wert von 1,0 haben wollen , nicht Also zufälliger F-Bereich von minus 1,0 bis 1,0. Und dann müssen wir das ein zweites Mal machen, damit wir diese Zeile für den Y-Wert einfach hierher kopieren können diese Zeile für den Y-Wert einfach hierher kopieren Und dann möchte ich den Vektor normalisieren , sodass er eine reine Richtung hat. Okay, jetzt bekommen wir unseren Offset. Vari-Offset entspricht also der Richtung mal der maximalen P-Entfernung. Und dann geben wir den Offset zurück, und das ist im Grunde alles. Also nehmen wir hier Get spawn offset, und wenn wir die globale Position festlegen, werden wir globale Position plus gitSpawnOfSet machen Die Standardeinstellung ist drop Max distance, also können wir das hier einfach als Standard verwenden Sie müssen also die Drop-Max-Entfernung nicht wirklich eingeben, könnten es aber. Es wäre also nur der Wert, der sich selbst überschreibt. So oder so, es wird dasselbe sein, aber Sie haben die Möglichkeit , es leer zu lassen, und dann wird dieser Wert hier unten einfach standardmäßig verwendet . Ich denke , das ist alles was wir brauchen. Gehen wir also einfach in den Spielmodus und schauen, ob diese 50 Gegenstände tatsächlich an verschiedenen Orten fallen. Drücken wir also auf Play und wir gehen hier rein. Ich schieße einen Pfeil oder einen Speer auf den Ork. Und wir können sehen, dass sie alle in zufälligen Richtungen spawnen Aber ich habe tatsächlich einen Fehler gemacht. Wir wollen den Vektor also nicht normalisieren, weil ich möchte, dass der Prozentsatz der Entfernung zwischen 0 und 100% Okay, weil ich den Vektor für die Richtung normalisiert habe , wird dir hier immer die volle maximale Entfernung angezeigt. Das wird nur die reine Richtung sein. Aber was ich eigentlich will, ist, wenn es diese Richtung nimmt, wird es ein gewisser Prozentsatz der Entfernung sein. Und vielleicht möchten wir das eher als Zufallsvektor bezeichnen . Und dann gehen wir runter zum Offset hier unten und darüber hinaus. Also, wenn es das X nimmt, wird es irgendwo 0-100% der Entfernung auf dem X multipliziert mit der maximalen Entfernung P sein und das Gleiche gilt für das Y. Das gibt ihm also eine eher zufällige Position innerhalb eines imaginären Kreises Wenn Sie eine Kollisionsform erstellen würden, würde sie für die möglichen Spannweiten ungefähr so aussehen würde sie für die möglichen Spannweiten ungefähr so aussehen. Gehen wir also in den Spielmodus, und es sollte jetzt korrekter sein , wenn wir alle 50 Gegenstände gleichzeitig fallen lassen. Also da hast du es. Sie werden alle zufällig innerhalb dieses Kreises generiert. Wir werden niemals 50 Artikel gleichzeitig fallen lassen . Das sieht also irgendwie funky aus. Aber wenn es zwei oder drei Tropfen sind, denke ich, dass es gut funktionieren wird Um das zu demonstrieren, gehe ich zum Animation-Player, und wenn wir den Tod machen, nehme ich die Drops-Funktion hier und ändere ihren Argumentwert, wie viele Drops es ändere ihren Argumentwert, wie gibt, auf etwas mehr als drei. Ich denke, das ist realistischer. Lass uns auf Play drücken und dann gehen wir hier rein. In den meisten Fällen glaube ich, dass die meisten Feinde nur einen Gegenstand fallen lassen. Aber wenn wir uns dafür entscheiden, drei fallen zu lassen, können wir zumindest sehen , dass sie unterschiedliche Positionen haben, und es ist offensichtlich, dass wir zumindest sehen, wo sie sich befinden. Okay, ich möchte das zum Abschluss bringen indem ich die Drops einfach auf eins ändere. Jeder oder lässt nur eine EXP fallen. 36. P35 Implementieren eines Pickup-Schwerkraftbereichs: Es ist etwas mühsam, wenn dein Spieler über jeden einzelnen Pickup laufen muss , den du dir schnappen möchtest, besonders wenn du all diesen Ork-Feinden ausweichen musst, die sich über den Bildschirm erstrecken Was wir also hinzufügen wollen, ist ein Bereich mit der Schwerkraft der Pickups unserer Spielerszene werde ich also, anstatt die Gravitationsfläche zu unserem Collector-Zwei-D-Knoten hinzuzufügen , anstatt die Gravitationsfläche zu unserem Collector-Zwei-D-Knoten hinzuzufügen, einen separaten Knoten mit zwei D-Bereichen speziell für die Schwerkraft erstellen . Der Grund dafür ist, dass die Kollisionsform zwei D hier, um die Gegenstände tatsächlich aufzunehmen , ein anderer Bereich sein wird als der , auf den die Schwerkraft angewendet wird. Das wäre also etwas verwirrend, wenn der Kollektor zwei D hier zwei Flächenformen hat. Also werden wir einen neuen Knoten erstellen. Ich klicke mit der rechten Maustaste auf Spieler und füge einen untergeordneten Knoten hinzu. Das wäre bei Bereich zwei D. Wir fügen ihn hier unten hinzu, und ich werde ihn umbenennen, zum Beispiel in Pickup Gravity Two D, weil das speziell für Gegenstände auf der Karte ist , die aufgenommen werden können. Okay, klicken wir also mit der rechten Maustaste auf Spieler und fügen einen untergeordneten Knoten hinzu. Wir werden nach Bereich zwei D suchen, und ich könnte es so etwas wie Gravitationsbereich zwei D nennen . Ich habe darüber nachgedacht, es Pickup Gravity Two D zu nennen, aber wir wollen das Skript etwas allgemeiner gestalten , weil es später Fälle geben kann denen Sie möchten, dass die Schwerkraft auf etwas angewendet wird, das kein Pickup ist, und das spezifische Gewicht der Aufnahme handhaben wird nur durch die Kollisionsform gesteuert. Der Umgang mit der Tatsache, dass es zum Anvisieren Pickups dient, wird einfach von den Kollisionsebenen gesteuert Alles, was Sie tun müssen, um Pickups ins Visier zu nehmen, ist hier Maske 5 für die Pickups-Ebene auszuwählen. Lassen Sie uns die erste Ebene für die Position ausschalten, auf der sie sich befindet, und sie nur zur Überwachung Okay, das ist also unser Setup. Dann müssen wir es nur noch im Gravitationsbereich auf alle Objekte anwenden, die es erkennt. Innerhalb des Schwerebereichs klicken wir also mit der rechten Maustaste. Bevor wir den Inspektor verlassen, sehen wir uns diesen Gravitationsbereich an, da ist die Schwerkraft im Bereich zwei D eingebaut, aber die Sache ist die, die für starre Körper zwei Ds gilt, bei ist die Schwerkraft im Bereich zwei D eingebaut, aber die Sache ist die, denen es sich um vollständige physikalische Objekte im Spiel handelt, und wir wollen nicht, dass denen es sich um vollständige physikalische Objekte im Spiel handelt, 1.000 starre Körper auf dem Bildschirm herumschweben. Anstatt also die Standardphysik zur Steuerung der Schwerkraft unserer Pickups zu verwenden , wollen wir einfach ein einfaches Skript bei dem wir es einfach dorthin bringen wo sich der Spieler im Mittelpunkt befindet. Und wir sollten uns überhaupt nicht mit zwei Ds mit starrem Körper befassen. Es handelt sich also im Wesentlichen um eine Leistungsoptimierung. Wir benötigen nicht für jeden unserer Pickup-Artikel die vollständige Physik. Sie existieren nur, um vom Spieler abgeholt zu werden. in den Spieler zu saugen ist also völlig in Ordnung, sie direkt Also klicke ich mit der rechten Maustaste auf Gravity Area Two D und wir hängen ein Skript Natürlich nenne ich diesen Gravitationsbereich zwei D. Lassen Sie uns diesen Klassennamen erstellen. Natürlich Gravitationsbereich zwei D. Okay, solange sich ein Objekt innerhalb der Zone befindet, wollen wir es verfolgen und ihm eine konstante Bewegung zuweisen. Dabei im Grunde einen weiteren Knoten zwei D über den Bildschirm in Richtung des Mittelpunkts dieses Bereichs zwei D, der Gravitationsfläche zwei D. Also lasst uns eine lokale Variable haben Ich nenne es Ziele, und das wird ein Array von Knoten zwei sein. D ist in Ordnung Funktion bereit ist, wollen wir zwei D mit dem Signal dieses Bereichs verbinden . Also sagen wir eingegebener Bereich, Punkt verbinden, Unterstrich auf eingegebenem Bereich Wir stellen auch eine Verbindung zum ausgehenden Bereich her, Punkt verbinden mit dem Bereich , der verlassen wurde Wir müssen diese Funktionen jetzt erstellen. Funktion unterstreicht den eingegebenen Bereich, und das gibt uns Bereich zwei D als Parameter Also P Bereich zwei D, wir versuchen es hier mit void. Okay, also was machen wir mit der Gegend hier? Wir werden es in Richtung des Mittelpunkts unseres Schwerpunktbereichs zwei D bewegen des Mittelpunkts unseres Schwerpunktbereichs . Das wird mit dem Tonabnehmer gut funktionieren, weil die Aufnahmebereiche an ihrer Wurzel in Bereich zwei D liegen. Also alles, was sich darunter befindet, wird automatisch in Richtung Zentrum bewegt , also setzen wir voraus , dass es so eingerichtet ist. Andernfalls benötigen Sie einen Verweis auf den übergeordneten Knoten der Szene. Was auch immer Ihre Basis Ihrer Pickup-Szene sein mag, es ist das Objekt oder der Knoten, der sich bewegen muss. Seien Sie sich dessen also bewusst. Da wir alle Tonabnehmer speziell auf diese und Tonabnehmer nur auf Ebene fünf verfügbar sind, wird es so wie es ist einwandfrei funktionieren Wenn du besonders sicher sein willst und es nur auf Pickup-Skripte beschränken willst , dann könntest du natürlich überprüfen, ob der P-Bereich vom Typ Pickup two D ist . Es scheint nicht notwendig zu sein, so wie es jetzt ist, aber das ist etwas , das du beachten solltest Also werde ich da oben einfach einen kleinen Kommentar zu dem machen, was ich gerade gesagt habe. Okay, und seit der P-Zone gibt es solche Pickups. Ich werde gut arbeiten, so wie es ist. Ich würde also sagen, Ziele stehen auf einem Stift, einem P-Bereich. Denken Sie daran, dass P-Bereich zwei D vom Typ Knoten zwei D ist, also funktioniert das hier oben einwandfrei. Es ist nicht nötig, genauer zu sein , da wir nur auf die D-Funktionen von Knoten zwei zugreifen müssen . Also bei Verlassen des Bereichs, Funktion, Unterstrich beim Verlassen des Bereichs P-Bereich zwei D, gibt ungültig zurück, dann sagen wir Ziele, Punkt löschen Nun zur Löschfunktion: Wenn das Objekt, das Sie aus dem Array löschen möchten , nicht in dem Array existiert, dann wird das nichts bewirken. Wenn es gelöscht wird, wird es entfernt. Es ist also eigentlich nicht nötig zu überprüfen, ob es sich bereits im Array befindet. Denn wenn es nicht im Array existiert, dann wird das schon einfach nichts bewirken. Es besteht also keine Notwendigkeit , dies noch einmal zu überprüfen. Richtig. Und dann brauchen wir einen physikalischen Prozess. Nehmen wir an, die Funktion unterstreicht den physikalischen Prozess, und wir sagen für ein Ziel in Zielen, wir ihn über den Bildschirm in Richtung des Schwerpunkts der Schwerpunktfläche übertragen wollen Richtung des Schwerpunkts der Schwerpunktfläche Wir benötigen eine Geschwindigkeit an der Spitze beim Export, weit die Schwerkraft ist ein Float Wenn ich mich recht erinnere, wird das in Pixeln pro Sekunde ausgedrückt. Also werde ich etwas wie 50,0 versuchen. Dann müssen wir die Richtung zwischen dem Ziel und unserem Gravitationsflächenmittelpunkt berechnen zwischen dem Ziel und unserem Gravitationsflächenmittelpunkt Bisher entspricht die Richtung der globalen Position des Zielpunkts der Punktrichtung zwei der globalen Position. Okay? Und dann müssen wir nur noch unseren Umzugsbetrag berechnen. Bewegung von var entspricht also Richtung mal der Schwerkraft, der Geschwindigkeit und dem Delta. Da wir Translate verwenden, müssen wir das direkt hier für den endgültigen Bewegungsvektor berücksichtigen . Wir können sagen, dass dies ein Faktor zwei D ist, wenn das klarer wird. Und dann wollen wir das Ziel nehmen und es mit dem Verschiebungsversatz über den Bildschirm übertragen. Das ist im Grunde unser Gravity-Skript. Das Letzte, was wir meiner Meinung nach brauchen, ist, unserem Gravitationsbereich eine Kollisionsform hinzuzufügen . Klicken Sie also mit der rechten Maustaste auf den Gravitationsbereich zu D, fügen Sie eine Kollisionsform zu D hinzu. Gehen Sie nach oben rechts, eine neue Kreisform und machen Sie diese ziemlich groß, sodass wir den Bereich haben , in dem die Schwerkraft tatsächlich auf den Mittelpunkt angewendet wird . Okay, ich kann spielen, und wir gehen hier rein und Sie können sehen , dass unsere Objekte in Richtung Zentrum gezogen werden Also momentan ist die Schwerkraft linear. Vielleicht möchten wir ihr eine Kurve geben , sodass sie , je näher sie dem Mittelpunkt kommt , desto schneller animiert sie diese Translation tatsächlich zum Mittelpunkt hin Gehen wir also zum zweiten Gravitationsbereich D, und innerhalb dieses Bereichs sage ich beim Export, sagen wir Effektkurve vom Typ Kurve. Das speichern wir. Dann bearbeiten wir im Inspektor diese Effektkurve, neue Kurve. Und dann wollen wir, dass X oder die maximale Domäne hier im Grunde die Entfernung vom Zentrum ist. Und dann gibt der Wert hier an, wie viel Prozent der Höchstgeschwindigkeit Sie basierend auf dieser Entfernung anwenden möchten. Nehmen wir also an, dass die Entfernung hier für die maximale Domäne etwa 100 beträgt . Je näher es ist, desto näher wollen wir an 1,0 herankommen. Nehmen wir also den ersten Punkt und verschieben ihn hier auf 1,0. Ich zoome hier rein, damit du es sehen kannst. Und dann ziehe ich einfach so einen zweiten Punkt nach unten. Okay. Wenn es also eine Entfernung von 100 erreicht, wird es an diesem Punkt sehr schwach sein. Und das würde natürlich in Pixeln gemessen werden. Mit dieser Kurve wollen wir also wieder reingehen und die Bewegung anpassen , indem wir diese Kurve abtasten. Nehmen wir also den Kurvenmodifikator, und das entspricht dem Punktmuster der Effektkurve Und wir müssen die Probe mit der Entfernung von unserem Ziel zum Gravitationszentrum abtasten Vara-Entfernung wird also Zielpunkt globale Position, der Punktabstand zur globalen Position sein Punktabstand zur globalen Position Okay, wir geben diese Entfernung einfach in die Stichprobe des Kurvenmodifikators und dann nehmen wir den Kurvenmodifikator und multiplizieren ihn mit dem Delta Das wird also ein Wert zwischen 0,0 und eins sein. Und das sollte die Schwerkraft basierend auf dieser Kurve beeinflussen. Je näher es ist, desto stärker ist es. Und hier drüben wird es schwächer. Fühlen Sie sich frei, eine Kurve anzupassen , wenn Sie die Form der Animation ein wenig ändern müssen . Okay, also ich drücke hier auf Play und wir werden das irgendwie testen. Es ist ein bisschen schwer zu erkennen, weil ich die maximale Entfernung hier vielleicht zu groß gewählt habe. Sie können also die Kollisionsform überprüfen und sehen, wie groß ihr Radius ist. Also 27 Pixel. Wir erstellen also im Grunde eine Kurve für bis zu 100 Pixel, aber das Maximum dieses Radius beträgt 54 Pixel, hier 27. Oh, wirklich, nein, nein, 27 Pixel, weil es von der Mitte zum äußeren Punkt geht, oder? Natürlich nicht der Durchmesser. Ja, vielleicht möchte ich den Radius hier nehmen und einfach 30 Pixel daraus machen, eine schöne gerade Zahl, und dann gehen wir zum Gravitationsbereich. Und dann nehmen wir den Kurvenpunkt hier und verschieben ihn ebenfalls auf 30 Pixel. Okay, das ist quasi unsere maximale Entfernung für diese Form hier drüben. Es müssen nicht perfekt 30 sein. Ungefähr hier, damit wir die Form etwas besser erkennen können . Okay, wenn ich jetzt auf Play drücke und wir hier rüber gehen, sollte es etwas genauer sein. Okay, jetzt können Sie sehen, wie die Schwerkraft wirklich zunimmt, je näher sie kommt, also ist sie von außen langsam, fast zu langsam Vielleicht ziehe ich das ein bisschen nach oben und Sie können die Form der Kurve anpassen, und Sie können die Form der Kurve anpassen indem Sie an den Griffen ziehen, was auch immer Sie tun müssen. Siehst du, das gefällt mir irgendwie. Zum Testen drücken wir noch einmal auf Play. Und ja, ich denke, das ist richtig für die Schwerkraft. Also da hast du's. Skalierung der Schwerkraft. Je näher dein Objekt an die Oberfläche kommt, desto schneller bewegt es sich und saugt alle Gegenstände auf, die du hier auf der Maskenebene markierst, oder wirklich alle Bereiche, die du auf der Maskenebene markierst In diesem Fall sind das momentan nur Tonabnehmer, aber das könntest du auch mit anderen Bereichen machen 37. P36 Erstellen einer Player-Benutzeroberfläche mit HP- und EXP-Fortschrittsbalken: Okay, obwohl der Hauptkampf im Spiel funktioniert, können wir Gegenstände wie EXP-Pickups einsammeln, aber wir haben keinen Hinweis auf der Benutzeroberfläche, was vor sich geht Wir können die Stufe unseres Charakters, unsere HP und unsere EXP-Leiste nicht sehen HP und unsere EXP-Leiste Also werden wir damit beginnen, an der EXP-Leiste zu arbeiten und, sagen wir, oben links auf dem Bildschirm einen Levelzähler hinzuzufügen sagen wir, oben links auf dem Bildschirm Und das werden wir auf einem neuen Knoten machen. Also gehe ich hier hoch in den mittleren Bereich und füge eine neue Szene hinzu. Und wir wollen, dass das eine Benutzerschnittstelle ist. Also werde ich das Player-UI nennen. Speichern wir es im UI-Ordner. Und speichere es dort. Dann klicke ich auf die Player-Benutzeroberfläche und wir fügen, sagen wir, einen Panel-Container hinzu. Das wird also im Wesentlichen der Hintergrund für unsere Haupt-Player-Benutzeroberfläche sein . Sie sagen nun, dass sich die Player-Benutzeroberfläche standardmäßig über den gesamten Bildschirm erstreckt. Also wollen wir in das Layout auf der rechten Seite gehen und das Preset „Anchors“ von „ Full Wrecked“ auf „Oben links“ ändern Okay, das wird die Größe hier im Grunde auf Null reduzieren. Und dann wollen wir die Größe der Behälter bestimmen horizontale Füllung und die vertikale Größe erweitern Dann möchten wir unter unserem Panel-Container mit der rechten Maustaste klicken und einen neuen, sagen wir, einen V-Box-Container hinzufügen . Ein VBox-Container organisiert seine untergeordneten Objekte vertikal. Wenn Sie hier also zwei Elemente einfügen, wird das Objekt, das sich direkt darunter befindet vom visuellen Layout her überlagert Klicken wir also mit der rechten Maustaste auf den VBox-Container, und jetzt möchte ich einen HBox-Container Unser HBox-Container, der erste, wird also von links nach rechts verschoben, und dieser wird über allen anderen untergeordneten Es hilft uns also, die Dinge fast wie ein Raster anzuordnen , aber nicht exakt Okay, und als Kind für den HBox-Container wollten wir einen Textur-Fortschrittsbalken hinzufügen, damit Sie nach Progress suchen können und genau hier fündig werden Auf diese Weise können Sie oben rechts Texturen für die Untertextur, die Übertextur und die Fortschrittstextur festlegen Übertextur und die Fortschrittstextur Wenn sich die Werte füllen, wird tatsächlich mehr oder weniger von der Fortschrittstextur angezeigt , und darunter befindet sich dann die Basistextur, die immer im Hintergrund zu sehen ist. Okay, und zusätzlich dazu wollen wir ein Label rechts davon haben. Also klicke ich mit der rechten Maustaste auf den HBox-Container und füge ein Etikett hinzu. Ein einfaches Etikett sollte hier in Ordnung sein. Wir können es später jederzeit in ein Rich-Text-Label ändern. Okay, und jetzt für diesen Textur-Fortschrittsbalken wollen wir die Grafik für unseren Fortschrittsbalken finden. Lassen Sie uns also alles unten rechts minimieren und den Kunstordner erweitern. Gehen wir zur Crimson Fantasy GUI. Und ich glaube, es war hier unter GI Sprite. Also werde ich oben rechts für unten eine neue Atlas-Textur erstellen und diese dann erweitern Und lassen Sie uns GI Sprite hier in den Atlas ziehen. So können wir den vollständigen Atlas sehen, ziemlich cooler gotischer Kunststil, der hier vor sich geht Und wir können wählen, wie unsere Untertextur aussehen soll. Die Untertextur wird also im Grunde unser Balken sein , in dem sie völlig ungefüllt ist Wenn ich also einen Bereich bearbeite, kann ich hier hineinzoomen und diesen auswählen, aber genau hier, also so, das kann unsere Untertextur sein, indem ich auf „Schließen“ klicke Und was das Etikett angeht, sagen wir für den Moment einfach Null von 100 PS, nur als Modell. Jetzt ist es also sinnvoll, diesen HBox-Container umzubenennen, so etwas wie HP Display Und lassen Sie uns ihn duplizieren, und dann benenne ich den zweiten in EXP-Display um Gehe zum Textur-Fortschrittsbalken. Und in den Texturen wählen wir eine andere aus dem Bearbeitungsbereich aus. Schauen wir uns also an, was uns hier als EXP-Leiste gefällt? Wir könnten diesen einfachen hier verwenden, aber ich denke, es könnte tatsächlich hilfreich sein , wenn wir verschiedene Blöcke sehen könnten Mit diesem könnten wir also von sieben sehen, wie nahe wir einem tatsächlichen Levelaufstieg sind Aber du wirst feststellen, sobald ich den Wert hier für diesen ändere, auch der oberste Wert automatisch aktualisiert da wir eine gemeinsame Atlas-Texturressource verwenden Was wir hier also tun müssen, ich werde schließen, ist, mit der rechten Maustaste auf diese Textur zu klicken und sie dann einzigartig zu machen. Wenn Sie das also tun, wird diese Textur einzigartig sein. Wir müssen zum ersten zurückkehren und es reparieren, mit der rechten Maustaste klicken und dann Unique machen, und wir müssen die HP-Textur wieder auf ihre HP-Textur umstellen. Also hier wählen wir das HP-Schnäppchen aus, und jetzt können wir sehen, dass es sich um zwei verschiedene Dinge handelt Okay, jetzt machen wir auch das Ausfüllen für das oberste. Ich werde hier weitermachen, neue Atlas-Textur, und dann können wir schnell aus dem Drop-down-Menü unser GUI-Sprite laden dem Drop-down-Menü unser GUI-Sprite Und jetzt wollen wir die Region bearbeiten, und wir wollen uns hier die ausgefüllte Gesundheitsleiste holen Okay, das wird ungefähr so aussehen und dann auf Schließen klicken. Jetzt, wo wir die Textur festgelegt haben, wenn du, sagen wir, hier zum Wert gehst und 50 eingibst, wirst du sehen, dass ein Teil der Gesundheitsleiste jetzt gefüllt ist. Aber ihr seht auch, dass das bei diesem Setup teilweise daran liegen kann das Herz Dinge versteckt, aber es scheint nicht wirklich so, als ob es 50% eurer gesamten Gesundheit hier genau wiedergibt 50% eurer gesamten Gesundheit , wenn der Wert 50 ist. Um das zu umgehen, habe ich den Wert für Männer so geändert, dass er etwa negativ 20 ist dass er etwa negativ 20 , um das irgendwie nach rechts zu kompensieren. Jetzt können Sie also sehen, dass es vier von acht sichtbaren Gesundheitsbrocken Dieser Wert von 50 ist also viel sinnvoller , wenn Sie dort einen negativen Offset von 20 haben negativen Offset von 20 Also musst du das vielleicht nur irgendwie anpassen. Wenn Sie also Null Gesundheit charakterisieren, wird das natürlich zeigen, dass Null der Wert ist, der hier drüben sein wird Aber was wirklich zählt, sind die 50 von 100 hier und die 100 von 100 dort Nur um sicherzugehen, dass wir einen Wert 100 für einen vollständig ausgefüllten Gesundheitsbalken haben, und das sieht gut aus. Wir können 20 sagen. Wir können immer noch unsere Gesundheit sehen. Und selbst mit fünf oder zehn, naja, ich schätze, mit fünf müssen wir es nicht unbedingt sehen. Aber wie bei zehn können wir immer noch einen winzigen Splitter sehen. Ich finde, so wie es jetzt ist, ist es ziemlich gut. Also können wir die Standardeinstellung einfach bei 50 belassen. Und lass uns an der EXP-Display-Textur arbeiten. Klicken wir hier einfach mit der rechten Maustaste auf die Basis unter Textur, kopieren und dann mit der rechten Maustaste auf den leeren Fortschritt klicken und ihn einfügen Dann wollen wir hier mit der rechten Maustaste klicken und es einzigartig machen und es auf den Wert ändern, den wir benötigen. Bearbeiten Sie also die Region und wir möchten diese ausgefüllte Version dieser Leiste abrufen. Okay? Und wir können 50 für den Testwert eingeben. Okay, und dann können wir sehen, dass das zur Hälfte ausgefüllt ist. Also das ist in Ordnung Wir müssen bei dieser Version der Textur keinen negativen Mindestwert angeben. Es gibt hier ein kleines Problem, bei dem unser Fortschrittsbalken für die XP rot ist, genau wie der oben. Was wir also eigentlich tun wollen, ist , dass dieser Metallteil in einer anderen Farbe getönt wird können wir also tun, indem wir hier zur Fortschrittsfarbe übergehen und die Farbe auf Grün umstellen, quasi so Aber Sie können sehen , dass dadurch tatsächlich die gesamte Textur getönt wird Wir möchten also mit der rechten Maustaste auf die Untertextur klicken, die Kopiertaste drücken und sie dann in die Übertextur einfügen Okay, jetzt werden nur die Pixel , die auf der Unter- und Oberseite nicht existieren , die auf der Unter- und Oberseite nicht existieren, von der Änderung der Fortschrittstextur betroffen sein . Welche Farbe auch immer Sie für den Fortschritt haben möchten, Sie können ihn einfach so ändern , indem Sie hier einfach den Farbton manipulieren Kann die Dunkelheit ändern, und das ist wahrscheinlich gut genug für deine XP-Leiste, um ehrlich zu sein, da es die einfachste Lösung ist, ohne einen Shader oder so zu verwenden Wenn wir also jetzt zum Label gehen, wollen wir das in EXP ändern Also Null von 100 EXP. Okay, und dann wollen wir diese Textur-Fortschrittsbalken vertikal zentrieren Ich denke, Sie können beide gleichzeitig auswählen , wenn Sie die Strg-Taste gedrückt halten und mit der linken Maustaste klicken und dann zur Layoutcontainergröße wechseln und sie von „Vertikal füllen“ auf „Mitte verkleinern“ ändern Vertikal füllen“ auf „Mitte verkleinern Ja. Okay. Und dann nimmt das im Grunde genommen diese, und es konzentriert sich auf die anderen Elemente wie dieses Etikett hier auf der rechten Seite. Das wird also gut aussehen. Dann wollen wir nur den Text verkleinern. Was wir also vielleicht tun möchten, ist einfach zur Player-Benutzeroberfläche im Stammverzeichnis zu gehen und das Thema zu ändern wenn wir unser Spielthema schnell aus dem Drop-down-Menü laden Dann wird es diese Pixel-Art-Schrift haben, die bereits standardmäßig etwas kleiner ist. Okay, als letztes, um unser Modell abzuschließen, wir wollen wahrscheinlich einen Randcontainer, der für den Panel-Container sichtbar Klicken Sie also mit der rechten Maustaste auf die Roots, Player-UI, und fügen Sie einen Randcontainer hinzu Suchen Sie also nach dem Rand und ziehen Sie dann den Panel-Container darunter. Dann können Sie jetzt im Randcontainer zu den Theme-Overrides für die richtigen Konstanten wechseln und einen Rand anpassen Ich nehme also fünf für alle Seitenränder. Okay, irgendwie so. Also das ist wahrscheinlich eine ausreichende Marge, aber ich habe die Bestellung tatsächlich falsch verstanden. Der Panel-Container befindet sich unter der Player-Benutzeroberfläche, und dann befindet sich der Margin-Container unter dem Panel-Container, und dann befindet sich der VBox-Container darunter Okay, der Punkt ist also, dass wir wollen, dass der Panel-Container das Hintergrundbild hier bis zu den Rändern ausdehnt, und dann wollen wir, dass alles andere irgendwie darin enthalten Deshalb muss sich der Randcontainer innerhalb des Panel-Containers befinden, damit sich der Panel-Container weiter ausdehnen kann als der Randcontainer. Es ist nur eine ordnende Sache. Das wird also ziemlich anständig. Lass es uns in unsere Welt bringen. also in unserer Weltszene Lassen Sie uns also in unserer Weltszene eine Canvas-Ebene erstellen, unter der die Benutzeroberfläche platziert wird. Klicken Sie also mit der rechten Maustaste und fügen Sie jetzt einen Canvas-Ebenenknoten hinzu. Okay, und der Grund, warum Sie hier eine Leinwandebene haben würden , ist, dass Sie dadurch einen separaten Renderbereich von allem anderen in der Szene erhalten. Die Benutzeroberfläche wird also völlig unabhängig von der Toti-Spielwelt gerendert völlig unabhängig von der Toti-Spielwelt Und das wäre wichtig, wenn Sie beispielsweise Toti-Spiellichter haben und Sie möchten, dass sich das überhaupt nicht auf die Benutzeroberfläche auswirkt Sie möchten, dass diese separat gerendert werden. Die Lichter für die Welt sind also anders wenn Sie irgendwelche Lichter für die Benutzeroberfläche haben würden, das wäre eine separate Sache. Und du verwaltest sie einfach getrennt. Also werde ich jetzt die Player-Benutzeroberfläche hier hinzufügen wollen, also filtere deine Dateien, suche nach Player-Underscore-UI, falls du das als Namen angegeben hast, die Szene mit Dragon auf die Canvas-Ebene und sie wird genau dort oben links auf unserer Benutzeroberfläche Bevor wir auf Play klicken, stellen Sie sicher, Player-Benutzeroberfläche unter der Canvas-Ebene befindet Das wird wichtig sein, damit es nicht auch in der Spielwelt gerendert wird, sondern als Teil des Bildschirms. Also ist es da oben links. Es ist eigentlich ziemlich klein. Das ist ziemlich lustig, wenn ich ehrlich bin. Wir können die Benutzeroberfläche entweder hier hochskalieren oder wir können sie in der Basisszene vergrößern Also vielleicht möchte ich einfach die Canvas-Ebene hier nehmen und wir transformieren, den Maßstab auf etwa vier X erhöhen. Sie können die Ansicht verkleinern. Haltet nach der lila linierten Schachtel Ausschau. Vielleicht musst du die Bodenwelt verstecken, um sie wirklich sehen zu können. Okay, da. Also haben wir die lila Kiste hier. Dies ist der Bereich mit voller Aussicht auf den Hafen. Ihre Benutzeroberfläche hier bezieht sich also irgendwie darauf. Also bei vierfacher Skalierung funktioniert das meiner Meinung nach ziemlich gut. Jetzt zeige ich wieder den Dreck und das Gras. Wir klicken auf Play. Und mal sehen , ob die Benutzeroberfläche oben links schön ist. Und ich denke, diese Größe ist eigentlich ziemlich anständig. Das gefällt mir sehr Das behalten wir vorerst bei und arbeiten dann daran, es auszuarbeiten 38. P37 Implementieren eines statistikbasierten Benutzeroberflächensystems mit Signalen: Damit diese Benutzeroberfläche tatsächlich funktioniert, müssen wir sie an Signale anschließen, die sich auf unseren Sp-Block für Charaktere beziehen. Das heißt, wir benötigen zum Beispiel ein geändertes EXP-Signal oder ein geändertes HP-Signal Wir möchten sicherstellen, dass wir das aktualisieren. Wir haben auch ein weiteres kleines Problem, nämlich dass diese Benutzeroberfläche auf dem Bildschirmbereich, in dem sie sich gerade befindet, im Grunde sehr groß ist. Also möchte ich schnell ein Skript hinzufügen, in dem ich es einfach so einrichten kann , dass die Canvas-Ebene automatisch angezeigt wird , wenn das Spiel startet, aber wir können es optional einfach ausschalten, wenn wir ein Editor sind Ich möchte also nicht immer die Sichtbarkeit manuell einschalten müssen Sichtbarkeit manuell einschalten Ich klicke mit der rechten Maustaste auf die Canvas-Ebene hier drüben und füge ein Skript hinzu. Das wäre also nur Canvaslayer Dot GD. Speichern wir das im UI-Ordner Bin. Erstellen. Und ich sage einfach, Funktion Underscore bereit. Es wird ungültig zurückgeben, und dann sagen wir, sichtbar ist gleich wahr Und das ist alles, was wir dafür brauchen. Jetzt können wir es ausblenden , wenn wir uns unsere Kartenansicht hier ansehen und auf Play klicken. Und es sollte immer noch auftauchen, sobald das Spiel beginnt. Jetzt können wir es hier in unserer Kartenansicht verstecken, Play klicken und es wird immer noch angezeigt, sobald das Spiel beginnt. Also, in der oberen linken Ecke, da ist es. Das wird also bei der Bearbeitung hilfreich sein. Eine andere Möglichkeit, damit umzugehen, wäre, dass Sie eine völlig separate Szene für Ihre Canvas-Benutzeroberfläche haben eine völlig separate Szene für , wenn Sie diese bearbeiten, dann Ihre Weltszene, und Sie kombinieren sie in einer übergeordneten Szene. Wenn du die Spielwelt tatsächlich hochlädst , wäre das in Ordnung. Und vielleicht wäre das die langfristige Lösung. Aber das ist einfach eine wirklich nette, schnelle und einfache Lösung. Lasst uns also daran arbeiten, unsere Spieler-Benutzeroberfläche mit den Spielerstatistiken zu verbinden . Lassen Sie uns also in die Szene mit der Spieler-Benutzeroberfläche springen. Ich klicke mit der rechten Maustaste auf die Player-Benutzeroberfläche. Und füge ein Skript hinzu. So kann der Playi Dot gD die Steuerung und das Innere erweitern. Wir sind einfach bei einem Export R und wir sagen Kontext des Spielerkontextes Da wir diese Ressource bereits erstellt haben, ist sie sehr einfach zu verwenden. Und der Inspektor hier oben rechts lädt einfach schnell den Spielerkontext. Und falls du dich noch an den Anfang des Kurses erinnerst, wird sich der Spieler automatisch selbst dort einstellen, sodass wir uns einfach den Kontext-Punkt Spielerpunktstatistiken schnappen können, und bumm, wir haben einen Verweis auf die Statistiken. Wir benötigen lediglich Signale, um das HP-Display und das EXP-Display zu aktualisieren Okay, also können wir die Statistiken nachschlagen. Mal sehen, Stat Controller Punkt GD. Wenn wir in das Drehbuch springen, hat sich unser Leben verändert. Lassen Sie uns einige Signale dafür erstellen, dass HP sich geändert hat, Max HP sich geändert hat und sich die Erfahrung geändert hat. Okay, also das Signal Mx HP hat sich geändert. Und Sie können sehen, dass dies eine Menge Statistiken sind, die wir mit einem sehr ähnlichen Typ ändern werden. Vielleicht möchten wir das Objekt, das geändert wurde, den alten Wert, den neuen Wert und den Änderungsbetrag übergeben den alten Wert, den neuen Wert . Wir können also tatsächlich eine Klasse erstellen, die alle unsere Statistiken kapselt , die sich ändern werden Und das ist ein sehr statistisches Spielsystem, wie Survivor, richtig, weil du vielleicht eine Reduzierung der Abklingzeit hast, du hast vielleicht die Bewegungsgeschwindigkeit der Spieler, HP, Angriffskraft, all diese zusätzlichen Dinge Und das sind alles Statistiken, die innerhalb eines Objekts dargestellt werden könnten , das wir dann in ein Ereignis umwandeln können Es ist auch viel einfacher, wenn Sie nur einen Parameter haben , sodass Sie diesen Parameter senden und sie ihn dann als Teil empfangen, anstatt als drei oder vier. Um zu zeigen, was ich meine, lassen Sie uns ein neues Skript in unserem Dateisystem erstellen . Also werde ich alles zusammenklappen und dann gehen wir, sagen wir , weil Objekte Statistiken haben. Also klicke ich mit der rechten Maustaste und erstelle ein neues Skript. Das werden also Daten sein, die als Signal gesendet werden, wenn sich eine Statistik ändert. Ein ziemlich klarer Name wäre also stat changed data dot gD. Das schaffen wir. Okay, und lassen Sie uns das Drehbuch öffnen. Also, Stat hat die Daten geändert. Klassenname, Stat hat die Daten geändert. Und das gilt auch für Ref Counted, ein Objekt, das automatisch aus dem Spiel gelöscht wird, wenn es nicht mehr referenziert wird. Also Referenzen. Und anstatt nein zu erweitern, wird das tatsächlich von ref count ausgehen, was ein Gadot-Objekt ist, das nachverfolgt, wie viele Objekte es referenzieren Und wenn keine Objekte mehr darauf verweisen, stellt es sich quasi von selbst in die Warteschlange zum Löschen, sodass Sie es nicht manuell freigeben müssen Es wird einfach von der Engine aufgenommen und gelöscht. Das ist übrigens auch die Standardklasse, wenn Sie nicht von einer Klasse aus erweitern, das ist auch die Standardklasse. Okay, also unsere Statistik hat Daten geändert, wir wollen ihr eine Initialisierungsfunktion geben, also die Funktion unterstreicht eine Und wenn wir eine NIT für ein Objekt erstellen, können wir alle Parameter weitergeben, die wir benötigen Also sage ich P-Objekt, das Objekt, das wir mit unserer Statistikänderung beeinflussen. Also kein TD, der P Nu-Wert , der meiner Meinung nach momentan eine Ganzzahl sein wird. Es könnte eine Float-Statistik geben. In diesem Fall könnten Sie diesen Typ in eine Variante ändern, könnten Sie diesen Typ in eine Variante ändern sowohl Integer als auch Float unterstützt. Aber ich glaube nicht, dass es im Spiel momentan tatsächlich Floats für Statistiken wie Erfahrung und HP geben wird Spiel momentan tatsächlich Floats für Statistiken wie Erfahrung und HP Wir haben daraus eine konkrete Ganzzahl gemacht, was wahrscheinlich sowieso vorzuziehen ist Also, den neuen Wert, den wir übergeben, und dann wollen wir den alten Wert. Und wenn wir den neuen und den alten Wert haben, können wir die Änderung automatisch berechnen. Geben wir also die Zustandseigenschaften für dieses Objekt ein. Ich würde sagen, das var-Objekt wird ein Knoten zwei D sein, das var new wird eine Ganzzahl sein. Das alte Var wird eine Ganzzahl sein. Die Var-Änderung ist ebenfalls eine Ganzzahl. Wenn wir also die Funktion initialisieren, nehmen wir einfach die Parameter und setzen die lokalen Variablen auf diese Werte Das Objekt wird also dem P-Objekt entsprechen. Ein neues wird gleich P Nu sein, alt wird gleich P alt sein. Jetzt, wo wir den neuen und den alten Satz haben, wird unsere Änderung gleich dem Neuen minus dem Alten sein, ich denke, das ist so, es sei denn, ich habe es umgekehrt. Okay, also wenn der alte Wert 30 und der neue Wert 20 ist, dann wird die Änderung negativ zehn sein, was wir hier wollen. Also ja, neu minus alt. Also, was wir hier tun, ist, dass wir diese vier Parameter als ein von St geändertes Datenobjekt an das Signal übergeben diese vier Parameter . Und dann können wir auf dem Signalempfänger, der Callback-Funktion, auf alles innerhalb von St zugreifen, das in Theta geändert wurde, indem wir einfach St changed data dot object, dot new dot CAGE ausführen new dot CAGE Und das alles brauchen wir vielleicht nicht, aber wir haben Zugriff darauf Außerdem, wenn wir hier jemals etwas anderes wie var Cookie hinzufügen, was eine Textur oder etwas Ähnliches ist, dann müssen wir das nicht als zusätzlichen Parameter hinzufügen. Es ist in dieser Klasse enthalten. Sie können dieses Objekt also ändern, ohne Ihre Callbacks oder den Sendesignalparameter ändern zu müssen Ihre Callbacks oder den Sendesignalparameter , da Sie nur ein Objekt senden Hoffentlich macht das Sinn. Es ist einfacher , es im Laufe der Zeit zu ändern. Wie dem auch sei, wir haben unsere Statistiken geändert. Wenn wir also zu unserem Stat-Controller-Skript zurückkehren, können wir jetzt unsere Signale erstellen. Max HP hat also geändert, dass die Daten der Statistik geändert werden. Okay, und dann machen wir einfach das Signal für das andere Signal, HP hat Daten geändert, Statistik hat Daten geändert, Signalerfahrung hat sich geändert. Data Stat hat Daten geändert. Der Grund, warum ich für jeden von ihnen ein Signal setzen würde , ist, dass wir im Empfangsskript wählen können, welche Statistiken uns wirklich wichtig sind. Also zum Beispiel kümmert sich die EXP-Anzeige hier nur darum, dass sich das Spielerlebnis ändert Wir stellen also nur eine Verbindung zum Signal mit geändertem Erlebnis und vielleicht auch zu einem Signal mit geändertem Pegel her, um die Pegelbezeichnung zu aktualisieren, wenn das Signal im selben Anzeigebereich angezeigt wird geändertem Erlebnis und vielleicht auch zu einem Signal mit geändertem Pegel her, um die Pegelbezeichnung zu aktualisieren , wenn das Signal im selben Anzeigebereich angezeigt Wir haben also diese Signale. Wir müssen sie nur aussenden. Also, was ich vorher mit dem HP-Setter hier gemacht habe, dem HP-Setter hier gemacht habe, wenn Sie nur den geänderten Wert ausgeben, denke ich, das ist eine akzeptable Verwendung eines Sets, sodass wir ausgeben, dass der Wert geändert hat, und es einfach zu einer beobachtbaren Eigenschaft machen Also sage ich hier, wann immer wir die HP setzen, sagen wir einfach, dass HP geändert wurde Nun, wenn wir auf HP 100 gesetzt werden , obwohl es schon immer wieder 100 ist, möchten wir vielleicht die Signalausgabe überspringen , sodass wir sagen können, ob HP dem Wert entspricht, dann kehren wir einfach zurück, weil wir hier nicht live aktualisieren müssen Wir müssen HP nicht aktualisieren, da es sich um denselben Wert Also nach diesem Muster werde ich im Grunde dasselbe mit MAX HP machen. Also machen wir Colon. In der nächsten Zeile den Wert festlegen. Wenn Mx HP dem Wert entspricht, kehren wir zurück. Andernfalls entspricht Max HP dem Wert und wir geben Max HP changed aus. Oh, aber hier unten habe ich vergessen, dass es hier nicht nur um den HP-Wert geht, sondern wir müssen tatsächlich das Datenobjekt mit der Änderung der Statistik erstellen Datenobjekt mit der Änderung der Statistik Daten entsprechen Stat, geänderte Daten sind punktneu. Und wir werden diese Objektreferenz hier oben für den Stat-Controller übergeben . Also Objekt, und dann geben wir den neuen Wert von HP und den alten Wert ein, den wir zuerst bekommen müssen. Bevor wir also den neuen Wert auf HP setzen, direkt davor, machen wir var Old equals HP, und jetzt geben wir den alten Wert hier und wir geben die Daten an die Signalemission Also hat HP den Punkt MMI mit den Daten geändert , und das ist alles, was wir tun müssen Und jetzt wird es diese vier Dateneigenschaften innerhalb dieses Objekts haben , anstatt nur eine, aber es sieht trotzdem super sauber aus, weil wir nur ein Objekt senden Okay, jetzt in MX HP wollen wir das noch einmal machen. Also sagen wir var Old entspricht Max HP, und dann machen wir far data equals stat changed data dot u. Also das Objekt, der Max hP und der alte, und dann geben wir das HP-geänderte Signal mit den Daten aus, und das war's Okay, also nach demselben Muster, noch einmal, hier unten in Experience, Doppelpunkt gesetzt, können wir uns immer noch davor schützen, wenn das Erlebnis derselbe Wert ist, nur für den Fall Wenn also Erfahrung gleich Wert ist, kehren wir zurück. Andernfalls ist das Alte gleichbedeutend mit Erfahrung, und dann entspricht Erfahrung Und dann sind Vara-Daten gleich den Daten, die sich geändert haben, Punkt gegen Objekt, das alt ist, und wir geben Erfahrung aus, die mit den Daten geändert wurde. Okay? Und ich könnte das hinzufügen. Oh ja, okay, ich habe das D oben für das Signal vergessen. Kontrolliere STA, und das sollte gut sein. 39. P38 Skripting dynamischer HP- und EXP-Anzeigen für die Player-Benutzeroberfläche: Wir haben also das Signal eingerichtet und wir haben hier unseren Kontext und die Player-Benutzeroberfläche, die es uns ermöglichen wird diese Signale aus dem Statistikblock Aber das müssen wir nicht wirklich direkt in der Player-Benutzeroberfläche tun. Wir müssen das auf dem HP-Display und dem EXP-Display machen. Also möchte ich hier unten Skripte für das HP-Display und das EXP-Display erstellen unten Skripte für das HP-Display und das EXP-Display Also klicke ich mit der rechten Maustaste auf HP Display, hänge ein Skript und wir können das in die Benutzeroberfläche einfügen, also HP Display Dot GD Großartig. Wir können das einfach vom Container aus erweitern. uns wirklich egal, um welche Art von Container es sich handelt, weil Sie eine Anzeige mit anderen Typen erstellen können. Vielleicht zeigen Sie Ihren HB eher vertikal als horizontal an. Sie können also eine andere Basisklasse verwenden, z. B. Container statt HBox-Container, und Sie können dann trotzdem den eigentlichen Knoten im HBox-Container erstellen den eigentlichen Knoten im HBox-Container Die Idee hier ist also, die Dinge einfach flexibel zu halten. Und ich sage Klassenname HP Display. Okay, in unserem HP-Display benötigen wir also einen Verweis auf die Statistiken des Player-Controllers. Wir könnten den Spielerkontext exportieren und ihn dann direkt hier für jedes der Displays abrufen. Wenn wir jedoch solche Dinge für jede Ihrer Unter-UI-Komponenten einrichten , wenn jede von ihnen eine Exporteigenschaft hat , die Sie festlegen müssen, wird es sehr schwierig, sie in die Szene zu ziehen , um sie wiederzuverwenden , weil Sie dann mit der rechten Maustaste darauf klicken und sie bearbeitbar machen und sicherstellen müssen, dass Sie alle individuellen Eigenschaften wie den Spielerkontext zuweisen . Jedem Unter-UI-Knoten direkt. Eine weitere Option, die vielleicht vorzuziehen ist, besteht darin, dass die Root-Player-Benutzeroberfläche den Spielerkontext oder das , was daraus relevant ist, den Statistik-Controller, in jeden seiner Unter-UI-Knoten Und dann müssen Sie nur noch sicherstellen, dass die Player-Benutzeroberfläche über ihre Unterkomponenten wie das HP-Display und das EXP-Display Bescheid weiß wie das HP-Display und das EXP-Display Aber dann lassen Sie die Benutzeroberfläche des Players die schwere Arbeit erledigen. Wie das also im Kontext unseres HP-Displays aussehen würde , wäre, dass wir unseren lokalen Stat-Controller benötigen. Also wenn unser Unterstrich den Stat-Controller angibt. Also machen wir das lokal, oder? Und dann erstellen wir eine Setter-Funktion, damit wir den Statistik-Controller über die Player-Benutzeroberfläche einstellen können den Statistik-Controller über die Player-Benutzeroberfläche einstellen Sagen wir, Funktion setzt Statistiken, und dafür wird ein P-Unterstrich-Statistik-Controller benötigt Welches ist der Typ Stat Controller. Ich kehre als ungültig zurück. Ich habe den P-Unterstrich für Parameter gesetzt, damit klar ist , dass diese Variable ein Parameter der Funktion ist Falls Sie hier oben einen anderen Statistik-Controller haben, wird es keine Verwechselung zwischen unserem lokalen Verweis auf den Stat-Controller und unserem Funktionsumfang geben, P unterstreicht Stat-Controller Also werden wir dafür diese Funktion zum Einstellen von Statistiken verwenden. Also ist Underscore Stats gleich P Underscore Stat Controller Okay, wir haben also unsere Methode für festgelegte Statistiken. Sie ordnet die Statistiken den Statistiken zu, was hier wegen des Unterstrichs privat ist Hover, das ist ein GD-Skript, also ist es nicht wirklich privat Es ist nur markiert, dass Sie nicht von außerhalb der Klasse darauf zugreifen sollten , aber Sie können es technisch gesehen immer noch Also haben wir unseren Statistiker hier. Wir wollen uns jetzt mit dem Signal verbinden. Das ist also das HP-Display. Und ich möchte sagen, dass HP aufgehängt wurde, Punkt Connect, und wir werden sagen, dass HP geändert wurde Und wir können auch sagen, die Statistiken unterstreichen MxHPHanged Und das kann einfach am Unterstrich auf Max HP geändert werden. Technisch gesehen haben beide Signale also dieselben Parameter, sodass wir nur eine Callback-Funktion verwenden könnten, wenn wir wollten Aber um es flexibel zu halten, gäbe es vielleicht Code , den wir anders machen möchten, je nachdem, ob es MaxHP ist oder ob HP geändert wurde Ich werde hier nur zwei Callbacks haben , also Auf Max hat HP geändert, was bedeutet, dass die P-Daten, die Statistik die Daten geändert haben wird, dieser Umsturz ist Statistik die Daten geändert haben wird, dieser Und was wir tun wollen, ist LUI zu aktualisieren. Also werde ich hier einfach eine Aktualisierungsfunktion erstellen, und dann machen wir dasselbe für on HP Changeed Also können wir das einfach hier runterkopieren und dann das Max-Bit entfernen. Also lösche viermal. Okay, das ist es. Jetzt brauchen wir eine Refresh-Funktion. Also sagen wir Funktionserneuerung. Und was wollen wir auf dem HP-Display machen? Wann immer sich die HP ändert? Wir möchten den Schiebereglerwert aktualisieren und wir möchten die Textbeschriftung aktualisieren. Wir wollen also grundsätzlich den Prozentsatz gesund für Prozent Gesundheit berechnen, und das ist eine Gleitkommazahl, die, sagen wir, dem Unterstrich der Statistik Punkt HP geteilt durch den Unterstrich der Statistik Punkt MAX HP entspricht Unterstrich der Statistik Punkt HP geteilt durch den Unterstrich der Statistik Punkt MAX Okay, dann können wir den prozentualen Gesundheitszustand dem Textur-Fortschrittsbalken zuweisen Sie können also sehen, dass wir jetzt einen Verweis auf die Texturleiste hier unten benötigen . Das einzige Mal, dass wir Verweis auf die Texturleiste einrichten , ist das erste Mal dass wir diese HP-Display-Szene erstellen. Vielleicht speichern wir das in einer separaten Szene in unserem Projekt, und die Hauptszene, die wir der Welt tatsächlich hinzufügen , ist die Player-UI-Szene. Aber ich denke, es ist absolut vernünftig , die Texturleiste und das Label hier zu exportieren. Es gibt auch andere Möglichkeiten, sich diese zu schnappen. Aber das ist die Methode, die ich verwenden werde. Also ich sage beim Export var progress ist ein Textur-Fortschrittsbalken. Und dann ist beim Export var label ein Label. Wenn wir also aktualisieren, können wir den Fortschritt nehmen und das Etikett nehmen und sagen, dass der Fortschrittspunktwert dem prozentualen Zustand entspricht Also lass mich sehen. Das sollte auf einer Skala von 0-100 liegen Und diese Berechnung ergibt Ihnen tatsächlich einen Wert von 0,021 0,0 Also wollen wir das mit 100 multiplizieren, um einen tatsächlichen Prozentsatz zu erhalten , also mal 100 Und ich bin mir nicht sicher, was die Reihenfolge der Operationen angeht. Also werde ich diesen Teil einfach abschließen, um sicherzugehen, dass er vorher mit Sicherheit ausgeführt wird Okay, und dann ist der Fortschrittswert unsere prozentuale Gesundheit von 0-100 als Dann müssen wir den Textwert auf dem Etikett festlegen. Der Punkttext auf dem Etikett wird also der Zeichenfolge entsprechen. Wir könnten einfach in Anführungszeichen HP, Prozent, aus einem Schrägstrich Prozent sagen , und dann ersetzen wir diese Werte ein Prozentzeichen und geben sie an eine Reihe von Werten weiter Die Werte, die wir verwenden werden , werden also aktuellen HP und die MX HP sein Mit anderen Worten, unterstreichen Sie den Punkt HP und unterstreichen die Statistiken den Punkt MAX HP Wenn Sie also möchten, dass dies anpassbar ist, können wir das mit Control X ausschneiden und es durch so etwas wie eine Textvorlage für Gesundheit ersetzen Dann könnten wir hier oben in der Exportleiste sagen, dass die Textvorlage „Gesundheit“ gleich sein wird, und dann mit Strg V das einfügen. Hier stehen immer noch diese Prozentsätze als Symbole für das Ersetzen. Also schreiben wir immer noch die Textvorlage Health in Prozent und dann die Anordnung der beiden Werte der Reihe nach, nämlich Unterstrich Statistik Punkt HP und dann Unterstrich Statistik Punkt Max Okay, das wird den Balken aktualisieren und wir werden den Text aktualisieren Also wollen wir das auch nennen, wann immer wir die Statistiken festlegen. Deshalb sage ich hier „Aktualisieren “, um sicherzustellen, dass wir, nachdem wir die Statistiken festgelegt haben, auch diesen Text sofort aktualisieren. Wir brauchen hier oben einen Doppelpunkt, um diese Funktion zu beenden, und das ist ziemlich gut. Jetzt müssen wir auf der rechten Seite für das Skript den Fortschritt und das Label zuweisen. Weisen Sie also den Textur-Fortschrittsbalken zu und weisen Sie das Label zu. Stellen Sie sicher, dass Sie diejenigen unter der HP-Leiste auswählen . Nun, das wird gut für das HP-Display sein. Wir wollen fast dasselbe Skript für das EXP-Display, aber es gibt ein paar Unterschiede Also werde ich A und Control C steuern, um alles in diesem Skript zu kopieren Wir gehen zum EXP-Display. Rechtsklick, Skript anhängen. Exp Display Dot gD klingt für mich gut. Wir ändern hier allerdings den Typ inherit in container wählen dann einfach alles aus und ersetzen es durch ein Control-V, das es einfügt Jetzt müssen wir den Klassennamen in EXP Display ändern. Unsere HealthText-Vorlage. Wir werden das Control R auswählen, um es durch die EXP-Textvorlage zu ersetzen Wählen Sie in dieser Health-Textvorlage den Text aus. Sie können darauf doppelklicken , um das Ganze auszuwählen. Und dann drücken Sie Control R. Hier unten werden wir die Textvorlage Health durch die EXP-Textvorlage ersetzen, alles ersetzen und dann wollen wir diese HP gleich hier in EXP als Standardvorlage ändern gleich hier in EXP als Standardvorlage Das Letzte, was wir tun müssen, ist die Verbindung zwischen Signal und geänderter Erfahrung zu Wir können die Änderung von Max HP komplett loswerden und dann diesen Funktionsnamen gleich hier bei HP ändern, und dann diesen Funktionsnamen gleich hier bei sodass Sie ihn auswählen können, Control R, und dann hier unten, wir wollen den ersetzen, EXP geändert oder Erfahrung geändert wurde , was auch immer für Sie Sinn macht Das werden wir ersetzen. Werde die auf Max HP geänderten Daten hier los , um diesen Teil abzuschließen. Lassen Sie uns den Fortschrittsbalken noch nicht aktualisieren, also werde ich diese auskommentieren. Für den Moment zoomen wir hier rein und ich ersetze die Erlebnis-Textvorlage durch das Unterstrichpunkt-Erlebnis, und ich füge die Erfahrung auch hier wieder Es wird also sagen, eins von eins oder zwei von zwei, aber zumindest können wir sehen, dass es funktioniert Stellen Sie jetzt oben rechts sicher, dass Sie den Fortschritt zuordnen. Dem Textur-Fortschrittsbalken, das Label dem Label. Dann brauchen wir nur noch das HP-Display und das EXP-Display, um ihre Set-Stats-Funktion von der Player-Benutzeroberfläche aus aufzurufen also innerhalb des Player-UI-Skripts Lassen Sie uns also innerhalb des Player-UI-Skripts die ExportVRHP-Anzeige vom Typ HP-Anzeige und die Export var EXP-Anzeige vom Typ EXP-Anzeige vom Typ EXP-Display verwenden Und dann die Funktion underscore fertig, wir werden hp display dot set Stats aufrufen , um den Punkt mit dem Punkt zu spielen, und wir müssen das zweimal abrufen, damit wir sogar var stats of stat Controller sagen können , dann setzen wir Also schneide ich das aus, gehe hier rüber, Gleichheitszeichen, füge es ein Also legen wir Statistiken über die Statistiken fest. Das Gleiche machen wir mit EXP Display XP Display Dot Set Stats Und dann machen wir Statistiken. Als letztes müssen wir das HP-Display und das EXP-Display und den Inspektor zuweisen EXP-Display und den , damit wir diese Referenz haben Klicken Sie also auf Player-UI, gehen Sie nach oben rechts und weisen Sie das HP-Display Und weisen Sie das EXP-Display zu. Nun, das HP-Display und das EXP-Display können und sollten wahrscheinlich ihre eigenen, eigenständigen Szenen sein , von denen wir eine Kopie in unserer Player-Benutzeroberfläche instanzialisieren Also klicke ich mit der rechten Maustaste auf das HP-Display und wir speichern den Zweig als Szene in unserer Benutzeroberfläche. Dann klicke ich mit der rechten Maustaste auf EXP-Display und mache dasselbe Speichern Sie den Zweig als Szene innerhalb der Benutzeroberfläche. Jetzt können wir uns mit diesen befassen und diese kleinen Displays individuell anpassen , wenn wir sie im Kontext unserer größeren Spieler-Benutzeroberfläche benötigen . Wir haben also Szenen innerhalb von Szenen, und dann nehmen wir unsere Spieler-UI-Szene und fügen sie in die Spielwelt ein, die momentan unsichtbar ist, weil die Canvas-Benutzeroberfläche betroffen ist. Aber ja, bitteschön. Und wenn wir mitspielen, werden wir sehen, ob irgendwas richtig verknüpft ist. Okay, also setze Statistiken und HP Display ist Null, weil ich vergessen habe, sie im Inspektor zuzuweisen. Sie können hier sehen, dass sie bei Bereit Null sind, was bedeutet, dass ich das beim Export vergessen habe. Auch weil es sich um eine Überprüfung handelt, benötigen wir keine Asserts , da hier quasi impliziert wird, dass dies jetzt erforderlich ist Also springe in die Playerszene, klicke auf die Player-UI, weise das HP-Display und das EXP-Display Wie dem auch sei, jetzt können wir spielen und wir werden es erneut testen. Wir haben also zehn von 100 PS. Wenn ich mich an die Statistiken erinnere, waren unsere maximalen HP 100 und unsere Basis-HP zehn, was wir hier offensichtlich getroffen haben. Sie können sehen, dass die HP-Werte auf Null aktualisiert wurden. Der EXP-Fortschrittsbalken funktioniert noch nicht, weil wir unsere Erfahrungsanforderungen für Stufe E einrichten müssen , wodurch quasi eine ganze Hierarchie von Levelaufstiegen entsteht eine ganze Hierarchie von Levelaufstiegen Aber versuchen wir es ganz schnell, indem wir die HP unseres Spielers auf 50 Also gehe ich zu unserer Spielerszene und schaue mir dann hier die Statistikkontrolle an. Und wir setzen die HP auf 50. Lass mich sehen. Wenn ich das direkt dort mache, kann ich dann zurück zum Spiel tippen? Nein, weil die Spieler schon entfernt wurden, glaube ich. Aber wenn wir auf Play drücken, sollten wir sehen die HP-Leiste hier mit dem richtigen Fortschrittswert aktualisiert wird, was aber nicht der Fall ist. Es zeigt den richtigen HP-Wert an, aber wir müssen das HP-Display schnell reparieren. Okay, lassen Sie mich auf dem HP-Display sehen, was hier vor sich ging. Der Fortschrittswert entspricht dem prozentualen Gesundheitszustand. Lassen Sie mich hier einen Grenzwert festlegen und dann auf Play klicken, und wir werden sehen, was diesen Wert tatsächlich so einstellt , dass der prozentuale Gesundheitszustand 0,0 ist. Ah, richtig, weil ich mit ganzen Zahlen dividiere. Wenn wir also durch zwei ganze Zahlen dividieren, erhalten wir eine Ganzzahl, die automatisch auf den Boden von Null geht . Aber das ist nicht das, was wir wollen Wir wollen eigentlich, dass es wieder in Schwung kommt. Was wir hier also als schnelle Lösung tun könnten ist einfach Float auf dem Mx HP zu sagen. Jetzt wird das also eine Ganzzahl sein, die durch eine Gleitkommazahl geteilt wird, was eine Gleitkommazahl zurückgibt. Wenn wir auf Play klicken, sollten wir sehen, dass der richtige Wert dort steht. Jetzt können wir also 50 Prozent Gesundheit sehen. Wenn wir auf Play klicken, wird die Leiste dort richtig angezeigt. Abzüglich der Verrechnung für den Wert. Lass mich mal sehen Habe ich den Wert dort verrechnet, HP Display? Wir haben den Textur-Fortschrittsbalken, und aus irgendeinem Grund ist er hier bis zu 00, aber ich möchte, dass dieser Wert minus 20 ist, damit er, wenn der Wert 50 ist, dort richtig in der Mitte angezeigt wird. Sie können genau dort sehen, dass das ungefähr vier von 8 Balken sind. Und der Wert hier ist 50. Ich muss das irgendwann rückgängig gemacht haben, aber die Art von hackischer Lösung dafür ist, dass man den Minimalwert einfach weiter nach links verschiebt , sodass 50 in der Mitte landet Denn wenn das hier Null ist, dann ist 50 am Ende quasi der dritte Balken Weißt du, ich stelle sicher, dass dein Men-Wert dort minus 20 ist, und das sollte für das HP-Display funktionieren. Okay, der letzte Test hier, wir klicken auf den Play-Fortschrittsbalken und haben den Fortschrittsbalken auf 50 gesetzt. Ich kann diesen Breakpoint rückgängig machen, indem ich auf Play drücke. Und wir können sehen, dass sich unser Fortschrittsbalken korrekt in der Mitte befindet, genau dort Unsere HP zeigt uns 50 von 50. Lass uns getroffen werden. Sie können sehen, wie unsere HP sinken, das spiegelt sich sofort in der Benutzeroberfläche wider, einschließlich des Fortschrittsbalkens. Alle unsere Signale sind also korrekt angeschlossen. Wir bekommen die Erfahrung dort, und wir müssen nur unsere Level-Up-Definitionen hinzufügen , damit wir unseren Charakter aufleveln können Bevor wir mit dem Video zu unserer Funktion „Statistiken festlegen“ fertig sind, gibt es hier noch einen Fehler Wenn wir jemals die Statistiken mit festgelegten Statistiken zurücksetzen und einer ist hier bereits gesetzt, erhalten wir am Ende doppelte Signale Wir wollen hier also sagen, wenn Underscore Stats nicht Null ist, bevor wir set Stats aufrufen, dann wollen wir die Verbindung zu den Signalen trennen, also können wir sagen: underscore stats dot mxhPHanged dot disconnect also können wir sagen: underscore stats dot mxhPHanged dot Der Unterstrich auf MAX HP wurde geändert. Und das Gleiche gilt für die normale HP. Also kopieren wir das einfach und machen SATS HP geändert, und dann hat HP geändert Es geht eher darum, es robust zu machen. Ich habe nie vor, den SATS-Controller auf etwas anderes einzustellen den SATS-Controller auf etwas , aber nur für den Fall, dass Sie das tun, wird dadurch sichergestellt, dass es nicht zu einem schrecklichen Fehler kommt, wenn Sie zwei Signale für zwei verschiedene Statistikcontroller angeschlossen haben , aber auf einem HP-Display Machen Sie jetzt dasselbe auch auf dem EXP-Gerät Wenn Sie sich also das EXP-Display ansehen, füge ich das einfach und wir ändern den Signalnamen Also hat sich die Erfahrung von Sats geändert, und dann hat sich hier die EXP Okay, so sollte das also aussehen. Unterstreichen Sie die Erfahrung von SAT, trennen Sie die Verbindung, wenn sich die Erfahrung geändert hat trennen Sie die Verbindung, wenn sich die Erfahrung Okay, das sollte gut sein falls Sie jemals den SATS-Controller gewechselt haben Ich wollte das nur zeigen, um es etwas vollständiger 40. P39 Debuggen und Optimieren von Benutzeroberflächen und Pickup-Skripten: Ich wollte ein paar Warnungen und Fehler korrigieren. Ich bin bisher mit dem Projekt in die Konsole eingestiegen. Wenn Sie also den Code Wort für Wort kopiert haben, sind Sie möglicherweise auf dieselben Probleme gestoßen. Nehmen Sie also zwei D , wo steht, dass Sie monitorable equals false nicht verwenden können, normalerweise weil es blockiert ist und Sie auf Set Deferred warten müssen Wenn Sie also darauf doppelklicken, wird es darauf hinweisen, dass ich in der Entfernen-Funktion versucht habe, monitorable auf wird es darauf hinweisen, dass ich in der Entfernen-Funktion versucht habe, False zu setzen Nun, eigentlich ist es hier gleich falsch, das Monitorable zu entfernen , denn wenn Sie Qu loslassen, es am Ende des aktuellen Frames entfernt Wenn Sie set deferred aufrufen, es am Ende des aktuellen Frames entfernt Es wird also nicht wirklich helfen, es nicht überwachbar zu machen wenn Sie es gleichzeitig freigeben wirklich ging darum, es so zu gestalten, dass, wenn zwei Objekte versuchen, es gleichzeitig aufzunehmen , es nicht zweimal aufnehmen würde Was wir jedoch tun könnten, wenn Sie besonders sicher sein möchten. Wenn Sie jedoch besonders sicher sein und zwei D abholen möchten, lassen Sie uns das Auto abholen. Und das wird ein boolescher Wert sein , der standardmäßig auf False gesetzt ist. Ich will damit nur andeuten, dass es dort ein boolescher Wert ist. Ich meine, wenn du es mit Sicherheit deklarieren willst, dann kannst du das tun. Also das ist ausgewählt. Und wenn wir versuchen, anzunehmen, wann das wahr ist, dann lassen wir es zu. Andernfalls geben wir Falsch zurück. Also, was ich mit Tr Take machen werde, ist, dass ich es tatsächlich bewachen lasse, und dann haben wir eine separate Take-Funktion, die genau das ist, was die Pickups tatsächlich implementieren, wie die virtuelle Funktion, was sie derzeit tun Ich möchte also function machen, T unterstreichen, und das wird nichts zurückgeben, also das ist ein Rückgabetyp von void Und ich nehme diesen Push-Fehler und bringe ihn hier runter. Also werde ich hier jetzt den Wahrheitsgehalt zurückgeben. Ich werde das in Unterstrich T ändern. Also rufen wir die virtuelle Funktion auf, und dann werden Unterstrich T ändern. Also rufen wir die virtuelle Funktion auf, wir uns davor hüten hier oben ein zweites Mal anzufangen. Also sagen wir, ich habe ausgewählt, geben Falsch zurück. Okay, da ist also unsere Wache. Und andernfalls kommen wir hierher. Nachdem wir genommen haben, haben wir gewählt, was gleich wahr ist. Und ich füge das hier ein, damit wir uns keine Gedanken über diesen Booleschen Wert und die erbenden Klassen machen müssen Gedanken über diesen Booleschen Wert und die Wir müssen uns nur um die Implementierung der Take-Funktion kümmern Implementierung der Take-Funktion Also ich denke, das ist ein besseres Setup. Es wird gut mit ir Quarter funktionieren, und solange wir picked nach dem Anruf auf true setzen sind wir sicher, dass es kein zweites Mal startet, weil wir diesen Guard hier haben. Jetzt müssen wir nur noch unsere anderen Pickup-Skripte aktualisieren. Suchen Sie also nach Abholung. Ich denke, wir haben bisher nur EXP-Pickup Also werde ich darauf doppelklicken. Wir werden das umbenennen, um zu unterstreichen , dass der Rückgabetyp ungültig ist Und anstatt hier false zurückzugeben, wir einen Fehler zurück, wenn stats Null ist Drücken Sie also den Fehler. Percent hat keinen Statistik-Controller. Das wird das Ziel von Prozent P sein. Also ersetzen wir das dort durch einen Knotennamen. Und dann kehren wir unten nicht zurück. Wir rufen einfach Remove an. Und wir müssen sicherstellen, dass wir mit der Unterschrift der Eltern übereinstimmen. Also muss ich wahrscheinlich das P-Ziel an das übergeordnete Skript übergeben . Okay, also lass uns hochgehen. Und ja, wir wollen das P-Ziel überschreiten. Also P-Ziel, wir werden den Unterstrich dort entfernen , weil wir ihn jetzt tatsächlich verwenden Und dann unterstreichen wir hier P Ziel ist ein Knoten zwei D. Das sollte nun die Fehler in unserem EXP Pickup two D beheben. Und nur um das zu überprüfen, gehen wir in den Okay, dann die anderen Warnungen, lass uns dazu übergehen. In den meisten Fällen sind dies nur ungenutzte Parameter. Bei etwas wie Pickup Two D sehen Sie also, dass das P-Ziel unbenutzt ist, also möchten Sie es einfach mit einem Unterstrich markieren, damit es absichtlich als unbenutzt markiert wird Gehen wir hier zum nächsten. Die Kameragröße wurde nie verwendet. Die Kameragröße wurde also tatsächlich verwendet , um das Kamerarecht zu erstellen. Sie wird hier also eigentlich nicht benötigt, weil in dieser Funktion zur Berechnung des finalen Spawns wir in dieser Funktion zur Berechnung des finalen Spawns das Spawn-System verwendet haben. Das Kamera-Rechteck wird erstellt, und dann wird die Größe daraus gezogen Wir können also tatsächlich die Kameragröße als Parameter entfernen , das ausschneiden. Und wo wir das hier aufrufen, entfernen wir einfach auch die Kameragröße als Parameter und wir vereinfachen es auf drei Parameter. Das wäre also ein guter Fall, in dem uns diese Warnung tatsächlich geholfen hat. Und dann, als Nächstes, wenn Sie ein Update haben, das Delta nicht verwendet, was der Fall wäre, wenn Sie Move and Slide verwenden was der Fall wäre, wenn , weil Move and Slide nicht das Delta ausführen muss, legen Sie die Geschwindigkeit fest, und dann wird Move and Slide automatisch mit dem Delta gesteuert. Wir unterstreichen also das Delta und das war's. Und dieses Drop-Skript, der Name Drop hier, überschattet den Funktionsnamen Also könnten wir den Namen hier in etwas wie Drop-Instance ändern den Namen hier in etwas wie Drop-Instance Und wo auch immer wir Drop darunter verwenden, wie hier, sagen wir stattdessen Drop Instance. Sie möchten nur sicherstellen, dass, wenn Sie eine Variable lokal verwenden, diese Variable nicht auch außerhalb des Gültigkeitsbereichs in der Klassenbasis deklariert wird, wie die lokalen Variablen. Und Sie möchten nicht, dass sie auch denselben Namen wie ein Funktionsname hat. Dann habe ich in jedem dieser Signale, die Statistiken geändert haben , die Callbacks dafür, immer aktualisiert, wenn sich der Wert ändert, und ich muss die P-Daten nicht wirklich direkt für diese Funktionen verwenden die P-Daten nicht wirklich direkt für diese Funktionen Also würde ich beide einfach noch einmal im EXP-Display-Skript unterstreichen noch einmal im EXP-Display-Skript Klicken Sie dort und unterstreichen Sie das, und das sollte alle aktuellen Warnungen und Fehler beseitigen alle aktuellen Warnungen und Fehler Und ich drücke Play. Okay, keine Fehler für. 41. P40 Leveling-System mit Erfahrung und Statistikfortschritt: Gesundheit und Erfahrung, wir müssen eine Art Leveling-Mechanik hinzufügen und wir brauchen einen Levelstatus auf unserem Statistik-Controller, und wir brauchen einen Levelstatus auf unserem Statistik-Controller um den Stufenaufstieg unseres Spielers und möglicherweise auch anderer Charaktere zu verwalten , aber auf jeden Fall für den Spieler aber Also gehen wir zum Step-Controller und ich werde hier eine neue Variable hinzufügen Wir sagen, es wird eine Ganzzahl gleich Null sein, und wir werden ein ähnliches Setup wie hier unten haben , wo wir nur einen Satur-Wert haben , bei dem wir sagen, dass I-Level dem Wert entspricht, den wir zurückgeben, andernfalls wiederholen wir einfach dasselbe Muster, das das Signal für einen geänderten Pegel ausgibt das Signal für einen geänderten Pegel , damit wir in unserer Benutzeroberfläche darauf reagieren können. Wir sagen also, dass Var alt gleich Level ist, und wir sagen Level ist gleich Wert Wir sagen, dass var-Daten gleich stat changed data dot u object level old sind, und wir geben ein Level-Change-Signal Mit den Daten. Jetzt müssen wir natürlich dieses Signal erzeugen, also hat sich die Kopierebene oben geändert. Wir erstellen eine Signalebene für geänderte Daten, Statistik für geänderte Daten. Jetzt können wir das abonnieren, wenn wir es brauchen. Jetzt können wir Add Experience vollständig implementieren. Wenn wir also Erfahrung hinzufügen, wollen wir auch überprüfen, ob wir für das nächste Level bereit sind. Ich füge das hier ein und nicht den Experience Setter, weil ich nicht zu viele zufällige Nebenwirkungen beim Einstellen des Erlebnisses haben möchte beim Einstellen des Erlebnisses Deshalb möchte ich explizit die Methode der Werbeerfahrung aufrufen, die sich verbessert, wenn der Schwellenwert erreicht wird Okay, um das zu tun, müssen wir ein Leveldefinitionsobjekt erstellen Lassen Sie uns dafür ein neues Skript erstellen. Alles wird sich, sagen wir, auf Charaktere beziehen. Klicken Sie hier mit der rechten Maustaste, machen Sie ein neues Skript und wir nennen es Level-Definition. Also Leveldefinitionspunkt gD. Es wird sich von der Ressource bis zur Schöpfung erstrecken. Doppelklicken Sie, um es zu öffnen, und wir geben Ihnen eine Definition auf Klassenebene. Dadurch werden die Ressourcen erweitert und ein Levelaufstieg für einen Charakter definiert. Was wir hier also brauchen ist die Erfahrungsschwelle. Bei Export VR sagen wir also, dass Erfahrung erforderlich ist. Und das wird eine Ganzzahl sein. Wir könnten standardmäßig auf etwa zehn setzen. Und wir wollen wahrscheinlich auch einige Statistiken, die wir verbessern werden. Im Moment fangen wir einfach mit HP an und halten es einfach, aber du würdest hier später zusätzliche Statistiken hinzufügen , wenn du herausfindest, dass sie zu Mechaniken werden. Bei Export var HP sagen wir also, dass es sich um eine Ganzzahl handelt, die standardmäßig auf zehn gesetzt Und wir könnten sagen, dass dies die Bonus-HP für den Levelaufstieg ist. Wenn du also dieses Level erreichst, erhält dein Charakter so viele HP. Nun, wie wenden wir unsere Statistikänderungen auf den Charakter an? Du könntest es einzeln manuell machen, aber eine intelligentere Methode wäre es, eine Methode zu erstellen, die das für dich erledigt. Sagen wir also, Funktion anwenden, und wir werden das auf einen Statistik-Controller anwenden , sagen wir. Also P-Statistiken eines Statistik-Controllers. Dann kehren wir damit für ungültig zurück. Also wollen wir die Sets grundsätzlich aktualisieren. Also P Stats Punkt HP plus entspricht der HP-Menge. Und davor wollen wir auch die MX HP erhöhen. Also p stats-Punkt MX HP plus entspricht HP. Es ist wichtig, dass Sie die MAX HP vor der HP angeben, da die aktuelle HP bei der MAX HP begrenzt ist Wenn also ein Charakter mit voller Gesundheit seine HP um zehn erhöht, erhält er die Lebenspunkte nicht, es sei denn, die MAX HP werden zuerst aktualisiert Also wichtig, da zu bestellen. Und das kann vorerst unsere grundlegende Definition sein. Statistikkontrolle angeht, wäre es also ein guter Ort, um unsere Ebenendefinitionen zu definieren. Ich sage also beim Export von VR-Level-Up-Definitionen. Und das ist eine Reihe von Level-Definitionen. Okay, um zu überprüfen , ob das Level höher ist, müssen wir das nächste Level in der Reihenfolge erreichen. Lassen Sie uns also eine Funktion erstellen, um unser nächstes Level zu erreichen, falls es eine gibt. Also hier unten, sagen wir Funktion, Unterstrich, nächstes Level Was eine Ebenendefinition oder Null zurückgibt. Und das wird die Level-Up-Definitionen auf Git zurückgeben , und wir kommen zur Indexebene. Der Grund, warum wir auf die Indexebene kommen , ist , dass Level tatsächlich der zweite Platz im Array ist. Wenn unser Charakter also Stufe eins hat, befinden wir uns derzeit auf dem Index Null, und wir wollen uns den Index plus eins ansehen, was Level ist, weil Level bei eins beginnt. Okay, um mit dem Aufsteigen unserer zusätzlichen Erfahrung fertig zu werden, müssen wir zuerst die nächste Leveldefinition zu werden, müssen wir zuerst die nächste Leveldefinition für das nächste Level finden Also, wie bei der Stufe plus eins, müssen wir diese Leveldefinition nach oben bringen Also werden wir das bei Export tun, nicht in gewisser Weise, sondern hier ein Wörterbuch. Bei Definitionen auf VR-Ebene exportieren werden wir also sagen. Und das wird ein Wörterbuch mit ganzen Zahlen sein, die der Ebenendefinition zugewiesen sind Die Ganzzahl ist also die Ebene, die wir erreichen wollen, und die Ebenendefinition ist die Statistikänderung, die sich ergeben würde, wenn sie existieren Bevor wir also ein Level aufsteigen oder versuchen, aufzusteigen, müssen wir zuerst sehen, ob tatsächlich ein Level definiert ist. Am Ende erstellen wir also eine weitere private Funktionsfunktion mit dem Unterstrich zum nächsten Level, und das wird eine Ebenendefinition oder Null zurückgeben Also geben wir unseren Ebenendefinitionen den Punkt GET auf der Ebene plus eins zurück auf der Ebene plus eins Unser aktuelles Level plus eins, das wollen wir erreichen und wir wollen Null zurückgeben. Wenn wir es nicht finden können. Wenn wir also Null zurückgeben, überspringen wir den Levelaufstieg In dieser Erfahrung wird „ Lass uns VR als nächstes machen eine Leveldefinition sein, die dem Erreichen der nächsten Stufe entspricht Wenn next also Null ist, kehren wir einfach zurück oder Sie könnten sogar eine Warnung auslösen. Eigentlich ja, lassen Sie uns eine Warnung aussprechen. Charakter kann nicht bis zu einem Prozent Stufe plus eins aufsteigen, weil für diese Stufe keine Definition definiert ist. Also könnten wir hier am Ende Zeichenfolge von Level plus eins sagen und es mit einer weiteren Klammer beenden . Okay, das wird funktionieren Also nehmen wir das Level plus eins. Wir versuchen, auf Stufe zwei aufzusteigen, wenn wir Stufe eins sind, und wir stellen fest, dass wir nicht aufsteigen können , weil das nicht definiert ist. Vielleicht möchtest du das als Warnung haben, oder wenn du dir sicher bist, dass du das nicht willst, kannst du das einfach kommentieren oder entfernen. Ich lasse es vorerst drin, damit wir zumindest sehen können , wann es uns nicht gelingt, eine Leveldefinition festzulegen. Die nächste Stufe ist also Null Wenn also next Null ist, kehren wir zurück, weil wir nicht aufsteigen können. Es ist kein nächstes Level definiert. Also überspringen wir einfach alles. Und dann wollen wir überprüfen, ob die Erfahrungsanforderung für die nächste Stufe geringer oder gleich unserer aktuellen Erfahrung ist. Wir können das also als Teil einer dreistufigen Funktion zusammenfassen. Unterstreichen Sie also Tri Level Up und wir sagen beim nächsten Also kommen wir runter und wir werden unsere Funktion haben. Unterstreichen. Versuche, ein höheres Level zu erreichen. Unterstreichen Sie, weil es privat ist, und wir geben die Definition der nächsthöheren Ebene Oder eigentlich, weißt du, ich finde, dass das wirklich in dieser Funktion enthalten sein sollte Das wird also einen booleschen Wert zurückgeben , und das haben wir hier Also bekommen wir einfach die nächste Ebene innerhalb dieser Definition. Und dann müssen wir keinen Parameter übergeben. Wir versuchen einfach, ein Level aufzusteigen, nachdem wir XP hinzugefügt haben, oder? Es ist einfach so. Wenn wir also nicht aufsteigen können, geben wir Falsch zurück. Und dann wollen wir überprüfen, ob die Erfahrung größer oder gleich der nächsten benötigten Erfahrung ist . Wenn das der Fall ist, würden wir ein höheres Level erreichen. Aber ich werde das rückgängig machen. Ich werde sagen, wenn es weniger als die erforderliche Erfahrung ist, dann geben wir Falsch zurück. Okay, das Wenn-Statement ist wieder raus. Und wenn wir dann hier ankommen, haben wir die Wachkontrollen bestanden, also können wir sagen, dass Stufe plus gleich eins ist Wir ziehen die benötigte Erfahrung von der aktuellen Erfahrung ab Erfahrung minus entspricht also nächstem Level. Oh, tut mir leid, als Nächstes ist Punkterfahrung erforderlich. Und dann werden wir die Statistiken des nächsten Levels auf unsere aktuellen Statistiken anwenden . Nachdem wir also die XP abgezogen haben, gilt der nächste Punkt für uns selbst weil wir innerhalb des Statistik-Controller-Skripts arbeiten , und dann geben wir true zurück weil wir erfolgreich aufgestiegen sind . Lassen Sie mich jetzt darüber nachdenken. Ich glaube, ich möchte eigentlich , dass das Level steigt, nachdem die Statistiken angewendet wurden, also so. Also wenn wir sagen, lass einen Charakter aufleveln und wir geben ihm dann die Wahl , was die Belohnungen angeht. also ein Upgrade beim Levelaufstieg auswählen, was eine Kernmechanik ist und unser Überlebender mag, wollen wir das tun, nachdem die Basiswerte gültig sind, sodass die Benutzeroberfläche im Grunde immer noch im selben Frame aktualisiert wird, aber kurz bevor wir aufsteigen und unser Levelwechselsignal ausgeben, sodass die Benutzeroberfläche reagiert und uns unsere Upgrade-Optionen zeigt. Ich denke, das ist eine wichtige Änderung der Reihenfolge. Okay, also ja, dann wird das Signal zur Änderung des Pegels hier oben wegen des Setzers ausgegeben Und das ist im Grunde unser Levelaufstieg. Wenn Sie aus irgendeinem Grund die aktuelle Leveldefinition abrufen möchten , könnte das außerhalb des Skripts nützlich sein Und diese könnte sogar außerhalb des Skripts nützlich sein. Also nehme ich Get next level, und wir entfernen den Unterstrich für Pivting, verschieben diesen Unterstrich und versuchen es mit Next Und lassen Sie uns eine Funktion G hinzufügen, aktuelle Ebene. Definition oder vielleicht einfach die aktuellen Werte klar genug machen. Und dann geben wir die Leveldefinition zurück. Also geben wir die Ebenendefinitionen als Punkt GIT zurück, und wir wollen die Ebene oder Null zurückgeben. Okay. Diese könnten also für andere Skripte nützlich sein, die untersuchen wollen, was mit dem Stat-Controller vor sich geht. Es macht also Sinn, diese öffentlich zu machen . Indem ich es nicht unterstreiche Deshalb. Okay, wir haben also diese Statistikeigenschaft und wir können aufsteigen, wenn unsere EXP steigen sollte automatisch geschehen , weil dieses Werbeerlebnis von unserer Abholung, unserer EXP-Abholung aus aufgerufen wird Also wird alles gut funktionieren, wenn es gut funktioniert Aber jetzt müssen wir sicherstellen, dass wir eine Verbindung zum Level-Stat und zum Level-Up-Signal oder zum Level-Change-Signal herstellen. Und das machen wir im EXP-Display. Also müssen wir in einem Projekt nach EXP suchen und nach unten scrollen, unseren Scene XP-Display-Punkt tSCN finden und ihn öffnen Okay, jetzt, wo unser Leveln funktionieren sollte, müssen wir zur EXP-Anzeige gehen und sicherstellen, dass sie anzeigt, wie viel EXP wir für das nächste Level benötigen Also lass uns hier reingehen. Und wenn wir aktualisieren, wollen wir das nächste Level XP bekommen. Wir wollen diesen Teil gleich hier auf die Mx-XP der Statistiken ändern , falls die Statistiken ein nächsthöheres Level haben, auf das wir tatsächlich zugreifen können. Also wirst du diesen Teil los und sagst, dass varnnXT gleich dem Unterstrich von Statistiken auf der nächsten Stufe sein wird . Also bekommen wir das nächste Level, und wenn es kein nächstes Level gibt, dann sagen wir, dass I next gleich Null ist, dann wollen wir den Text mit dem Label-Punkt so ändern, dass er, sagen wir, unserer maximalen Level-Zeichenfolge entspricht sagen wir, unserer maximalen Okay, also müssen wir das hier bei export var max level string definieren , und das entspricht einfach so etwas wie max level in all caps. Okay, sonst setzen wir den Text auf unsere EXP, unsere aktuelle Zahl aus der Nummer der nächsten Ebene. Wir haben also bestätigt , dass next nicht Null ist, also können wir dieses Bit durch Next Dot Experience Ned ersetzen Wenn ich das Spiel jetzt starte, wird wahrscheinlich nur Max Level angezeigt, weil wir keine Leveldefinitionen definiert haben. Wenn wir auf dem MAX-Level sind, dann möchte ich auch den Fortschrittsbalken nehmen und diesen Wert auf 100 setzen. Wenn wir das Spiel jetzt starten, wird uns das eine Fehlermeldung geben, weil ich den Fortschritt nicht festgelegt habe , also lass uns das machen. also in unserem XB-Display Gehen Sie also in unserem XB-Display nach rechts und weisen Sie den Fortschrittsbalken zu Okay, jetzt können wir rennen und wir sollten einen vollständigen Fortschrittsbalken sehen Wir sind auf dem MAX-Level. Okay, also XB abzuholen ist nicht mehr wichtig Ich kann immer noch gute Erfahrungen machen, aber es wird nie mehr besser Weil Leveldefinitionen im Editor zugewiesen werden , nicht während des Spiels. könntest du zwar tun, aber das wäre ziemlich komisch, oder? definierst zum Beispiel einfach das Endspiel, sodass du bis jetzt Level 31 hochleveln kannst, wo vorher 30 die Obergrenze war , nein, das machst du im Editor. In 99,99% der Fälle. Der Fortschrittswert wird hier also festgelegt. Wir werden einen Prozentsatz zwischen unserer Erfahrung und der nächsten benötigten Erfahrung ermitteln wollen , und dann werden wir hier den Fortschrittswert aktualisieren , damit wir ein höheres Level erreichen können. Unser Fortschritt ist also unverändert und wir setzen diesen Wert auf die nächste benötigte Punkterfahrung geteilt durch die Unterstrichstatistik Punkterfahrung Denken Sie jetzt daran, dass wir eine Ganzzahl durch eine Ganzzahl dividieren, aber eigentlich wollen wir, dass es Also müssen wir eine davon nehmen und sie als Float umwandeln. Also sag Float. Und dann, bei Stats Dot Experience, beenden wir es mit unseren Klammern Also machen wir das, und das sollte uns jetzt irgendwo zwischen 0,0 und 1,0 Aber das muss im Grunde genommen in einen Prozentsatz umgewandelt werden, da unser Fortschrittsbalken standardmäßig einen Maximalwert von 100 hat, also betrachten wir Prozentsätze In beiden Fällen müssen Sie den Maximalwert auf eins herunterskalieren. Beide sind tatsächlich gültig. Also hier können wir das einfach in weitere Klammern setzen und es mit 100 multiplizieren , und das sollte uns unseren tatsächlichen Fortschritt geben Wir werden das also immer noch nie erreichen, weil wir einige Definitionen definieren müssen Gehen wir also in den Player und klicken auf den Statistik-Controller. Wir haben unsere Leveldefinitionen hier. So können wir einige Wörterbuch-Schlüsselwerte hinzufügen. Wir möchten, dass hier die nächste Stufe von zwei definiert wird. Fügen Sie also zwei und eine neue Ebenendefinition hinzu. Hier drinnen können wir einfach sagen, dass XB zehn HP benötigte. Das ist gut für den Anfang. Fügen Sie das Schlüssel-Wert-Paar hinzu. Es ist wichtig, dass Sie daran denken, darauf zu klicken. Sonst steht es nicht im Wörterbuch. Wir haben also unser Wörterbuch mit einem Schlüssel auf Stufe zwei und einer Leveldefinition, um unseren Charakter zu verbessern. Okay, eine letzte kleine Änderung , die wir vornehmen müssen, besteht darin , sicherzustellen, dass unser Spieler standardmäßig auf Stufe Gehen wir also in den Statistik-Controller und dort, wo wir Level haben Wir müssen sichergehen, dass es sich um eine Eins handelt. Wenn wir also nach Stufe plus eins von zwei suchen, finden wir diese Ebenendefinition und sie sollte in der Benutzeroberfläche korrekt angezeigt werden. Drücken wir also auf Play und wir werden unser XB hier benötigen. Der Fortschrittsbalken wurde nicht aktualisiert, aber schauen wir mal, wenn wir eine EXP bekommen , steigt sie und sie werden von zehn angezeigt Und ja, einfacher Fehler. Ich habe vergessen, den Fortschritt dem Fortschrittspunktwert zuzuweisen . Vielleicht ist es also tatsächlich sinnvoll , dies in einen anderen Namen zu ändern. Wir beschatten eine Variable. Ich wette, wenn ich die Fehler hier überprüfe, können Sie sehen, dass ich das mit dem Namen der Fortschrittstexturleiste beschattet Nehmen wir an, Prozent nivelliert wäre ein viel besserer Name. Und dann sagen wir, dass der Fortschrittspunktwert gleich Prozent Und jetzt bin ich mir ziemlich sicher, dass es funktionieren sollte. Lass uns spielen. Geh da rein. Wir können sehen, warum EXP dort oben nicht geliebt hat, und jetzt heißt es eins von zehn Das ist interessant. Also muss ich hier einen Breakpoint setzen, um zu sehen, was das zeigt Und lass uns in den Spielmodus gehen. Und wir können sehen, dass da gerade 0,0 steht, aber nehmen wir eins und wir bekommen 1.000. Ein weiterer einfacher Logikfehler Ich sollte die Erfahrung geteilt durch die benötigte Erfahrung machen . Also machen wir das rückgängig. Ich nehme die benötigte Erfahrung und lege das hier hin, und dann schneide ich die Statistik-Punkt-Erfahrung ab und dann schneide ich die Statistik-Punkt-Erfahrung und lege das hier nach links. Wir könnten den Floatguss immer noch auf der rechten Seite machen . Das ist in Ordnung. Okay, lass uns noch einmal spielen. Das testen? Also, okay, jetzt wird angezeigt, dass es sich um 0% verbessert hat Wir holen einen Artikel ab. Wir bekommen dort 10%, zwei, drei, aber es sollte bis zum Ende reichen. Deshalb möchte ich hier den Wert für den Stopp des Fortschritts überprüfen und herausfinden, warum das passiert. Okay, hier sind wir also um 40% aufgestiegen. Der eingegrenzte Prozentsatz ist also richtig. Also müssen wir vielleicht die Benutzeroberfläche außerhalb des Spiels überprüfen die Benutzeroberfläche außerhalb des Spiels Gehen wir also hier in die EXP-Anzeige. Ich werde testen, den Wert auf Null zu setzen. Okay, das ist richtig. 100 ist richtig. Es geht ganz nach rechts. Sagen wir 25, 50, 75. Okay, das sieht richtig aus. Also lass uns den Wert auf Null bringen. Ordnung, spiel. Lass uns das ein bisschen testen. Okay, entferne den Breakpoint. Geh in den Spielmodus und lass uns eins, zwei, drei machen. Das sind also 30%? Vielleicht ist es tatsächlich richtig. Okay, also wir bekommen vier von zehn und dann fünf von zehn. Okay, ja, es hat gut funktioniert. Lass uns sieben von zehn nehmen. Lasst uns einfach unseren Charakter verbessern, um zu beweisen, dass es funktioniert. Okay, also wir bekommen neun von zehn und dann spawnen wir das Skelett. Wir können noch eins bekommen, zehn von zehn. Okay, du hast gesehen, dass wir hier gerade zehn HP haben, dann sind wir bei der benötigten EXP auf Null von zehn gegangen Der Teil mit dem nächsten Level sollte also etwas zurückgeben, aber das hat er nicht getan Der Grund, warum das passiert ist , ist, dass unsere Erfahrung auf Null gesetzt wird. Es sendet ein Signal aus, und dann unser Level geändert und es wird hier keine Verbindung hergestellt. Nachdem das Level geändert wurde, wird es also nicht erneut aktualisiert. Okay, die einfachste Lösung ist einfach, die Punkteebene der Unterstriche zu unterstreichen, und wir stellen die Verbindung auf geänderter Ebene her, um sie erneut zu aktualisieren Also können wir das hierher kopieren und die Verbindung trennen. Also erstellen wir unsere Callback-Funktion in der unteren Funktion , Unterstrich auf geänderter Ebene Wir werden die Daten nicht verwenden, also unterstreichen Sie P-Daten. Wenn die Daten geändert wurden, geben wir void zurück und aktualisieren sie einfach Okay, auf diese Weise wird die Benutzeroberfläche aktualisiert, nachdem die Erfahrung auf Null gesetzt , kurz bevor wir unser Level erhöhen wurde , kurz bevor wir unser Level erhöhen, aber dann ändert sich das Level und wir aktualisieren die Benutzeroberfläche erneut. Lassen Sie uns also noch einmal zeigen, dass alles wie beabsichtigt funktioniert. Also werde ich einfach genug Erfahrung sammeln, um hier aufzusteigen. Also für und dann, fünf, sechs, sieben, acht, neun. Skillsins lassen eigentlich noch nichts fallen. Das werden wir bald reparieren. Und dann zehn. Okay, jetzt wird das maximale Level angezeigt, aber wir haben auch unsere HP erhöht. Das hat also unsere Benutzeroberfläche zweimal aktualisiert. Einmal, als wir unsere Statistiken geändert haben, wodurch die Erfahrung verringert wurde, und ein anderes Mal, als wir unser Level erhöht haben, was jetzt zeigt, dass das nächste Level nicht existiert Deshalb zeigen wir in unserer EXP-Leiste die maximale Stufe an, wie wir es erwarten würden. Also scheint alles zu funktionieren. 42. P41 Einrichten von XP-Schwellenwerten und Signalverbindungen für Level-Up-Belohnungen: Zeigen Sie jetzt, wo wir ein betrügerisches Upgrade-System hinzufügen möchten Wir erhöhen also die Stufe unseres Charakters wenn unser Charakter einen bestimmten EP-Schwellenwert erreicht, und können dann aus einer von drei Optionen auswählen , wie wir unseren Charakter verbessern möchten Und das wird aus einer zufälligen Liste verfügbarer Optionen ausgewählt . Der Einfachheit halber möchte ich, bevor wir darauf eingehen, die XP-Anforderung ändern Stufe zwei auf eins anpassen, damit wir sie sehr schnell auslösen können. Wenn ich also zum Spieler-SAN gehe, öffnen wir den Spielerpunkt TCN und dann gehen wir zum Statistik-Controller, ich glaube, dort haben wir ihn definiert Und die Level-Definition, wir haben hier die erste Ebene auf zehn XB festgelegt Lassen Sie uns das ganz schnell auf eins ändern. Und dann füge ich vielleicht ein paar zusätzliche Level hinzu. Also können wir hier Level drei als neuen Schlüssel verwenden, und dann machen wir eine neue Definition. Wir lassen einfach dafür sorgen , dass man zehn braucht. Also fügen wir das Schlüssel-Wert-Paar hinzu. Sie können hier so viele hinzufügen, wie Sie möchten. Das ist also im Grunde nur eine riesige Liste der Stufen, die wir hier auf der linken Seite einrichten wollen , und die Definition der Statusstufe auf der rechten Seite. Also Stufe vier, wir können sagen, dass wir 20 EP benötigen, und das erhöht die HP um zehn Und mach einfach weiter, wie du möchtest. Also Level fünf, sagen wir 30 X P und L Level zehn. Ich werde das einfach konkretisieren, damit ich mir später keine Gedanken darüber machen muss . Lass uns Level sieben machen. Also neue Level-Definition. Wir sagen 50 XP, fügen ein Schlüsselwertpaar hinzu, sieben, und wir erstellen eine neue Leveldefinition bei 100 XP und fügen das hinzu. Und ich denke, das sollte vor allem für unseren Prototyp mit sieben verschiedenen Stufen gut sein . Ist definitiv genug, um Dinge zu testen. Also haben wir diese Leveldefinitionen beim Levelaufstieg eingerichtet, sie werden das Signal zur Leveländerung von unserem Stat-Controller ausgeben Signal zur Leveländerung von unserem Stat-Controller Deshalb wollen wir in unserer neuen Benutzeroberfläche eine Verbindung dazu herstellen, wir die Möglichkeit haben werden , eines von drei verschiedenen Objekten auszuwählen oder Funktionen zu verbessern Und wir wollen, dass das Spiel pausiert wird, während unser Spieler diese Wahl trifft Lassen Sie uns also eine neue Benutzeroberfläche erstellen. Ich werde hier einen neuen Kontrollknoten hinzufügen, Auswahl erhöhen, ich denke, das ist ein guter Name, und wir werden dem ein neues Skript hinzufügen. Also Level U Selection Punkt GD. Das speichern wir natürlich im UI-Ordner. Also UI und dann öffnen und erstellen. Okay. Steuern Sie auch, ob die Szene neben dem Drehbucheintrag gespeichert werden soll. Das ist also auch im UI-Ordner. Ich werde es einfach dort speichern. Okay, jetzt fangen wir an, an dem Drehbuch zu arbeiten. Ich wähle den Klassennamen nach oben aus. Generell gilt, dass ich fast immer einen Klassennamen erstelle, sofern es sich nicht um ein Skript für den einmaligen Gebrauch handelt einen Klassennamen erstelle, sofern es sich nicht um ein Skript für den einmaligen Gebrauch , auf das nichts anderes verweisen muss , falls das zu diesem Zeitpunkt noch nicht klar war. Nur einen referenzierbaren Namen zu haben macht die Arbeit zwischen Skripten viel einfacher Okay, der schnellste Weg , den Verweis auf den Statistik-Controller des Spielers zu bekommen , ist, Sie haben es erraten . Der Spielerkontext Fügen wir also export var hinzu, den Kontext, der hier der Spielerkontext sein wird . Drücke S, um das zu speichern. Und dann laden wir im Inspektor schnell den Ein-Spieler-Kontext unseres Spiels, und das gibt uns im Grunde den Verweis auf den Spieler und damit den Statistik-Controller. Okay, und dann, wenn die Funktion Underscore fertig ist, wollen wir zum Kontext Punkt Spielerpunkt-Statistik Punkteebene Chang gehen Spielerpunkt-Statistik Punkteebene und uns mit dem auf Spielerebene geänderten Kontext verbinden, was eine neue Funktion sein wird, die wir direkt weiter unten erstellen Also Funktion Unterstrich bei Änderung der Spielerebene. Und das wird das Datenobjekt „ Level Change“ haben. P-Daten sind also so, wie sie es nennen, Stats Change-Daten. Wir wollen die Benutzeroberfläche also nur dann bereitstellen, wenn die Level tatsächlich steigen. Es kann einige seltsame Umstände geben, unter denen wir beschließen, dass das Niveau in Zukunft sinken könnte. Um uns davor zu schützen, sagen wir, wenn die Änderung der P-Datenpunkte größer als Null ist, wissen wir, dass es sich um einen Anstieg handelt Okay, wenn sich das Niveau ändert, wollen wir nur darauf reagieren, dass es sich verbessert, nicht aber auf ein Absenken Also werden wir sagen, wenn die Punktänderung bei pdata kleiner oder gleich Null ist, dann kehren wir einfach hierher zurück, weil das keine Bedingung ist , mit der wir umgehen wollen Andernfalls werden wir den Spieler aufleveln. Im Moment werde ich nur den Code schreiben, der das Aufsteigen eines Levels nach dem anderen ermöglicht, denn im Kontext des aktuellen Spiels wäre das der einzige Weg, auf dem das möglich wäre Also werde ich zumindest den Prototyp des Skripts schreiben , um das Levelaufsteigen nur einmal nach dem anderen zu erledigen Wenn Sie aus irgendeinem Grund ein Objekt mit 1.000 EXP aufnehmen und das dann drei oder vier Stufen nach oben auslösen würde, könnte das eine Bedingung sein, mit der Sie sich später befassen möchten Aber ich denke, das ist hier ein bisschen unnötig, weil wir sowieso nur jeweils eine XP sammeln werden Aber für dieses Skript werden wir vorerst nur ein Level nach dem anderen bearbeiten. Lassen Sie uns hier also eine Funktion erstellen. Ich nenne es Startauswahl. Und dann bietet uns diese Funktion, die ich über der Startauswahl der Funktion platzieren werde Startauswahl der Funktion , drei Optionen. Es wird auch die Benutzeroberfläche zeigen. Also können wir hier einfach mit einem Show-Call beginnen. Und dann wollen wir auch das Spiel pausieren, damit wir sagen können, dass „ Get Tree Dots pausiert“ gleich Okay, da wir das Spiel hier pausieren, bedeutet das, dass es alle Skripte pausiert, die so eingestellt sind, dass sie nur aktiv sind, wenn das Spiel nicht pausiert ist, was alle Skripte pausiert, die so eingestellt sind, dass sie nur aktiv sind, die Standardeinstellung ist die Standardeinstellung Also drüben hier unter dem Knotenprozess müssen wir den Modus hier auf Ich denke immer ändern, müssen wir den Modus hier auf Ich denke immer ändern damit er immer Dinge innerhalb des Spiels auslösen kann, unabhängig davon, ob es pausiert ist Weil wir auch in der Lage sein wollen, das Skript zu öffnen, wenn das Spiel nicht pausiert ist Es wird also wichtig sein, während eines Spiels ohne Pause die Startauswahl aufrufen während eines Spiels ohne Pause die Startauswahl Ich denke also, dass es eigentlich immer Sinn macht, das zu machen. Aber wir wollen auf jeden Fall, dass es läuft, während das Spiel pausiert ist Später müssen wir hier reinkommen und eine Liste mit Belohnungen erstellen , die wir dem Spieler zeigen werden Dafür müssen wir zuerst die Benutzeroberfläche ein wenig einrichten. Und wir wollen auch sicherstellen, dass dies soweit getestet wurde, damit es tatsächlich auftaucht Klicken wir mit der rechten Maustaste auf die Level-Up-Auswahl und fügen Sie ein paar UI-Komponenten hinzu Ich beginne also, sagen wir, mit einem Panel-Container, damit wir ihn sehen können, wenn er auf dem Bildschirm erscheint Klicken Sie außerdem auf die Root-Benutzeroberfläche. Und dann werden wir, mal sehen, das Layout nach oben links ändern Layout nach oben links und hier die Capreset-Taste drücken. Also genau da Ich möchte auch sichergehen , dass die Maus nicht verhindert, dass die Klicks ausgeführt werden, aber wir werden das vorerst ignorieren. Es wird Dinge geben, auf die wir auf der Benutzeroberfläche klicken möchten , wie zum Beispiel Schaltflächen, um die Auswahl zu treffen, aber wir wollen nicht, dass das UI-Root diese Maus - und Portsignale blockiert. Schauen wir uns also an, ob wir das beim Levelaufstieg zum Vorschein bringen können. Gehen wir zum Stammverzeichnis und ich füge die Level-Up-Auswahl Erhöhen Sie also den Unterstrich und wir platzieren das Ganze unter der Leinwandebene Lassen Sie uns vorübergehend die Benutzeroberfläche anzeigen. Okay. Und wir wollen, dass das tatsächlich in der Mitte des Bildschirms ist. Nehmen Sie also die Level-Up-Auswahl und gehen Sie zum Layout oben rechts, und wir werden es hier zentrieren. Also zentrieren und wenn wir herauszoomen, dann sollte das theoretisch in der Mitte des Bildschirms sein Gehen wir also zu Level zwei und spielen, und wir werden sehen, ob das tatsächlich funktioniert Also werde ich hierher gehen. Das Spiel hat eine Pause gemacht. Ich sehe nicht, dass es auftaucht, aber das ist ein guter Anfang. Zumindest wissen wir, dass es bei Lavote ausgelöst wird. Also ich denke, was das Problem hier verursachen könnte, ist, dass die Canvas-Ebenenskala auf vier eingestellt ist Lass uns das so machen. Okay, und dann möchte ich ein Kind für die Canvas-Ebene, das ich tatsächlich für die Skalierung verwenden werde. Klicken wir mit der rechten Maustaste auf die Canvas-Ebene und fügen hier einen Kontrollknoten hinzu. Also nehme ich die anderen Knoten und erstelle die Wurzel. Dieser Knoten wird also die Benutzeroberfläche sein. Okay, wir müssen auch die UI-Steuerung übernehmen, das Root hier, das ich gerade erstellt habe. Und wir nehmen die voreingestellten Anker und machen daraus ein vollständiges Rechteck Das wird sich nun auf die Größe des Ansichtspunkts ausdehnen . Wir möchten sicherstellen, dass die Maus auf Ignorieren eingestellt ist , damit die UI-Signale nicht blockiert Okay, und wenn wir dann die Level-Up-Auswahl hier auf die Mitte gesetzt haben , können wir tatsächlich sehen, dass das die tatsächliche Mitte des Aussichtspunkts ist tatsächliche Mitte des Aussichtspunkts Also hier ist der Root-UI-Steuerknoten, und dann ist er in der Mitte Wenn ich also auf „Jetzt spielen“ klicke und wir uns ein XP holen, dann würde das in der Mitte angezeigt werden, obwohl es standardmäßig ein bisschen angezeigt wurde. Also muss ich es zuerst verstecken. Und jetzt drücken wir Play. Wir gehen hierher und du siehst, dass es auftaucht und das Spiel pausiert. Okay, das Drehbuch funktioniert also. Wir müssen die Größe unserer HPUI hier oben wieder ändern. Also werde ich hier tatsächlich auf die Benutzeroberfläche klicken und ihre Skalierung direkt erhöhen Es ist vielleicht am besten , die einzelnen Komponenten zu skalieren , anstatt eine globale Skala auf alles anzuwenden. Dann können wir unsere Play-Up-Auswahl einfach entsprechend dimensionieren. Ein weiterer Vorteil der Benutzeroberfläche besteht darin, dass wir, wenn wir ein Thema auf alles darunter anwenden möchten , einfach zum Thema unten rechts wechseln und dann schnell das Spieldesign laden können . Jetzt wird also alles diese Pixar-Schrift verwenden, auch wenn wir sie nicht direkt der Level-Up-Auswahl zuweisen direkt der Level-Up-Auswahl Manchmal möchten Sie also eine genaue Kontrolle über die einzelnen Wenn Sie beispielsweise ein benutzerdefiniertes Thema für die Level-Up-Auswahl wünschen, würden Sie hier unten einfach ein neues erstellen Und ich denke, auf den niedrigsten Stufen überschreibt es alles, was darüber liegt Sie können also im Grunde eine solche Hierarchie von Themen haben , weil nicht alles auch jede einzelne Eigenschaft überschreiben muss Sie können ein Hauptthema haben und dann für sehr benutzerdefinierte Dinge, wie zum Beispiel das Aussehen einer Schiebereglerleiste, können Sie es wie ein Unterthema gestalten 43. P42 Erstellen des Level-Up-UI-Layouts und des animierten Texts: Wir werden daran arbeiten, unsere UI-Vorlage für die Level-Up-Auswahl auszuarbeiten . Wir haben also bereits einen Panel-Container. Ich denke, wir sollten das ausdehnen, also ziehe ich an der unteren rechten Ecke und verschiebe es etwas größer. Wir werden eine viel größere Benutzeroberfläche benötigen , um unsere Auswahl tatsächlich anzuzeigen. Jetzt brauchen wir einen Header. Vielleicht zeigen wir eine Grafik. Zum Beispiel herzlichen Glückwunsch. Du hast so etwas hochgestuft. Dann brauchen wir drei Säulenanzeigen. Das werden VBox-Container sein, die unsere Optionen zeigen werden Das wird also wahrscheinlich wie ein Titeltext, ein Symbol, eine Beschreibung und dann eine Auswahlschaltfläche Sobald die Auswahltaste gedrückt ist, verarbeitet die Level-Up-Auswahl die Auswahl, wendet sie auf den Spieler an, schließt die Benutzeroberfläche und setzt das Gameplay fort. Klicken wir also mit der rechten Maustaste auf unseren Panel-Container und ich füge einen Randcontainer als nächste Ebene hinzu, füge einen untergeordneten Knoten hinzu. Wir suchen also nach einem Margin-Container. Und dann nehme ich in den Theme-Overrides auf der rechten Seite diese Ränder und setze sie vorerst jeweils auf fünf Pixel Dadurch sieht es nur ein bisschen schöner aus, damit nicht alles so zusammengeklumpt ist Klicken wir mit der rechten Maustaste auf den Randcontainer und nun einen VBox-Container hinzu So können wir alles andere vertikal organisieren. Man kann schon den Randcontainer sehen, der die Ränder irgendwie ein wenig zu den Seiten hin spreizt. Wir möchten dem wahrscheinlich unseren Titeltext hinzufügen. Also können wir das als Rich-Text-Label hinzufügen. In Ordnung, klicken Sie auf Ein untergeordnetes Rich-Text-Label hinzufügen. Der Grund dafür, dass es Rich-Text anstelle eines regulären Labels ist, dass Sie mit Rich-Texten Dinge wie BB-Code ausführen können, was gut ist, wenn Sie einen Regenbogeneffekt anwenden oder den Text nach oben und unten schwenken möchten einen Regenbogeneffekt anwenden oder den Text nach oben und unten schwenken Es ist also einfach leistungsfähiger als ein normales Textlabel. Ich bin mir sicher, dass es technisch gesehen etwa mit Ressourcenkosten verbunden ist, aber ein paar Textanimationen auf dem aber ein paar Textanimationen auf dem Bildschirm werden Sie nicht hinterherhinken Also lassen Sie uns das hier als Text auf der höheren Ebene eintragen. Wir können sehen, dass es hier nicht wirklich auftaucht. Also müssen wir den passenden Inhalt übernehmen und überprüfen, ob er wahr ist. Jetzt wird unser Text dort in der Mitte angezeigt. Wir möchten diesen Text auch zentrieren, also ändern wir die horizontale Ausrichtung hier auf zentriert. Okay, jetzt ist es zentriert. Lassen Sie uns ein Symbol darunter platzieren, damit wir eine Grafik zeigen können, die vier Stunden höher ist. Also werde ich mit der rechten Maustaste auf den VBox-Container klicken und einen untergeordneten Knoten hinzufügen Sagen wir Texture Rack. Fügen Sie das hinzu und wir können eine Textur auswählen. Jede Grafik, die wir aus unserem Projekt verwenden möchten, funktioniert also. Mal sehen, ob wir schnell etwas laden können. Wenn ich also suche, sagen wir 64 mal 64 um die Textur mit der höchsten Auflösung zu erhalten, nehmen wir aus diesen Symbolen eines, das wir verwenden möchten, und skalieren es dann noch weiter. Also wollte ich das eigentlich als Teil einer Atlas-Textur verwenden . Wenn Sie es also ausgewählt haben, klicken Sie mit der rechten Maustaste darauf und gehen Sie dann zu Kopieren. Und geben Sie in der Drop-down-Liste hier oben Atlas-Textur ein. Klicken Sie auf Atlas-Textur und dann mit der rechten Maustaste auf das Atlas-Ende einfügen Jetzt können wir hier auswählen, welches Symbol wir verwenden möchten. Also einfach alles, was du für gut hältst, es gibt eine Menge Optionen. Und das ist das 64 x 64 Textur-Sprite Sheet aus dem Icons Pack Das war offensichtlich, also eines der drei Kunstschätze, die wir für das Projekt haben Also so etwas wie diese Zwillingsschwerter oder das glänzende Schwert könnte ziemlich gut funktionieren Alles, was wie eine leuchtende menschliche Figur aussehen würde, irgendwie bedeuten würde : Oh, ich Ich wurde superstark, zum Beispiel speziell so, oder im Basisprojekt habe ich dieses verwendet, was eher ein Blitz ist, aber es könnte auch funktionieren Okay, dieses Mal nehme ich den, bei dem es wie ein riesiger Lichtstrahl aussieht eher wie ein riesiger Lichtstrahl aussieht als wie ein Blitz. Und ich werde nah dran sein. Wir haben also unser Symbol in der Textur rechts angezeigt. Das Dehnen ist nicht wirklich so, wie wir es wollen, also wollen wir den Streckmodus ändern, um den Aspekt zentriert zu halten. Ich glaube, das ist hier die beste Option. Und das wird ziemlich gut funktionieren Ich denke, wenn wir unserem Level-Up-Symbol folgen, fügen wir einen Textblock hinzu, in dem wir dem Spieler sagen, wir eine von wenigen Auswahlen treffen wollen Also lasst uns mit der rechten Maustaste auf den Container von VBux klicken, ein weiteres Rich-Text-Label hinzufügen und dann machen wir etwas Ähnliches Überprüfe, ob es zum Inhalt passt. Und dann sagen wir für den Text, wählen Sie eine der folgenden Level-Up-Optionen. Da wir beabsichtigen, dass die Pixar-Schrift hier in unserer eigentlichen Anzeige angezeigt anstatt jedes Mal zur Welt zu gehen, um zu überprüfen, wie sie mit dem tatsächlichen Spielthema aussehen wird, gehen wir zur Auswahl des Basisknotens auf der oberen Ebene der Benutzeroberfläche und weisen das Thema auch hier Laden Sie also im Inspektor schnell das Thema, und dann wird unser Text aktualisiert Jetzt können Sie sehen, dass der Text mit dieser anderen Schriftart tatsächlich in eine Zeile passt. Das ist ein großer Unterschied. Klicken wir auf das zweite Rich-Text-Label und zentrieren wir es. Okay, als Nächstes nehmen wir diesen Titel und machen ihn etwas interessanter indem wir mit dem BB-Code einen Regenbogen- und einen Welleneffekt hinzufügen. Überprüfen Sie also, ob der BB-Code hier aktiviert ist, und gehen Sie zum Anfang des Textes oben links. Wir setzen in eckigen Klammern für BB-Code Regenbogen und dann Leerzeichen FREQ für Frequenz gleich 0,5 Leerzeichen SAT gleich eins Das ist die Sättigung. Der Leerwert entspricht Eins, und wenn Sie die eckigen Klammern beenden, erhalten Sie hier auf der linken Seite einen Regenbogeneffekt Um sicherzugehen, dass das endet, gehen Sie zum Ende des Textes und setzen dann die eckigen Klammern in Regenbogen Und da haben wir unseren Regenbogeneffekt der im Viewport animiert Und wir können hier auch die Einstellungen ändern. Wenn Sie also möchten, dass es weniger lebendig ist, versuchen Sie, die Sättigung auf 0,5 zu erhöhen, und jetzt erscheint dort ein zahmerer Regenbogen Das gefällt mir irgendwie, also behalte ich es. Lassen Sie uns jetzt auch den Welleneffekt hinzufügen. Drücken Sie also erneut auf die Startseite, um zum Anfang unseres Textfeldes zu gelangen, oder Sie können einfach oben links oben klicken Und dann machen wir noch eine eckige Klammer und wir geben WA VE für Wave Space AMP ein, wenn die Amplitude gleich 50 ist So hoch geht es zwischen den Wellen. Und dann entspricht die Raumfrequenz oder FREQ zwei. So oft wird es eine Welle machen und sie dann mit der rechten eckigen Klammer beenden Okay, und dann willst du bis zum Ende hinter dem Regenbogen hier oben gehen und mit eckigen Klammern winken. Das bedeutet nur, dass, wenn du danach zusätzlichen Text hinzufügst, dieser nicht den Welleneffekt hat, weil wir den Effekt in unserem Textblock beendet haben . Also Control Z, wir können sehen, wie unser Text dort animiert wird. Das ist ziemlich nett Wir möchten vielleicht , dass die Amplitude ein bisschen runtergeht, also werde ich sie auf 30 schrumpfen lassen Wenn wir uns also unsere Animation ansehen, können wir sehen, dass der Text fast bis zum unteren oder oberen Rand unseres Labelbereichs animiert fast bis zum unteren oder oberen Rand unseres Labelbereichs Ich denke, wenn wir eine Amplitude von 50 haben, wie wir es getan haben , bevor sie überhaupt abgeschnitten wird. Das ist also nicht ideal. Wenn es zu stark nach oben oder unten geht, können wir diesem speziellen Label etwas Auffüllung hinzufügen, indem wir zu den Theme-Overrides Und dann wollen wir zu den normalen Stilen wechseln und ein neues Stilfeld erstellen, das leer ist , weil es keinen Hintergrund gibt Erweitern Sie das, gehen Sie zu den Inhaltsrändern und dann können wir den oberen und unteren Rand um ein paar Pixel versetzt machen . Also werde ich versuchen, die oberen negativen drei und die unteren negativen drei zu machen . Und dann können wir hier oben und unten einen Inhaltsrand hinzufügen . Also mache ich es so, dass es oben zwei Pixel und unten zwei Pixel sind. Okay, und das wird unsere Box im Grunde genommen etwas größer als sie standardmäßig gewesen wäre. Das ist also eine weitere Lösung, wenn Sie nicht einfach eine ganze Reihe neuer Zeilen in das Textfeld einfügen möchten . Ich denke, das wäre auch eine schnellere Option. Aber auch ein bisschen weniger präzise. Und zu guter Letzt : Wenn wir den Text größer haben möchten, können wir hier zu den Theme-Overrides gehen und die Schriftgrößen anpassen Ich denke, wir wollen eine normale Schriftgröße, und lassen Sie uns sie auf 24 erhöhen Okay, der sieht tatsächlich etwas verschwommen aus. Lass uns 32 versuchen, oder? Okay, ich denke, für diese spezielle Schriftart weil es Pixar ist, gibt es sehr spezifische Skalierungszahlen , auf die Sie die Pixelgröße einstellen müssen Wenn ich also sagen würde, dass es etwas wie 22 ist, dann ist es wohl kein Vielfaches von acht oder 16, also wird es nicht funktionieren Also lass uns stattdessen 32 machen , um das da zu haben, damit es korrekt gerendert wird Diese Überschreibungen können übrigens, wenn Sie es möchten, auch Zeit investieren und es und die Themen speziell anpassen Aber wenn es nur einmalig sein soll, ist es vielleicht schneller, Ihre benutzerdefinierten Werte speziell diesem Header zuzuweisen Ihre benutzerdefinierten Werte speziell diesem Header Nur wenn du im Spiel eine Menge Benutzeroberflächen haben wirst und diese an einem zentralen Ort anpassen möchtest, dann ist es sinnvoll, viele Themen zu erstellen Anstatt es nur für Schriftarten zu verwenden, können Sie auch die Schriftgrößen anpassen oder eine benutzerdefinierte Kopfzeile hinzufügen 44. P43 Entwerfen der Benutzeroberfläche zur Prämienauswahl und endgültige Anpassungen: Ordnung, jetzt müssen wir unsere vertikalen Auswahlfelder erstellen unsere vertikalen Auswahlfelder Das wird also eine Unterbenutzeroberfläche sein. Ich werde hier oben einen neuen Knoten erstellen. Das wird, sagen wir, eine Benutzeroberfläche sein, aber ich mache einen Rechtsklick hier und ändere den Typ in einen Panel-Container. Wir machen aus der Wurzel hier einfach einen Panel-Container. Und das wird standardmäßig in voller Größe sein und überall erweitert werden. Benennen wir es in „Prämienauswahl“ um . Und ich werde es im UI-Ordner speichern. Okay, jetzt gehen wir zur Lavop-Auswahl und ich werde drei davon in die Hierarchie aufnehmen Suchen Sie also im Projekt nach einer Belohnung und legen Sie eine davon auf VBox Ich werde es noch ein paar Mal duplizieren. Und Sie werden sehen, dass das unmittelbare Problem darin besteht , dass es drei gibt, aber sie sind alle vertikal. Also brauchen wir einen weiteren HBox-Container , um sie horizontal zu platzieren Klicken Sie also mit der rechten Maustaste auf den VBox-Container und fügen Sie einen untergeordneten HBox-Container und platzieren Sie die drei Prämienauswahlen unter dem Nun solltest du sehen, ob du auf den HBox-Container klickst , dass sie jeweils eine versetzte Position zueinander haben Aber im Moment erstrecken sie sich nicht über den Bildschirm. Also müssen wir zur Auswahl der Belohnungen übergehen, und das wird sich um das Layout und die Größe der Container kümmern. Wir wollen horizontal expandieren. Und wenn wir schon dabei sind, lassen Sie uns auch einfach vertikal expandieren. Steuern Sie, wie Sie speichern möchten, und kehren Sie zur Level-Up-Auswahl zurück. Und jetzt können wir sehen, dass es sich eine Art Kolumne handelt. Sie nehmen jeweils einen gleichmäßigen Abstand von links nach rechts ein, und das passt zu unserem Hauptpanel-Container. Das ist also eher das, wonach wir suchen. wir in der Belohnungsauswahl mit der rechten Maustaste auf den oberen Bereich und fügen Sie einen Knoten hinzu. Das wird also ein Rich-Text-Label in das Rch-Text-Label sein . Fügen wir den Text ein Wir sagen „Name in eckigen Klammern und ich aktiviere „Inhalt anpassen Wir können hier hineinzoomen, um es zu sehen. Also für die Prämienauswahl klicke ich auf Prämienauswahl und nehmen das Anker-Preset und nehmen das Anker-Preset und machen es oben links, okay? Und dann hier unten brauchen wir einen Margin-Container. Okay. Also wenn wir hier schauen, also wenn wir hier suchen, gibt es keinen Abstand zwischen unseren Beschriftungen und dem Rand dieses Panels. Fügen wir also unter der Prämienauswahl einen Margencontainer hinzu. Klicken Sie mit der rechten Maustaste auf „Container mit untergeordnetem Rand hinzufügen und machen Sie dann das Rich-Text-Label zu einem untergeordneten Element dieses Containers. Im Randcontainer werden Konstanten vom Thema überschrieben, und sagen wir, vielleicht drei Pixel für den linken, oberen, rechten und unteren Rand hier auf der Nehmen wir nun die Root-Reward-Auswahl und ich ändere ihre Anker-Voreinstellung auf, sagen wir, oben links Aber lassen Sie uns auch die Prämienauswahl nehmen und sie ein wenig erweitern, damit wir zumindest sehen können, womit wir hier arbeiten. Wir brauchen nicht, dass der gesamte Bildschirm gestreckt wird, weil das irreführend ist, aber wir wollen unseren vertikalen Inhalt sehen können Und wir können zur Level-Up-Auswahl gehen um zu sehen, wie das zu einem beliebigen Zeitpunkt nach der Größenänderung und diesem UI-Container aussehen wird beliebigen Zeitpunkt nach der Größenänderung und diesem UI-Container Bisher sieht es gut aus. Wir wollen diesen Titel jedoch in den Mittelpunkt stellen. Also klicke ich auf Rich-Text-Label und lass uns die horizontale Ausrichtung in der Mitte durchführen. Außerdem möchte ich hier für die vertikale Containergröße und für das Steuerelement die Option „Verkleinern“ verwenden. Dadurch wird sichergestellt, dass es nicht weiter expandiert als nötig Wenn wir zur Level-Up-Auswahl übergehen, sollten wir hier unsere zentrierten Beschriftungen sehen. Okay, jetzt brauchen wir unseren Icon-Platzhalter. Also klicke ich mit der rechten Maustaste auf Margin Container, füge eine Textur und dann können wir ein Symbol aus unserem Projekt auswählen Lassen Sie uns also eine neue Atlas-Textur machen. Und hier werde ich ein Atlas-Symbol aus dem 16x16-Pack schnell laden ein Atlas-Symbol aus dem 16x16-Pack Lassen Sie uns die Region bearbeiten und einen Platzhalter auswählen. Also etwas zum Levelaufsteigen, so etwas sieht ziemlich Und ich werde in die Nähe gehen. Jetzt müssen wir sicherstellen, dass das wirklich richtig organisiert ist, also benötigen wir einen VBox-Container unter dem Margin-Container Klicken Sie also mit der rechten Maustaste auf den Randcontainer, fügen Sie einen untergeordneten VBox-Container hinzu und machen Sie den Titel und die Textur zu einem untergeordneten Okay, jetzt wird es richtig organisiert. Wir müssen allerdings sicherstellen, dass das Seitenverhältnis beibehalten wird, damit es nicht komisch aussieht. also im Inspector für Textuct Ändern Sie also im Inspector für Textuct den Stretchmodus, um das Seitenverhältnis beizubehalten Außerdem sollte der Aspekt zentriert bleiben. Okay. Da. Das sieht passender aus. Möglicherweise möchten wir auch zum Layout gehen und eine Mindestgröße für Symbole festlegen. Also hier nehme ich die benutzerdefinierte Mindestgröße und wir sagen so etwas wie 48 mal 48. Okay, das wird das irgendwie erweitern. 32 mal 32 ist in Ordnung. Das heißt also nur, wenn Ihr Symbol kleiner als 32 mal 32 ist, wird es automatisch auf diese Größe skaliert. Okay, lassen Sie uns einen Beschreibungstext hinzufügen, damit ich C, das Rich-Text-Label, steuern und dann auf den VBox-Container und dann auf V klicken und ihn einfügen Und wir werden hier die Beschreibung in eckige Klammern setzen. Offensichtlich können wir sehen, dass das für diesen Bereich ziemlich groß ist, sodass wir möglicherweise später an unseren Schriftgrößen arbeiten müssen. Und dann wollen wir zum Schluss eine Schaltfläche, um die Option auszuwählen. Also werde ich auf den VBox-Container klicken und eine Schaltfläche hinzufügen. Also hier werden wir wahrscheinlich nur einen normalen Button wollen einen normalen Button wollen Dadurch können Sie ein Symbol haben, sodass wir schnell ein Testsymbol laden können, genauso wie wir es zuvor getan haben, weniger Textur, es erweitern. Schnelles Laden aus dem 16 mal 16 Spritesheet. Wählen Sie „Region bearbeiten“ und wählen Sie ein Symbol aus. Also vielleicht macht so etwas wie das Schwert mit einem Level-Up-Symbol Sinn. Okay. Jetzt können wir unseren Button als Symbol sehen. Und dann könnten wir im Textfeld „ Wählen“ sagen und angeben, was wir hier tun. Wenn wir jetzt zu unserem Level-Up-Auswahlfenster gehen, können wir unsere drei Teile der Benutzeroberfläche hier unten sehen. Wir haben drei Schaltflächen, die wir anschließen werden , um später aus ihnen auszuwählen Wir haben unseren animierten Titel. Und so wird unsere Vorlage mehr oder weniger aussehen. Es geht nur darum, die Optionen zur Auswahl bereitzustellen , sie an unseren Spieler anzuschließen und dann unseren Spieler zu aktualisieren, sobald er eine Auswahl getroffen Es geht nur darum , die Liste mit den verfügbaren Optionen zu füllen und diese dann auf den Spieler anzuwenden, sobald der Spieler seine Auswahl getroffen hat Okay, vielleicht stellen Sie fest, dass es ein kleines Problem gibt , bei dem sich der Rand unserer Symbole manchmal unserer Symbole mit möglicherweise benachbarten Symbolen überschneidet Um das zu beheben, können wir zur Prämienauswahl gehen und den Filterclip überprüfen. Für den Button. Wenn Sie das also tun, wenn Sie hierher gehen und hinein- und herauszoomen, sollte das Problem genau dort behoben sein, sodass Sie keine überlappenden Pixel mehr sehen Außerdem könnte es, was die Selektionsebene in der Welt angeht, technisch gesehen hier zentriert sein Aber Sie können sehen, dass es von diesem Mittelpunkt aus nach unten und nach rechts geht . Es wird also tatsächlich nicht mittig auf dem Bildschirm erscheinen. Um das zu bearbeiten, wäre es meiner Meinung nach eine gute Idee, unsere Canvas-Ebene zu nehmen und sie mit der rechten Maustaste als neue Szene in unserem UI-Projekt zu speichern . Also sage ich Gameplay UI Canvas als Namen, und dann öffnen wir es. Okay, wenn wir uns Hue ansehen, können wir viel klarer erkennen , wo sich unsere Objekte auf dem Bildschirm befinden und groß sie im Verhältnis zum Blickwinkel sind, als dass wir das übersichtliche Weltbild haben So können wir natürlich sehen, dass wir unsere Spielerauswahl, die Benutzeroberfläche, anklicken müssen und wahrscheinlich die Größe verdoppeln Also, was die Skala angeht, nehme ich einfach die Waage und mache daraus eine Zwei. Das muss vielleicht sogar auf drei erhöht werden. Ja, lassen Sie uns standardmäßig drei wählen. Okay, um dieses Problem zu lösen, bei dem sich unser Panel-Container im Grunde nach rechts und unten bewegt, anstatt hier zentriert zu sein. wir wollen in die Szene mit der Love-Up-Auswahl springen Ich glaube, wir wollen in die Szene mit der Love-Up-Auswahl springen und dann zum Panel-Container übergehen. Und auf der rechten Seite müssen wir den Layoutmodus auf Anker umstellen und ihn dann hier zentrieren. Ja. Okay, da. Jetzt haben wir, wonach wir suchen. Das macht also im Grunde alles, was ein Unterobjekt ist , auf diesem Ankerpunkt zentriert Wenn wir jetzt zur Canvas-Benutzeroberfläche gehen, wird es richtig zentriert. Okay, ganz schnell, lassen Sie uns dem Skript für die Llevo-Auswahl Und wenn wir bereit sind, wollen wir unsere Level-Up-Auswahl ausblenden. Also werde ich hier tippen und mich verstecken. Dadurch wird sichergestellt, dass das Spiel standardmäßig ausgeblendet wird, wenn wir es starten . Lass uns auf Play klicken. Wir gehen zu LeveOP, indem wir EXP sammeln Und da erscheint unser LevelUp-Selektor. Wir haben drei Schaltflächen zur Auswahl . Sie tun noch nichts. Vielleicht entscheiden wir später, dass wir die Musik nicht pausieren wollen, so wie es gerade passiert ist, aber abgesehen davon funktioniert alles. Das Spiel wurde komplett angehalten und unsere Benutzeroberfläche wird angezeigt. 45. P44 Erstellen eines Waffenleveling-Systems für Spielverbesserungen: Damit unser Levelaufstiegssystem funktioniert, benötigen wir tatsächlich einige Upgrades, um die Liste hier für unser Level-Up-Menü zu füllen Im Allgemeinen werden das also Waffen-Upgrades sein. Also müssen wir auch ein Levelsystem für unsere Waffen einrichten auch ein Levelsystem für unsere Waffen Wenn wir uns also die Spielerszene ansehen, haben wir die Standard-Speerwaffe und die hat eine Waffendefinition Die Waffendefinition ist hier vorerst sehr einfach gehalten, aber wir müssen ein Waffen-Upgrade hinzufügen Aber wir werden hier eine Reihe oder ein Wörterbuch von Waffen-Upgrades hinzufügen, damit wir zum nächsten Level übergehen und tatsächlich herausfinden können zum nächsten Level , wie viel Schaden diese Waffe auf einem bestimmten Level anrichten soll , sodass, wenn wir unsere Waffe starten, sie die entsprechenden Einstellungen verwendet. Und das kann auch Dinge wie die Abkühlzeit beinhalten oder wie viele Ziele eine Waffe treffen kann. Es gibt viele verschiedene Eigenschaften, die du für dein Waffensystem einrichten kannst. Wenn wir also in das Speerwaffen-Skript springen, können wir weiter zur Waffendefinition übergehen Sie können hier sehen, dass ich bereits eine Methode zum Abrufen der Abklingzeit entworfen habe, die je nach Level, der Abklingzeit für die Waffe, zurückkehrt Abklingzeit für die Waffe Wenn wir hier also unser Array definieren und dann das tatsächliche Level der Waffe übergeben, können wir die richtigen Statistiken für unsere Waffe auf ihrem aktuellen Level abrufen die richtigen Statistiken für unsere Waffe auf ihrem aktuellen Und dann müssen wir auch eine Get Seen-Methode generieren . Derzeit wird also nur die Speerszene direkt geladen die Speerszene direkt Aber wenn wir unsere Waffe aufrüsten, können wir die Option hinzufügen, dass völlig unterschiedliche Projektilszenen erscheinen, aber das wollen wir nicht erscheinen, aber das wollen wir nicht unbedingt auf jedem Level tun, also können wir es standardmäßig auf das ursprüngliche Waffenprojektil zurücksetzen und stattdessen einfach die Statistiken aktualisieren Kommen wir also dazu, indem wir so etwas wie eine Waffenstufe oder eine Waffenleveldefinition erstellen eine Waffenstufe oder eine Waffenleveldefinition Also gehe ich zum Dateisystem und wir gehen runter zu den Waffen. Lassen Sie uns hier mit der rechten Maustaste klicken und ein neues Skript erstellen. Und dann nenne ich es so etwas wie Waffenlevel, was wiederum eine Ressource sein wird. Also lass uns das erstellen. Öffne das Waffen-Level-Skript. Wir gehen nach oben und erstellen den Klassennamen Waffenlevel. Das definiert also die Statistiken für die Waffe auf diesem bestimmten Level. Eine Waffe kann also so viele Stufen haben, wie Sie möchten, und sie wird mit zunehmendem Upgrade an Stärke gewinnen. Wir können hier also einige Statistiken eingeben, auf die wir für ein anderes Waffenlevel zugreifen möchten . Ein offensichtlicher wäre also der Cooldown. Also können wir bei export var sagen, cool down, und das wird ein Float sein, und wir können standardmäßig 1.0 verwenden. Okay, also lass uns das ganz schnell speichern. Ich werde alle meine anderen Skripte hier schließen, also klicken Sie mit der rechten Maustaste und schließen alle, damit wir sehen können, was wir tun. Okay, und dann öffne hier Waffenlevel und Waffendefinition. Okay, dann wären das die einzigen beiden, mit denen wir hier arbeiten. Also, ich würde sagen, wir wollen ein Wörterbuch, wenn wir mit unseren Spielerstufen konsistent sein wollen . Und bei Export VR gibt es Levels , also ein Wörterbuch Integer- und Waffenlevel. Für die Abklingzeit von Git wollen wir also das Level ermitteln und dann die Abklingzeit anhand der Levelstatistiken zurückgeben VR-Level wird also dem Level Punkt Git entsprechen und wir werden das P-Level Und gib standardmäßig Null zurück. Jetzt wollen wir den Unterstrich für die P-Ebene entfernen , weil wir diese Variable endlich verwenden Nun, es kann hier nicht auf den Typ schließen, also müssen wir ihm den konkreten Waffentyp geben, und dann kehren wir zur Abklingzeit auf Level Dot zurück Okay, also klicken Sie mit der rechten Maustaste auf die Waffenstufe und wählen Sie das Loup-Symbol Okay, vergewissere dich, dass das auch wirklich da ist. Also, bei Get Cooldown wird es das Waffenlevel finden Wenn es die Waffenstufe nicht finden kann, es hier tatsächlich zu einem Fehler kommen Ich könnte mir vorstellen, dass wir diese Leitung oft benutzen. Also werde ich hier tatsächlich auch eine Funktion Git Weapon Level eintragen. Was eine Ganzzahl auf P-Ebene benötigt, und das wird eine Waffenstufe zurückgeben. Also können wir das einfach zurückgeben. Und stattdessen können wir hier sagen, die Waffe auf Level bringen. Geben Sie die Stufe P weiter, dann die Stufe unten. Ein guter Grund, warum wir das tun würden, ist, dass, wenn wir später Code hinzufügen wollen, sagen wir, es gibt kein Waffenlevel und wir wollen standardmäßig zum vorherigen Level zurückkehren, oder wir wollen Fehler portionieren Das alles können wir innerhalb der Funktion G ( Waffenlevel) erledigen. Und dann wird an all den anderen Stellen , die wir Get Weapon Level nennen, all dieser zusätzliche Code vorab bearbeitet. Das richtet es einfach so ein, wenn wir function get damaged, function g max hits usw. ausführen müssen , dann wird das unseren Code später reduzieren und in dieser Funktion zentralisieren Aber im Moment, besonders wenn wir Prototypen machen, möchte ich auf jeden Fall sofort wissen, ob ich vergessen habe, ein Waffenlevel einzurichten , bei dem wir erwarten würden, dass der Waffendefinition ein Waffenlevel definiert Also ich finde es total cool es einfach einen Fehler ausgibt, sobald wir versuchen, den Punkt Quo auf ein Nullwaffenlevel zu bringen. Deshalb werde ich es vorerst so lassen. Okay, lassen Sie uns jetzt in die Waffenebene springen und einige andere Eigenschaften einrichten , die wir pro Level ändern möchten. Ein weiterer offensichtlicher wäre der Schaden, den eine Waffe anrichten kann. Also bei Export Var Damage, und wir könnten Männern Schaden bis MAX Schaden zufügen, wenn wir wollen, dass es etwas interessanter ist. Wenn wir also bei Export Var Men Damage sagen und sagen wir, das ist ein Float, können wir ihn auf 10.0 voreinstellen, und dann haben wir bei Export var Max Damage, was ein Float sein wird. Und lassen Sie uns das einfach standardmäßig auf 20 setzen Welche Zahlen auch immer Sie für einen guten Ausgangspunkt halten , Sie werden sie anpassen. So ziemlich immer für jede Ressource auf Waffenebene. Wie ich bereits erwähnt habe, wollen wir wahrscheinlich auch maximale Treffer. Also bei Export V werden maximale Treffer erzielt, und das wird eine Ganzzahl sein. Ich setze es auf 1,0. Oh, außerdem die Männer Damage und MAX Damage, ich habe vergessen, dass wir es im Spiel mit ganzen Zahlen zu tun haben, also werde ich das auf Ganzzahl ändern Also werde ich das in beiden Fällen auf Integer ändern, um konsistent zu sein Natürlich könnten Sie Gleitkommazahlen in Kombination mit Ganzzahlen verwenden in Kombination mit Ganzzahlen Aber ich denke, in diesem Fall, wenn wir immer wollen, dass der Schaden keine Dezimalzahl ist, ist es einfach besser, in all unseren Skripten konsistent zu sein in all unseren Okay. Und dann sagt auch Maximum Hit, dass Integer dort kein Dezimalzeichen haben sollte. Wir werden hier wahrscheinlich auch irgendwo eine Geschwindigkeitsvariable haben wollen . Also exportiere die Geschwindigkeit von var, und das wird ein Float sein. Ich setze es dort auf 100,0, also ungefähr Pixel pro Sekunde. Dann auch ein kurzer Kommentar . Jetzt haben wir also eine Reihe von Immobilien. Wir wollen die Ressource in unserer Definition für Speerwaffen einrichten unserer Definition für Speerwaffen Okay, lassen Sie uns die Ansicht verkleinern und auf die Speerwaffe klicken. Hier auf der rechten Seite haben wir unsere Waffenstufen, also richten wir sie ein Das Level entspricht also nicht einer Array-Position, sondern dem tatsächlichen Level der Waffe. Also wollen wir hier mit einem beginnen. Und dann wollen wir ein neues Waffenlevel machen. Okay, in unserem Waffenlevel könnten das unsere Basissets sein. Warum fügen wir nicht einfach das Schlüsselwertpaar und das wird die Standardeinstellung für unseren Level-1-Speer sein. Fügen wir zwei hinzu und dann ein neues Waffenlevel. Und wir wollen den Schaden hier erhöhen. Also ich sage 15 bis 25, und vielleicht ist die Geschwindigkeit etwas schneller, also 110 für die Geschwindigkeit. Beim Abkühlen können wir etwas schneller starten , also sage ich 0,9, und MAX-Hits werden immer noch auf eins gesetzt weil das Hinzufügen eines zusätzlichen Max-Hits eine ziemlich große Sache ist. Das könnte so sein, als ob du deinen Schaden effektiv verdoppeln würdest. Also lass uns das hinzufügen. Und dann lass uns Level drei machen, neues Waffenlevel. Wir sagen 20 bis 25 Schaden, die Geschwindigkeit vielleicht 115 und dann die Abklingzeit auf 0,9, aber wir erhöhen die maximalen Treffer auf zwei. Also kannst du dir hier irgendwie ein Bild machen. Wir wollen fast immer, dass einige der Zahlen steigen. Ich sollte das Gefühl haben, dass jedes Level ein Upgrade gegenüber dem vorherigen ist. Wir müssen die Upgrades nicht unbedingt linear ändern. So könnte zum Beispiel ein Level einen massiven Schadensschub bedeuten, aber die Geschwindigkeit des Projektils bleibt gleich Wie dem auch sei, füge das hinzu und wir machen so viele Level weiter, wie du willst Okay, um weiterzumachen, machen wir vier. Wir werden hier ein neues Waffenlevel einbauen, und es könnte helfen, das vorherige Waffenlevel zu erweitern , damit du weißt, was du aufrüsten musst. Wir beginnen also mit einem Schaden von 20 Männern. Machen wir jetzt 25 drauf und dann 30 für den MX-Schaden und die Geschwindigkeit 120, die Abklingzeit 0,8. Das Maximum erreicht zwei. Fügen Sie ein Schlüssel-Wert-Paar hinzu. Mach einfach weiter. Okay, und ich habe nur zum Spaß noch eine fünfte hinzugefügt . Also, du kannst die Statistiken genau dort sehen, wenn du sie kopieren möchtest. Eine wichtige Statistik, die ich tatsächlich vergessen habe, ist die Anzahl der pro Einsatz gespawnten Projektile Lassen Sie uns also Var-Projektile exportieren, und das ist eine Ganzzahl, die eins entspricht Die Anzahl der pro Wurf zu instanzierenden Projektile ist also eine sehr starke Eigenschaft Wenn wir also wollen, dass ein Level extrem stark ist, dann könnten wir sagen, vielleicht Stufe fünf Pro Einsatz haben wir zwei Projektile, wodurch die Waffe viel mehr Schaden verursacht Nun wollen wir nicht, dass die Projektile in den meisten Fällen exakt zur gleichen Zeit erscheinen in den meisten Fällen exakt zur gleichen Zeit Eine Möglichkeit wäre, sie zu verschieben, sodass du sehen kannst, wo sie erscheinen werden Eine weitere Option, die Sie hinzufügen könnten, wäre , nach dem Wurf zu verzögern, wie lange es dauert, bis jedes Projektil Man könnte also sagen, lassen Sie uns beides als Option hinzufügen Wir könnten also bei Export Var Offset oder Span Offset sagen. Es wird ein Float sein. Es wird gleich Null sein, Null. Und dann ist beim Export VR die Spawn-Verzögerung ein Float, und wir sagen 0,05 Sekunden. Also das wird irgendwie so aussehen. Spawn-Offset ist der maximale Offset für die Position der sofortigen Spanne des Projektils Wie weit kann es also vom Mittelpunkt entfernt sein, wenn es Und dann ist die Span-Verzögerung die Zeit und die Sekunden, die zwischen weiteren Projektilspannen abgewartet werden müssen, und ich sollte sagen, nach der ersten ist das der entscheidende Wert Okay, also im nächsten Video werden wir daran arbeiten, diese Waffenstufen zu nehmen und so zu gestalten, dass wir sie innerhalb unserer Benutzeroberfläche tatsächlich aufleveln können sie innerhalb unserer Benutzeroberfläche tatsächlich aufleveln 46. P45 Waffengegenstände zum Aufstufen der Waffenkraft: Okay, für den nächsten Teil müssen wir die Möglichkeit einführen, über unsere Benutzeroberfläche zur Levelaufstieg den Gegenstand für das Waffen-Upgrade zu finden , sodass wir die Waffe aufleveln können , die im Spiel tatsächlich aktiv ist Der erste Schritt besteht also darin, innerhalb unserer Level-Up-Auswahl eine Optionsliste oder Ressource zu erstellen innerhalb unserer Level-Up-Auswahl eine Optionsliste oder Ressource , die wir verwenden werden, um die Optionen hier unten auf der Grundlage einer zufälligen Auswahl aus den verfügbaren praktikablen Optionen auszufüllen hier unten auf der Grundlage einer zufälligen Auswahl aus den verfügbaren praktikablen Optionen auszufüllen aus den verfügbaren praktikablen Optionen Ich sehe hier unten links, dass sich die Projektile im Level-Ordner Ich werde das tatsächlich auf Waffen umstellen, das macht einfach mehr Sinn Da der Levels-Ordner also nichts enthält, werde ich ihn in Einstellungen umbenennen, weil wir eigentlich eine Liste von Waffen-Upgrades oder anderen Upgrades erstellen Waffen-Upgrades oder anderen Upgrades aus denen wir in unserem Spiellevel wählen können. Und wir könnten das je nach Charakter oder je nach dem Level, das wir in unser Spiel laden, unterscheiden , aber wir wollen die Möglichkeit haben , es so oder so anzupassen. Also werden wir ein neues Skript erstellen, und ich nenne es die Leveling-Optionen Punkt gD. Das wird eine Ressource sein, sodass wir sie im GIDOeditor bearbeiten können Und dann werde ich hier reingehen. Und sagen wir, Optionen zur Nivellierung von Klassennamen. Zu Beginn des Kurses haben wir Pickups eingeführt. Diese Pickups existieren momentan nur als Szene in der Spielwelt, sie werden aufgenommen und die EXP werden den Spielern sofort hinzugefügt Wir brauchten also keinen speziellen Gegenstand , weil diese EP nur einen Wert modifizieren. Aber wenn wir etwas Komplexeres wollen, wie einen Gesundheitsbonus oder die Fähigkeit, eine Waffe zu verbessern, dann brauchen wir eine konkretere Objektklasse innerhalb unseres Spiels, und so ziemlich alle RPG-Spiele werden sie irgendwann haben. Deshalb wollen wir eine Liste von Gegenständen exportieren , die wir sofort mit unserem Spieler verwenden können Also werde ich Artikel exportieren, und das wird eine Reihe von, sagen wir, Artikel für den Moment sein. Jetzt haben wir keine Artikelklasse erstellt. Lassen Sie uns also unten links einen Ordner für Artikel erstellen. Ich klicke mit der rechten Maustaste und erstelle einen neuen Ordner. Ich nenne das Items. Und dann werde ich hier mit der rechten Maustaste klicken und ein neues Skript erstellen. Und das wird Punkt gD sein, der sich von Resource aus erstreckt. Okay, also hier drinnen machen wir das Klassennamenelement. Speziell für ein Survivor-ähnliches Spiel haben wir möglicherweise nicht unbedingt Gegenstände, die in einem Inventar existieren Sie müssen sich also trotzdem sofort bewerben. Weise, wie sie sich bewerben, ist jedoch komplexer als nur der ExbPickup, da eine sofortige Vergabe von Erfahrung Damit wir unsere Items zumindest auf einen Spieler oder ein Ziel anwenden können , werde ich eine Funktion erstellen Wir sagen function try apply, was ein P-Ziel benötigt, nicht zwei D, und es wird ein Boolescher Wert zurückgegeben Versuchen Sie es also mit apply, weil es Umstände geben kann, unter denen es fehlschlägt, und es könnte hilfreich sein, irgendwo in unserem Code eine Rückmeldung darüber zu haben , ob es erfolgreich war, oder wir möchten vielleicht auch eine Can-Apply-Funktion, damit wir im Voraus überprüfen können ob sie tatsächlich praktikabel ist oder Ich würde also sagen, dass die Funktion angewendet werden kann, und sie wird das Ziel übergeben , ohne zwei D und die Rückgabe von Booleschen Also standardmäßig sage ich hier return false, weil es sich um ein Basiselement handelt Wir können es nicht anwenden, und ich sage auch hier einfach return false. Also werde ich es einfach in eine Warnung einfügen, dass wir den Basisgegenstand nicht auf ein Ziel anwenden können, und dann lass uns unseren Waffengegenstand erstellen , weil uns das zuerst am meisten beschäftigt. Also klicke ich mit der rechten Maustaste auf Gegenstände, erstelle ein neues Skript, und das wird ein Gegenstand mit Waffenunterstrich sein, er wird vom Gegenstand als Basisklasse erben , also erstellen wir Also Waffengegenstand hier, wir gehen nach oben und geben den Klassennamen Waffengegenstand ein , der ein Knoten zwei D ist . Das wird Boolean zurückgeben Also brauchen wir eine Möglichkeit, auf die Waffenausstattung des Charakters zuzugreifen , falls er Einfach ausgedrückt, wäre weit Ausrüstung gleich p Zielpunkt finde Kind, und wir werden nach Waffenausstattung suchen Okay? Und das sollte eine Art Waffenausstattung zurückgeben Lassen Sie uns das also tatsächlich in eine eigene Funktion überführen. Also, Funktion Get Loadout , sie wird Waffen Loadout zurückgeben Und dann werden wir stattdessen einfach das zurückgeben , die Waffenausstattung des Zielpunkts Fine Child zurückgeben Also müssen wir das Ptarget hier weitergeben. Und dann können wir den Typ ableiten. Also mache ich Doppelpunkt gleich, Loadout auf pTarget und dann geben wir zurück, ob das momentan existiert Und dann wollen wir überprüfen, ob die Ausrüstung die Waffendefinition hat , die wir gerade Das könnten wir also beim Export der VR-Definition machen. Und das ist eine Waffendefinition, eher eine Waffendefinition. Okay, nachdem wir die Ausrüstung bekommen haben, wollen wir überprüfen, ob die Waffe neben der Ausrüstung existiert Wenn ja, werden wir sehen, ob es noch Spielraum gibt, um es zu verbessern, oder ob wir die Levelobergrenze bereits erreicht haben Also müssen wir innerhalb der Ausrüstung wissen, welche Waffen sich diesem System tatsächlich darunter befinden also fertig sind, können wir alle bereits vorhandenen Loadouts besorgen und dann eine Methode hinzufügen, sodass wir ihr eine neue hinzufügen können sie an das Array anhängt, wobei wir uns auf all ihre untergeordneten Waffen beziehen Nehmen wir an, Var Weapons ist ein Array von Waffen zwei D, und bei der Funktion underscore ready, was void zurückgibt, wollen wir alle Kinder vom Waffentyp bekommen Also für Waffe in „Kinder suchen und leere Anführungszeichen für die Musterzeichenfolge stimmten vom Namen her nicht überein Aber für den Typ werden wir Waffe zwei D verwenden, und hier spielt die Groß - und Kleinschreibung eine Rolle, hier spielt die Groß - und Kleinschreibung denn das ist der Klassennamentyp Also das bringt Kinder nur mit Waffe zwei D zurück . Und dann können wir sagen Waffen Punkt Penn-Waffe Und jetzt, wo das Drehbuch beginnt, haben wir alle bereits existierenden Waffen Wir könnten sagen, wir haben eine Funktion zum Hinzufügen von Waffen, die eine P-Waffe , also eine Art von Waffe zwei D, verwendet, eher Vitun void und wir sagen Waffen Penn P-Waffe Und wir wollen sichergehen, dass es ein Kind dieser Waffe ist Also machen wir das in einer Funktion. Wir sagen Child of P-Waffe hinzufügen. Das wird für den Moment gut sein. Gehen wir also zum Gegenstand Waffen über. Wir haben die Ausrüstung, damit wir überprüfen können, ob sie schon da ist. Nachdem wir die Ausrüstung erhalten haben, wollen wir die Waffe bekommen, die dieser Waffendefinition zugeordnet ist Nehmen wir an, unsere Waffe entspricht der LoadOut-Waffe, basierend auf einer Definition Also werden wir hier Definition sagen. Gehen wir nun zur Waffenausstattung über und machen wir die Funktion G-Waffe, basierend auf der Definition Also P-Definition. Ist eine Waffendefinition. Wir werden eine Waffe an D zurückgeben. Und sagen wir, für Waffe in Waffen, wenn die Waffendefinition der P-Definition entspricht, werden wir diese Waffe zurückgeben. Andernfalls geben wir Null zurück. Da wir nur ein paar Waffen durchsuchen müssen , ist es völlig in Ordnung, eine solche kleine Schleife zu haben , aber nicht wirklich ein Problem. Außerdem, wenn du die Anzahl der Waffen, die ein Spieler haben kann, einschränken willst , dann könntest du etwas sagen, was eher so ist wie beim Export VR Max Waffen eine Ganzzahl von sechs oben. Und dann können wir überprüfen, ob auch Speicherplatz vorhanden ist. Wir könnten also sagen, dass die Funktion Leerzeichen hat, und das wäre ein boolescher Rückgabetyp, und wir würden einfach sagen, dass Return Weapons Dot Si kleiner als die maximale Anzahl an Waffen ist Okay, das ist also nur eine einfache kleine Hilfsfunktion Force Nun zurück zum Waffengegenstand, wenn sie die Waffe haben, dann wollen wir sehen, ob wir sie aufleveln können. Es könnte sogar Sinn machen hier den Waffentyp zwei D zu deklarieren, obwohl dies bereits aus dem Funktionsaufruf der Waffe abgeleitet Funktionsaufruf der Waffe Okay, also zuerst, wenn es keine Waffe gibt, also wenn Waffe gleich Null ist, also wenn Waffe gleich Null ist, dann geben wir Load Out hat Leerzeichen zurück , um herauszufinden, ob wir sie anwenden können oder Denn wenn die Waffe nicht im Waffensystem existiert, müssen wir nur schauen, ob Platz ist, um eine neue Waffe hinzuzufügen Andernfalls, wenn es eine Waffe gibt, wollen wir sehen, ob wir sie aufrüsten können. Also dann sagen wir Waffe zurückgeben. Es könnte so etwas wie C Level Up oder Has Next Level sein. Ich denke, Has Next Level klingt auch nach einem guten Namen. Jetzt brauchen wir diese Funktion in unserem Weaps-to-D-Skript. In Weapons to D wollen wir also das Level mit der Definition vergleichen und einfach prüfen, ob es ein nächstes Level gibt. also unten Lassen Sie uns also unten unsere Funktion erstellen. Die Funktion hat also das nächste Level. Dies wird Boolean zurückgeben. Nehmen wir an, Funktion nächstes Level, und das ist eine Waffenstufe, die der Definition entspricht . Holen Sie sich die Waffenstufe unseres aktuellen Levels plus eins, was Null zurückgeben kann Also geben wir zurück, dass das nächste Level nicht gleich Null ist. Denn wenn es ein nächstes Level gibt, dann können wir das nächste Level erreichen. Wir können aufsteigen. Wenn nicht, dann haben wir entweder die Levelobergrenze erreicht oder wir haben vergessen, ein Level zu definieren. Wir haben vielleicht Stufe sieben definiert, aber haben wir Stufe sechs definiert, als wir Stufe fünf waren? Weil fünf auf sechs gehen kann, aber wir können nicht einfach auf sieben springen, zumindest normalerweise. Das sollte unsere Bedürfnisse dort erfüllen, damit wir prüfen können, ob wir uns bewerben können. Und wenn wir uns dann bewerben wollen, sagen wir Funktion, Bewerbung. Und lassen Sie mich die Basisklasse hier überprüfen, nur um sicherzugehen, dass wir versuchen, uns zu bewerben. Es könnte tatsächlich Sinn machen, das zu kopieren. Okay. Und dann werden wir das hier unten überschreiben, indem wir dieselbe Funktion erneut deklarieren Also müssen wir zuerst die Waffe besorgen , wenn wir uns bewerben wollen Var-Waffe ist also eine Waffe mit zwei D, und das wird der LoadOut-Waffe unserer Definition entsprechen LoadOut-Waffe unserer Definition Also, wenn die Waffe nicht da ist, dann scheitern wir schon. Wenn also Waffe gleich Null ist, geben wir Stürze zurück. Aber wir müssen uns auch die Ausrüstung wieder besorgen. Var-Loadouts werden also vom Typ des G-Loadout P-Ziels abgeleitet Also bekommen wir das Loadout auf Ziel, für das wir uns bewerben wollen Also, sobald wir die Waffe haben, wollen wir sie ausbessern. Also sagen wir Weapon Dot Tri Level Up und das kommt zurück, ob wir erfolgreich sind oder nicht Also geben wir diesen Wert zurück. Jetzt müssen wir Weapon Dot Tri Level Up und Weapon Two D definieren . Gehen wir also hier runter und die Funktion Tri Level Up, und wir geben einen Booleschen Wert zurück Okay, also schauen wir oben in unserem Weapon-2-D-Skript nach oben unserem Weapon-2-D-Skript Wir können sehen, dass wir das Level und das Waffenlevel in der Waffendefinition haben , um ein bisschen effizienter zu sein und einfach irgendwie unsere aktuellen Informationen zugreifen zu können. Sobald wir das Level erreicht haben, könnten wir auch eine lokale Variable haben Wir könnten sagen, unser Waffenlevel ist ein Waffenlevel. Also weiter lesen, nehmen wir an, die Waffenstufe entspricht der Waffenstufe mit dem Definitionspunkt Git auf unserer aktuellen Stufe. Und wenn wir dann ein Level aufsteigen, wir das auch fest. Wenn wir also die Statistiken unseres aktuellen Waffenlevels sehen wollen , greifen wir einfach hier auf diesen Wert zu. Also finden wir den Wert in unserer Definition einmal, und bis wir wieder aufsteigen, haben wir Zugriff auf die Informationen in dieser Waffenstufe. Okay, jetzt mit TreveLu wollen wir das nächste Level erreichen Unsere Statistiken für das nächste Level werden also der Definition entsprechen . Holen Sie sich das Waffenlevel auf unserem Level plus eins Wenn also die Statistiken der nächsten Stufe gleich Null sind, geben wir Falsch zurück Andernfalls sagen wir, dass die Waffenstufe den Statistiken der nächsten Stufe entspricht, und wir sagen Stufe plus eins Stufe plus entspricht eins und wir geben „Wahr“ zurück Okay, da ist also unsere Level-Up-Funktion. Okay, das Letzte, was wir in diesem Video für den Waffengegenstand tun werden, ist, ihn zu erstellen. Also klicken Sie in Gegenstände mit der rechten Maustaste, erstellen Sie eine neue Ressource, suchen Sie nach einem Waffengegenstand, drücken Sie die Eingabetaste, wir werden das in Gegenstände einfügen. Also sagen wir Speergegenstand. Und wenn Sie auf den Speergegenstand doppelklicken, können Sie sehen, dass wir hier einen Platz für die Definition haben Wir möchten, dass die Definition exakt der Definition unserer Speerwaffen Wenn du also auf Speerwaffe klickst, kannst du sehen, dass sie die Waffendefinition hat Lass uns hier mit der rechten Maustaste klicken und das innerhalb von Waffen speichern. An der Wurzel gehen wir also zu Waffen und dort haben wir die Definition von Speeren Wir wollen doppelklicken und das überschreiben. Okay? Also hier ist unsere eigentliche Definition von Speerwaffen, und das ist jetzt eine gemeinsame Ressource Wir können also auf den Gegenstand Speer klicken und möchten dieselbe Speerdefinition schnell laden Jetzt wird der Speer-Gegenstand auf diese Weise mit der Speerwaffe verknüpft Damit wir die Speerwaffe zwei D wiederverwenden können . Speichern wir diesen Zweig als Szene Klicken Sie mit der rechten Maustaste auf Zweig speichern als SN. Und legen wir es als Spear Weapon Dot TCN in den Waffenordner Spear Weapon Dot TCN in den Waffenordner Okay, jetzt könnten wir es bei Feinden oder wo auch immer wir es brauchen, wiederverwenden Feinden oder wo auch immer wir es brauchen Der entscheidende Punkt ist nur , dass wir sicherstellen, dass sie dieselbe Speerdefinition verwenden, was sehr wichtig ist, sonst wird der Speergegenstand niemals in der Lage sein, die Speerwaffe in der Ausrüstung zu finden. Okay, jetzt haben wir die ganze Vorarbeit geleistet . Also, nächstes Video, werden wir die Benutzeroberfläche einrichten und das Leveln für die Aufrüstung unserer Waffen zum Laufen bringen Leveln für die Aufrüstung unserer Waffen zum Laufen 47. P46 Erstellen eines gewichteten Gegenstandsauswahlsystems für Stufenaufstiegsbelohnungen: An dieser Stelle müssen wir unserer Auswahl für Stufenaufstiege eine Liste mit Waffengegenständen hinzufügen , aus denen wir wählen können , wenn wir das Fenster füllen Stelle kommt also das Leveling-Option-Skript ins Spiel, bei dem wir für eine bestimmte Spielwelt oder ein bestimmtes Level des Spiels einfach diese Reihe von Gegenständen haben, die wir in der Level-Up-Auswahl zuweisen können Im Skript zur Level-Up-Auswahl müssen wir also eine virtuelle Realität für Optionen exportieren, und das wird vom Typ Leveling-Optionen sein Okay, also speichern wir dieses Skript, und wenn wir uns jetzt den Inspektor und die beiden D-Ansichten ansehen, also klicken wir auf Level-Up-Auswahl und dann drüben auf der rechten Seite können wir unsere neuen Leveling-Optionen erstellen Nun, das ist wahrscheinlich sehr stufenspezifisch Vielleicht hast du eine Stufe eins wo du viele Optionen hast, und dann Stufe zwei, vielleicht ist es etwas schwieriger, also schränkst du die Gegenstandsliste ein , oder sie könnte sogar pro Charakterklasse sein, wenn du dich dafür entscheidest, Gegenstände auf bestimmte Charaktere zu beschränken In jedem Fall wird es sich um eine Ressource handeln, auf die Sie mit der rechten Maustaste klicken und sie dann im Projekt speichern möchten die Sie mit der rechten Maustaste klicken und sie dann im Projekt speichern Gehen wir also, sagen wir, in den Einstellungsordner, weil ich aus diesem Grund das Leveling-Optionen-Skript eingefügt habe, und dann geben wir Level-1-Level-Optionen ein und speichern dann, das ist ein Punkt TRS Und jetzt können wir eine Reihe von Elementen zuweisen. Also werde ich das auf eins erhöhen und wir werden schnell den Waffengegenstand des Speer-Gegenstands laden den Waffengegenstand des Speer-Gegenstands Und das ist eine der Möglichkeiten, die wir unserem Level-Up-Auswahlskript nutzen können In unserer Hierarchie wollen wir, dass die Level-Up-Auswahl die Optionen, sagen wir, an diesen HBox-Container weitergibt , von dem wir sagen könnten, dass er eher der Prämienauswahl ähnelt In Bezug auf unsere Hierarchie haben wir die Option also auf der Auswahlebene der höheren Ebene festgelegt Wenn wir das Menü öffnen, um unseren Charakter hochzustufen, wird unsere Auswahl an Belohnungen hier unten in diesem H-Box-Container angezeigt. Jede der Belohnungen, die wir wählen durften , wird hier unten als Option angezeigt Standardmäßig wären das drei. Aber es hängt wirklich davon ab, wie viele Artikel wir zur Verfügung haben. Wir könnten diesen HBox-Container also in etwas wie einen Belohnungsbox-Container umbenennen etwas wie einen Belohnungsbox-Container und dann mit der rechten Maustaste klicken und ihm ein Skript geben Also werde ich ein Skript anhängen und wir werden es im UI Slash Rewards Box Container speichern Der Grund, warum ich das mache, ist , dass je mehr Sie die verschiedenen Funktionen Ihrer gesamten Benutzeroberfläche in separate kleinere Skripte unterteilen, desto wiederverwendbarer wird jede dieser Komponenten sein, da Sie die Verantwortlichkeiten voneinander trennen Der Container der Prämienbox wird also ausschließlich dafür verantwortlich sein , die Belohnungen aufzufüllen , die unter ihm landen werden Also werden wir einen Container für die Belohnungsbox mit Klassennamen erstellen und dann wollen wir eine vollgepackte Szene exportieren, um jede dieser Prämienauswahlen zu instanzieren Die werden also nicht wirklich da sein. Und die BaseUI, die werden gelöscht und nur dann instanziiert, wenn wir eine Belohnung haben, die wir tatsächlich befüllen können Lassen Sie uns also eine Funktion populate erstellen und dafür wird Und wir möchten auch wissen, aus wie vielen Elementen gleichzeitig ausgewählt werden kann Ich denke also, Leveling-Optionen wären ein guter Ort, um diese Eigenschaft und nicht die Benutzeroberfläche selbst zu platzieren diese Eigenschaft und nicht die Benutzeroberfläche selbst Klicken wir also mit der rechten Maustaste auf Leveling-Optionen , Lookup-Symbol Und ich werde bei export var MAX Underscore Choices sagen , was eine Ganzzahl sein wird, und ich werde den Standardwert auf drei setzen Und wenn wir noch einen Schritt weiter sind, möchte ich eine große Änderung an dieser Reihe von Elementen vornehmen Ich werde es tatsächlich in ein Wörterbuch mit Einträgen umwandeln , sodass wir jedem einzelnen eine Gewichtung zuweisen können. Und das macht es so, dass wir, wenn wir ein Objekt als mögliche Option priorisieren wollen , das tun können, indem wir seine Drop-Rate effektiv erhöhen, indem wir ihm einen höheren Float-Wert oder einen niedrigeren Float-Wert für seltenere Artikel geben einen höheren Float-Wert oder einen niedrigeren Float-Wert für seltenere Nun, da ich den Typ dieser Variablen geändert habe, bedeutet das, dass ich sie in der Levelauswahl zurücksetzen muss Wenn wir also zur Levelauswahl gehen und uns hier unser neues Wörterbuch ansehen, müssen wir den Artikel angeben. Laden Sie also schnell den Speer-Gegenstand und geben Sie ihm dann einen Wert. Wir könnten eins sagen, wenn wir möchten. Jetzt hat dieser Speer-Gegenstand also eine Chance, um 1,0 zu fallen. Und genau wie bei den anderen Fällen, in denen wir Gewichte nach dem Zufallsprinzip ausgewählt haben , bezieht sich 1,0 auf das Gesamtgewicht aller anderen Elemente auf dieser Liste Im Moment sind es also 100%, weil es nur ein Gewicht gibt , das mehr als 1,0 hat, also ist es eins von eins Aber wenn wir vier weitere Artikel hinzufügen, dann wäre das eine Chance von 20%. Und weil wir drei Auswahlmöglichkeiten geben, wird es natürlich dreimal gewürfelt. Sobald wir einen Artikel auf unserer Auswahlliste ausgewählt haben, wird er ebenfalls aus den Gesamtgewichten entfernt. Wenn wir fünf Optionen hätten, würden wir drei davon wählen, drei einzigartige Optionen, würde ich sagen. Gehen wir also zum Rewards-Box-Container. Jetzt haben wir, aus wie vielen wir tatsächlich wählen werden. Oh, und wir wollen das Gesamtgewicht ermitteln. Liste der Optionen, wobei sichergestellt wird, dass jede Option für das spezifische Ziel verfügbar ist. Lassen Sie uns dafür also eine weitere Funktion erstellen. Ich nenne es Funktion, Generieren von Auswahlmöglichkeiten. Und so nehmen wir die P-Optionen als Nivellierungsoptionen und das P-Ziel als Knoten zwei D. Okay, also zuerst wollen wir die verbleibenden Optionen aus der Liste der Optionen abrufen die verbleibenden Optionen aus der Liste der Optionen Wenn also unsere verbleibenden Optionen sagen wir, dem Artikelgewicht von Poptionst oder dem Artikelgewicht entsprechen, und wir duplizieren Okay, dann ist der Grund, warum wir es hier duplizieren, weil wir dieses Wörterbuch der Artikel mit ihren Gewichten und wir duplizieren Okay, dann ist der Grund, warum wir haben wollen Um speziell auf diese Funktion einzugehen, wollen wir nicht das Originalwörterbuch manipulieren , indem wir Elemente aus diesem Wörterbuch entfernen Alle Leveling-Optionen sollten im Grunde für den Rest des Spiels in den Leveling-Optionen bleiben Grunde für den Rest des Spiels in den Leveling-Optionen , weil das eine Definition für die Bearbeitungszeit ist, und das sind unsere verbleibenden Optionen zur Laufzeit Also duplizieren wir die Liste und entfernen sie von ihr, nachdem wir jede Auswahl getroffen haben oder nachdem wir eine mögliche Option für ungültig erklärt haben Das Duplikat hier ist also wichtig, um sicherzustellen , dass wir das Originalwörterbuch nicht ändern Effektiv. Jetzt haben wir die verbleibenden Optionen Wir möchten alle ungültigen Optionen herausfiltern. Also, was die Option in den verbleibenden Optionen betrifft, Punkttasten, warum Schlüssel? Weil die Schlüssel in diesem Wörterbuch die Elemente und die Werte die Gewichte sind. Es könnte also tatsächlich hilfreich sein , den Typ hier oben zu deklarieren, auch wenn er aus dem Gewicht der Artikel abgeleitet wird, ist es besser, wenn wir ihn auf dem Bildschirm sehen können Also sage ich Wörterbuch des Artikels, und dann haben wir das Gewicht Oh, warte, das Gewicht ist schwimmend. Und da können wir sehr deutlich sehen , dass es sich bei dem Gegenstand um die Schlüssel handelt Und der Float ist der Wert. Für jedes dieser Elemente wollen wir überprüfen, ob das Ziel es anwenden kann? Eigentlich wäre es vielleicht besser , diesen Artikel hier zu nennen. Für das Element des Typs Element in den übrigen Optionen mit den Punkttasten können wir sagen, ob das Element Punkt zutrifft und weil wir es hier eingegeben haben, erhalten wir Zugriff auf die Funktionen im automatisch ausgefüllten Menü Also wollen wir sehen, ob wir das auf das P-Ziel anwenden können. Wenn wir es also nicht auf Pre-Target anwenden können, sollten wir das umkehren. Wenn also das Element Doc nicht auf das P-Ziel angewendet werden kann, werden wir das Schlüssel-Wert-Paar entfernen Wenn wir also die Punkttasten verwenden, erhalten wir ein Array. Dieses Array ist also vom Originalwörterbuch getrennt , sodass ich denke, dass wir dieses Wörterbuch tatsächlich problemlos ändern können , dass wir dieses Wörterbuch tatsächlich problemlos ändern da wir hier bereits das separate Schlüsselarray haben. Also diese Schleife hier, wenn wir das Wörterbuch ändern, wird das kein Problem sein. Normalerweise solltest du damit vorsichtig sein. Sie sollten also ein Array nicht ändern, während Sie es in einer Schleife durchgehen, aber in diesem Fall ist dieses Array von diesem Wörterbuch getrennt, also sollte es in Ordnung sein Wir werden aber mit Sicherheit sehen, wann wir den Code tatsächlich ausführen. Wenn wir das Element also nicht anwenden können, möchten wir es aus der Liste der Optionen entfernen , da wir es nicht verwenden können. Die verbleibenden Optionen werden also nicht entfernt oder vereinfacht, ja. Okay, hier heißt es Löschen. Und wir haben den Schlüssel genau dort. Der Schlüssel ist der Gegenstand. Also löschen wir das Objekt daraus, und das wird das als Option entfernen. Nachdem wir alle Optionen wiederholt haben, haben wir bereits alle Optionen herausgefiltert, die wir nicht anwenden können Jetzt müssen wir nur noch eine Auswahl treffen , die auf dem Gesamtgewicht basiert, und nachdem wir jede einzelne ausgewählt haben, entfernen wir sie aus den verbleibenden Optionen Unser Gesamtgewicht wird hier also ein Float sein, das 0,0 entspricht, und wir müssen die verbleibenden Optionen noch einmal durchgehen. Wir könnten also sagen, dass vier Gewichte schwimmend sind und die restlichen Optionen Punktwerte haben, dann sagen wir, dass Gesamtgewicht plus diesem Gewicht entspricht Also ich denke, das ist eine ziemlich klare Art, das aufzuschreiben. Also, jetzt haben wir das Gewicht zusammengezählt. Wir wollen eine zufällige Auswahl zwischen Null und dem Gesamtgewicht treffen zwischen Null und dem Gesamtgewicht und dann sehen, welches wir ausgewählt haben zufällige VR-Gewicht wird also vom Typ Rand F mal dem Gesamtgewicht abgeleitet vom Typ Rand F mal dem Gesamtgewicht Also haben wir das im Kurs bisher ein paar Mal gemacht. Das Gesamtgewicht ist unser Maximalwert. 0,0 ist unser Minimalwert. Und wenn wir im Grunde genommen 0,0 bis zum Einfachen des Gesamtgewichts nehmen, erhalten wir einen Wert zwischen Null und dem Gesamtgewicht. Okay, jetzt haben wir unser zufälliges Gewicht und wollen einen Artikel aus den verbleibenden Optionen auswählen. Und hier wird es übrigens eine Schleife geben, aber wir können es einfach zuerst für einen Artikel aufschreiben. Okay, jetzt hier vier Optionen in den verbleibenden Optionen. Also werden wir sagen, ob das aktuelle Gewicht größer oder gleich dem zufälligen Gewicht ist, dann wählen wir diese Option. Jetzt brauchen wir also auch hier tatsächlich ein aktuelles Gewicht. Unser aktuelles Gewicht wird also ein Float sein, das 0,0 entspricht. Also wollen wir zuerst die Gewichtung der Option hinzufügen. Also aktuell wird es plus gleich den übrigen Optionen bei dieser Option sein . Also geben wir den Schlüssel zum Wörterbuch ein. Es gibt uns den Wert, und es könnte tatsächlich ein sichererer Weg dafür sein. Wir könnten also sagen, holen Sie sich eine Option. Und wenn es keine Option gibt, ist der Standardwert Null. Wir würden uns hier einen Fehler geben. Und vielleicht ist es das , was wir wollen, weil wir erwarten, dass es da ist. Es ist eine große Sache, wenn wir das Schlüssel-Wert-Paar sperren und es einfach nicht existiert. Also ja, wir lassen das einfach so sein, wie es der Option eckige Klammern gewesen wäre. Grunde ist es dasselbe, außer dass Sie mit dieser Get-Funktion ein Standard-Backup mit einem Komma und dann einer Standardvariante anwenden Komma und dann einer Standardvariante Es ist also ein bisschen flexibler, aber in diesem Fall wollen wir einen harten Fehler, falls die Option einfach nicht da ist, weil sie auf jeden Fall Okay sein sollte , also haben wir die aktuelle Gewichtung hinzugefügt Wir wollen überprüfen, ob das aktuelle Gewicht größer als das zufällige Gewicht ist. Wenn das aktuelle Gewicht also größer oder gleich dem zufälligen Gewicht ist , fügen wir es der Liste der ausgewählten Optionen hinzu . Wir könnten die ausgewählten Optionen einfach hier oben deklarieren . var selected ist also ein Array von Elementen , weil wir das am Ende zurückgeben müssen. Also werden wir die Option an das ausgewählte Array anhängen Option an das ausgewählte Array anhängen Also haben wir die Option zum Anhängen ausgewählt, und dann müssen wir sie aus der Liste der Optionen entfernen Und ich denke , ich werde das so machen dass wir hier oben eine lokale Variable einrichten Wenn unsere nächste Auswahl also ein Element gleich Null ist, wählen wir das nächste Objekt aus. Entspricht dieser Option und dann Pause. Also brechen wir aus der Viererschleife aus. Wir brauchen die Viererschleife nicht mehr. Nach dieser Schleife ist die nächste Auswahl nicht gleich Null. Dann gehen wir zur ausgewählten Option zum Anhängen von Punkten über. Andernfalls wollen wir aus unserer gesamten Vierschleife ausbrechen. Wir brauchen also eine Viererschleife, weil wir das mehrmals machen werden. Also lass uns sehen. Also ich denke hier, 44 Mal in Range, Null, CP, Unterstreichungsoptionen bei Max Choices, Unterstreichungsoptionen bei Max Choices wobei eins inkrementiert wird Das bedeutet also im Grunde, dass wir von Null zu den maximalen Auswahlmöglichkeiten gehen und jedes Mal um eins steigen Wenn wir die maximale Anzahl an Auswahlmöglichkeiten erreichen, beenden wir die Schleife. Wenn also die maximale Anzahl an Auswahlmöglichkeiten drei ist, wird dies dreimal ausgeführt. Es wird Null, Eins, Zwei sein, und wenn es drei erreicht, entspricht es den maximalen Auswahlmöglichkeiten. Ich werde die Vierer-Schleife beenden. Okay, also im Grunde nehmen wir einfach all das und klicken drüber, und jetzt wird es den ganzen Code wiederholen, richtig? Als Teil des Anfügens der Option wollen wir also auch das Gesamtgewicht nehmen, und wir wollen, dass das Minus gleich Gewicht der Optionen Wir sagen also, dass die verbleibenden Optionen keine Option erhalten. Mir ist bewusst, dass das wieder aufgerufen wird, aber das ist nicht wirklich eine große Sache. Das wird also den Fließkommawert des Gewichts ermitteln. Wir entfernen es vom Gesamtgewicht und dann wollen wir wieder hierher kommen. Es gibt also auch die andere Möglichkeit, nämlich dass nichts ausgewählt ist, was bedeutet, dass nichts mehr zur Auswahl übrig ist. Also könnten wir einfach früh aus der Viererschleife ausbrechen. Wir sprechen hier also für Loop darüber. Und das sieht für mich wahrscheinlich gut aus. Wir müssen nur die ausgewählten zurückgeben. Also kehre ausgewählt zurück. Am Ende erhalten wir also bis zu drei Artikel. Für jedes dieser Elemente möchten wir die Benutzeroberfläche füllen Nehmen wir an, VR hier oben, Auswahlmöglichkeiten werden gleich sein um Auswahlmöglichkeiten für die P-Optionen zu generieren, und wir geben das P-Ziel weiter, sodass wir jedes Objekt mit seinem Ziel vergleichen können , um sicherzustellen, dass es gültig ist Also haben wir hier jetzt die Wahl. Und dann wollen wir die Szene mit der Bardauswahl erstellen und ihr die Auswahl hier unten zuweisen Da sich dieses Bit tatsächlich außerhalb dieser Vierer-Schleife befindet, wollen wir das nächste ausgewählte Bit anhängen, weil wir als nächstes ausgewählt hier gleich der Option setzen , sodass wir es außerhalb der Vierer-Schleife verwenden können Wir wollen hier also sagen, dass als nächstes ausgewählt wurde, und wir wollen auch mit der nächsten ausgewählten Option weitermachen Eine weitere Sache, die ich hier unten vergessen habe , ist, dass ich nach der Anpassung des Gesamtgewichts auch vergessen habe, die nächste Auswahl aus den verbleibenden Optionen zu entfernen. Wir reduzieren also das Gesamtgewicht weil wir die Option entfernen, und dann entfernen wir die Option aus der eigentlichen Liste, aus der wir auswählen. Wenn es also für die nächsten vier Loop für die verbleibenden Optionen wieder hier oben steht, wird es diese Option dort nicht geben, und sie wird einfach komplett übersprungen, weil sie nicht mehr in dem Wörterbuch steht, was wir wollen. Bei den übrigen Optionen wollen wir nur die Auswahl durchgehen, wollen wir nur die Auswahl durchgehen die immer noch möglich ist, und Auswahlen , die bereits getroffen wurden, zusammenfügen 48. P47 Auswahl der Codierungsprämie mit Signalausbreitung: unserer Funktion „ Auswahlmöglichkeiten generieren stehen uns diese Auswahlmöglichkeiten zur Verfügung. Es könnte uns tatsächlich helfen, den Typ visuell genau hier zu deklarieren, anstatt ihn abzuleiten Da wir also ein Array haben, wollen wir das Array in einer Schleife durchgehen Also erstellen wir für jede Auswahl eine Instanz unserer Belohnungsauswahl-Szene, und dann werden wir die Wahl auf diese Szene anwenden, die Auswahl im Grunde genommen auf der Szene festlegen und die Unterbenutzeroberfläche mit allem füllen lassen, was wir brauchen Für die Auswahlmöglichkeiten erstellen wir also eine Prämienauswahl, bei der es sich derzeit um ein Steuerelement handelt, und das entspricht dem Punkt „Instantiieren “ mit der Prämienauswahlszene Dann müssen wir es als untergeordnetes Objekt zu diesem HBox-Container hinzufügen. Fügen Sie also ein Kind der Prämienauswahl hinzu. Und dann sagen wir den Punkt für die Prämienauswahl setHoce und wir geben die Auswahl hinein unsere Prämienauswahl, die Sie hier sehen können , gibt es derzeit kein Skript Diese Funktion existiert nicht, also müssen wir eine Funktion für das Skript erstellen, und das werden wir innerhalb der gepackten Szene tun. Also wollen wir auf Öffnen und Bearbeiten klicken. Also gehen wir in die originalverpackte Szene für dieses spezielle UI-Element über. Bei der Prämienauswahl wollen wir also auf Neues Skript anhängen klicken und es Uilashrewardselection dot gD nennen Erstelle das. Und Seite von hier. Wir geben ihr den Klassennamen Rewards Selection , was es viel einfacher macht ihre Funktionen automatisch auszufüllen Und was uns hier wichtig ist, ist die Wahl des Funktionssatzes, und wir werden eine Auswahl übergeben Und diese Wahl ist ein Gegenstand. Ich erinnere mich. Das wird also nichtig zurückkehren. Und von dort aus müssen wir all diese Elemente auffüllen. Also nehme ich das Rich-Text-Label und benenne es in Namenslabel um Lassen Sie uns den Text direkt in Icon Rect umbenennen. Lassen Sie uns das zweite Rich-Text-Label Descript-Label umbenennen und die Schaltfläche in Auswahlschaltfläche Okay, das wird viel klarer machen , was diese eigentlich bewirken sollen Nachdem wir diese eingerichtet haben, gehen wir erneut zum Skript zur Belohnungsauswahl und holen uns Skript zur Belohnungsauswahl einen Verweis auf jeden von ihnen. Nun, so wie ich es während des gesamten Kurses gemacht habe, und ich denke, selbst in diesem Fall bevorzuge ich es immer noch, eine at-Export-Variable zu machen und wir sagen so etwas wie ein Namenslabel. Ist eine Art von was auch immer es ist, Rich-Text-Label. Okay, und dann können Sie das einfach im Inspektor zuweisen . Wir wissen, wie man das macht, oder? Aber das bedeutet, dass Sie jedes Mal, wenn Sie eine Kopie des Skripts einrichten, die Exportvariablen manuell festlegen müssen. Um also nur eine weitere Option anzuzeigen, können Sie bei on ready var, sagen wir, icon Rec machen und das wird ein Textur-Rect sein. Und dann gibst du ihm ein Öko-Zeichen und gibst ihm den Pfad zu seinem Namen. Wenn ich also die Schaltfläche „Wählen“ sage, wird sie hier automatisch eingefügt. Das können wir auswählen Und ich denke, dafür braucht man am Anfang ein 1-Dollar-Zeichen. Also Dollarzeichen, Randcontainer, Schrägstrich, VBox-Container, Schrägstrich, Schaltfläche „ Wählen Das bedeutet nun, dass es, wenn bereit, automatisch diesen Knotenpfad abruft und ihn dem Text direkt zuweist Wir müssen ihn also nicht manuell im Inspektor einstellen. Hier gibt es jedoch einen großen Fehler, nämlich dass der Pfad zu diesem Element derselbe sein muss Wenn Ihre Auswahltaste also etwas anderes als Auswahltaste heißt , wird sie nicht gefunden Das wäre also ein Grund , warum ich es vorziehen könnte, einen AT-Export zu machen , denn wenn Sie dann zufällig Ihre Knoten hier neu anordnen, solange Sie noch den Referenzsatz haben, wird Ihr Skript dadurch nicht beschädigt Okay, das ist der Grund, warum ich das im Allgemeinen nicht verwende, und ich werde zurück zu at Export var icon Rect wechseln, was ein Textur-Rect sein wird Und dann wollen wir bei Export var description label, was ein Rich-Text-Label ist, hier bei Export var die Schaltfläche wählen. Ist eine Schaltfläche. Okay, und was die Auswahl betrifft, kehren wir für den Moment einfach zurück, damit das Skript gespeichert werden kann, und auf Prämienauswahl klicken. Gehen Sie nach oben rechts und weisen Sie sie jeweils zu. Benennen Sie also Etikett zu Namenslabel, Symbol Rect zu Symbol Rec, Beschreibungslabel zu Beschreibungslabel. Und da wir zwei Rich-Text-Labels haben, es hier wirklich, aussagekräftige Namen wie Namenslabel und Beschreibungslabel zu haben, anstatt beide als Rich-Text-Label und Rich-Text-Label Two aussagekräftige Namen wie Namenslabel und Beschreibungslabel hilft es hier wirklich, aussagekräftige Namen wie Namenslabel und Beschreibungslabel zu haben, anstatt beide als Rich-Text-Label und Rich-Text-Label Two zu bezeichnen Rich-Text-Label und Rich-Text-Label . Ich möchte nur darauf hinweisen. Und dann wählen Sie schließlich die Schaltfläche , die wir der Auswahltaste zuweisen. Jetzt haben wir also einen Verweis auf all diese, und wir können sie ganz einfach mit Informationen aus unserem Artikel füllen . Okay, um jetzt die Auswahl zu regeln, können wir den Punkttext für das Namensschild eingeben, und das entspricht dem Namen des Elements. Im Moment hat unsere Artikelklasse also keinen Namen. Die Waffengegenstands-Unterklasse hat eine Definition, und diese Definition hat einen Namen, aber wir möchten vielleicht einen gegenstandsspezifischen Namen, und ich denke, das wäre der einfachste Ansatz, um einen Gegenstandsnamen in der Gegenstandsklasse zu erstellen Wenn wir also zum Objekt wechseln, können wir bei Export VR den Anzeigenamen angeben , der ein Zeichenkettenname sein wird, und ich werde diesen standardmäßig auf unbenanntes Das ist also eine Art Unterscheidung zwischen dem Gegenstand und der Definition der Waffe, weil ein Gegenstand nicht immer unbedingt eine Waffe ist, sodass wir, zumindest vorerst, zwischen Objekten mit zwei unterschiedlichen Eigenschaften unterscheiden können zumindest vorerst, zwischen Objekten mit zwei unterschiedlichen Eigenschaften Gehen wir nun zurück zur Belohnungsauswahl und wählen den Pchoice-Punktanzeigenamen Lassen Sie mich einen Blick auf die Definition von Speergegenständen werfen, können wir das irgendwie hier sehen Die Definition hier ist also eher so angelegt, dass sie eher eine Definition der Waffe ist, wie sie aufsteigt und welchen Schadenswert sie hat Die Beschreibung des Gegenstands klingt also nach etwas , das separat sein sollte , weil du vielleicht eine Kopie dieses Gegenstands auf der Weltkarte findest und dort etwa stehen würde, Oh, das ist ein Speergegenstand Es verleiht deinem Spieler die Möglichkeit, die Waffe zu haben, aber das ist nicht die Definition der Waffe selbst Also wollen wir diese unterscheiden. Wir können also sagen, dass der Punkttext der Beschreibungsbeschriftung Punktbeschreibung von pchoice entspricht Jetzt benötigen wir für den Artikel eine Beschreibung. Kopieren wir diesen Namen klicken Sie mit der rechten Maustaste auf den Artikel, das Lou-Symbol. Und wir machen das bei Export var, naja, und wir werden bei export var die Beschreibung einfügen, was eine Zeichenfolge ist, und die ist standardmäßig leer. Okay, das ist jetzt bei der Prämienauswahl erledigt. Als Nächstes wollen wir das Icon Rect machen. Wir könnten also sagen, dass die rechte Punkttextur dem pchoic-Punktsymbol entspricht Auch hier unterscheidet sich der Gegenstand von der Waffendefinition Es sollte ein eigenes Symbol haben, das eingestellt werden kann. Also werde ich die Textur des VR-Symbols exportieren. Okay, und wir haben das Textursymbol, sodass wir zur Belohnungsauswahl zurückkehren können. Nun, ich möchte hier vorsichtig sein, denn wenn Sie versuchen, das Pchoict-Symbol zu setzen, obwohl es kein Pchoic-Punktsymbol gibt, erhalten Sie eine Nullreferenz, sobald Sie versuchen, darauf zu eine Nullreferenz, sobald Sie versuchen Sie können also entweder jedes Mal manuell überprüfen, ob das Symbol existiert, oder Sie können es in ein Pchoic Dot Get Icon ändern und diese Sicherheit einfach Aber dann müssen wir diese Funktion zur Artikelklasse hinzufügen. Klicken wir also mit der rechten Maustaste auf das Symbol Lo up und dann erstelle ich hier unten unser Funktions-G-Symbol, das Funktions-G-Symbol, und das wird eine Textur oder nichts zurückgeben. Wenn also Symbol, dann geben wir Symbol zurück, andernfalls geben wir Null zurück. Okay? Ich denke, das ist einfach genug. Diese Methode gibt uns Sicherheit für den Fall, dass sie Null ist Dann geben wir einfach Null zurück anstatt sofort einen Fehler zu haben. Also dann ist der letzte hier etwas kniffliger. Wir haben die Auswahltaste. Wenn die Auswahltaste gedrückt wird, möchten wir die Auswahl mit der Auswahl treffen. Wir möchten also, dass die Schaltfläche über die Auswahl Bescheid weiß. Und dann geben wir das Signal weiter, dass die Taste ganz nach oben gedrückt wird, bis zu unserer Level-Up-Auswahl, sodass wir den Effekt auf den Player anwenden und das Menü schließen können . Hier auf der Ebene der Prämienauswahl wollen wir also das Signal , dass die Taste gedrückt wird, mit der Auswahl verbinden gedrückt wird, mit der Auswahl , die wir genau hier eingeben, der Artikelauswahl, und wir werden das als Signal bei der Prämienauswahl ausgeben, und dann verbindet sich die Level-Up-Auswahl damit, dass die Auswahl weiter oben in der Kette geht und wir können im Grunde auf der obersten Ebene wissen , wann Wir drücken unsere Tasten und wenden dann die Effekte auf unseren Spieler an. Also müssen wir, sagen wir, eine Auswahltaste drücken. Also müssen wir wählen und dann den Punkt Connect drücken, und wir werden das mit einer neuen Funktion auf Reward Pressed verbinden einer neuen Funktion auf Reward Aber wir werden es mit der P-Wahl verknüpfen. Wenn wir es also binden, übergeben wir dem Callback im Grunde einen zusätzlichen Parameter , den diese Funktion normalerweise nicht haben würde Funktionsunterstrich bei gedrückter Belohnung erhält jetzt die P-Auswahl, was ein Element ist, und sie wird als ungültig zurückgegeben, und jetzt können wir diese Auswahl in der Hierarchie weiter nach oben weitergeben Wir können also ein Signal an der Spitze AR platzieren, was bedeutet, dass ein Signal ausgewählt wurde, das dann eine Auswahl des Gegenstands durchgibt Jetzt müssen wir nur noch das so gewählte Signal aussenden. Punkt I MIT, und wir geben die P-Wahl weiter, und jetzt kann es in der Hierarchie nach oben gehen. Also ja, normalerweise hat ein Tastendruck keine Parameter, wenn Sie ihn zurückbekommen. Es wird lediglich gemeldet, dass die Taste gedrückt wurde. Aber wenn wir bind aufrufen, fügen wir diesen zusätzlichen Parameter , wann immer dieser gedrückt wird. Jetzt kann uns unsere Schaltfläche also die sehr wichtige Information darüber geben die sehr wichtige Information darüber welche Wahl tatsächlich getroffen wurde. Technisch gesehen könnten wir hier auch die lokale Auswahlvariable setzen und dann drücken, wir könnten einfach die lokale Auswahl für die Artikelauswahl übergeben . Wenn ich das also bei der Auswahl festlegen würde, würde das auch funktionieren. Zwei Möglichkeiten, dasselbe zu tun, aber jetzt kennen Sie eine viel coolere Art, Binding zu verwenden, sodass Sie tatsächlich zusätzliche Parameter hinzufügen können. Das erfordert auch nicht, dass die Prämienauswahl diese Wahl beibehält, obwohl das durchaus möglich wäre und das hier auch nicht problematisch wäre. Okay, gehen wir also in der Hierarchie weiter nach oben. Nun, in unserer Lavop-Auswahl, die wir uns ansehen wollen. Wir haben den Rewards-Box-Container. hier aus erstellen wir also Von hier aus erstellen wir also die Prämienauswahl Also hier muss ich das Signal wieder nach oben ausbreiten. Nehmen wir an, das Signal wurde ausgewählt, das das Auswahlelement einfach so übergeben wird Wann immer wir unser Prämienauswahlmenü auffüllen und jetzt, wo wir einen Klassennamen haben, können und sollten wir diesen in „Prämienauswahl“ ändern Und wir werden das mit „Keine ausgewählten Prämien“ verbinden . Also hier unten erstellen wir diese Rückruffunktion, erstellen wir diese Rückruffunktion die bei den ausgewählten Prämien unterstrichen Wir erhalten die Option P Choice, das ist der Artikel, den wir als ungültig zurücksenden, und wir werden das einfach nach oben weitergeben. Also haben wir Punkt EMT ausgewählt. Wir werden mit der P-Wahl emittieren. Das geht jetzt in der Hierarchie weiter nach oben. Das ist also auf der Ebene unserer Prämienbox. Nun zur Level-Up-Auswahl müssen wir uns nur noch mit unserem Prämienbox-Container verbinden. Lassen Sie uns also unseren Prämiencontainer exportieren , der ein Prämienbox-Container ist. Und wenn wir bereit sind, wollen wir eine Verbindung zu seinem Signal herstellen. Punkt im Prämiencontainer ausgewählt Punkt verbinden bei Prämie ausgewählt. Funktionsunterstrich bei Prämie, ausgewählt. Lassen Sie mich das ein bisschen vergrößern. Und wir entscheiden uns für P, was der Artikel ist, und geben sie als ungültig zurück. Also werden wir vorerst bestehen und müssen den Effekt auf den Spieler anwenden und das Menü schließen. Darauf kommen wir gleich zurück. Wir hatten also unsere Startauswahlmethode. Wir wollen im Grunde Container der Prämienbox zurücksetzen. Wir möchten, dass er gefüllt wird, aber wir möchten auch, dass er alle vorhandenen Gegenstände löscht In der Prämienbox nehme ich also die Option Auffüllen und mache diesen Unterstrich und generiere mache diesen Unterstrich und Ich mache auch einen Unterstrich für privat, damit wir das nicht versehentlich von unserer Haupt-Benutzeroberfläche aus aufrufen Hier müssen wir also unterstreichen, weil wir Unterstriche machen, um Auswahlmöglichkeiten zu generieren Lassen Sie uns nun die Funktion erstellen wir tatsächlich aufrufen werden Also Optionen für die Einrichtung der Funktion. Ja. Okay, das ergibt Sinn. Und wir werden unsere P-Optionen übergeben, das heißt Leveling-Optionen, und wir werden P-Ziel übergeben, das ist unser zweiter Knoten D. Natürlich werden wir mit diesen Optionen und unserem Ziel füllen diesen Optionen und unserem Aber vorher möchte ich auch dieses Menü löschen. Also, ich muss alle untergeordneten Felder entweder entfernen , bevor ich sie auffülle, oder ich muss sicherstellen, dass meine Datei die bestehende Benutzeroberfläche wiederverwendet und sie dann mit den neuen Optionen aktualisiert Da wir hier also nur ein paar Auswahlmöglichkeiten haben werden , wäre es etwas übertrieben, sich zu viele Gedanken über die Wiederverwendung aller möglichen Sub-UI-Komponenten zu machen über die Wiederverwendung aller Die einfachere kurzfristige Option wäre also definitiv, es einfach zu löschen, was für Kinder und Kinder gelten wird Wir werden Child Punkt Q einfach kostenlos nennen. jetzt hier oben abräumen, Wir können jetzt hier oben abräumen, bevor wir auffüllen. Oh, und wir müssen einen Rückgabetyp für die Einrichtungsoptionen fertigstellen einen Rückgabetyp für die Einrichtungsoptionen Also kehren wir als ungültig zurück. Okay. Ja. Also, setu Choices, wir können das in unserem Levelauswahl-Skript aufrufen in unserem Levelauswahl-Skript Also starte die Auswahl, wir machen Belohnungen Container Punkt Startauswahl, und das wird in den Optionen und dem Ziel, also dem Kontext-Spieler, übergeben . Und das ist der falsche Name für die Methode. Es war eigentlich Setup Choices. Okay, also beginnen wir mit der Auswahl. Wir haben die Auswahlmöglichkeiten festgelegt. Wir warten, bis der Spieler im Grunde eine Wahl getroffen hat, und dann erhalten wir unseren Rückruf An diesem Punkt wollen wir also das Menü schließen. Wir könnten hier also Prämiencontainer Punkt CE sagen. Und ich habe das zu einer privaten Methode gemacht. Also werde ich im Prämienfeld einfach den Unterstrich hier und hier entfernen Okay, jetzt wird es intern aufgerufen, aber auch von anderen Skripten aus Wenn Sie also eine Methode öffentlich machen müssen, können Sie das tun. Technisch gesehen verhindert GD Script auch hier nicht, dass Sie eine Methode aufrufen , die einen Unterstrich enthält Es ist einfach die beste Methode, um die Absicht anzugeben. Also zurück in der Auswahlebene der ausgewählten Prämien, wollen wir den Gegenstandseffekt auf den Spieler anwenden. Wir sagen p, Auswahlpunkt „ Versuch“, auf den Spieler anzuwenden. Das wird also der Kontext-Punkt-Spieler sein. Dann leeren wir den Container und schließen das Menü. Okay, lass uns sehen. Wir verstecken uns einfach hier. Und das könnte so ziemlich alles sein, was wir brauchen. Also ein bisschen Aufräumen hier. Gehen wir zum Rewards-Box-Container und nun, lassen Sie mich die beiden D-Ansichten zeigen. Hier können Sie sehen, dass wir diese drei Boxen hier haben. Es ist okay, sie hier im Blick solange wir sie freigeben, bevor wir etwas verwenden. Wenn wir also zum Rewards-Box-Container auf Bereit gehen, werde ich Clear anrufen wollen. Also, Funktion Underscore bereit. Lassen Sie uns diese UI-Elemente als klar bezeichnen. bedeutet, dass diese entfernt und jedes Mal neu erstellt werden , wenn der Prämienbox-Container erscheint. Wir möchten, dass es so optimal wie möglich ist. Es ist besser, jede UI-Komponente wiederzuverwenden , als sie aus einer Instanz neu erstellen zu müssen Aber bei so etwas Einfachem wirst du es nur einmal alle, ich weiß nicht, 30 Sekunden Gameplay zeigen , das sollte fast keine Wirkung haben und es ist nicht wirklich eine große Okay, wir haben hier immer noch die Speerauswahl. Wenn wir also tatsächlich versuchen, ein höheres Level zu erreichen, sollten wir eine Auswahl sehen Es ist definitiv an der Zeit , es zu testen und zu sehen, ob wir es tatsächlich schaffen , dass es überhaupt auftaucht und funktioniert. Also lass uns auf Play klicken. Und wir werden sehen, wie es funktioniert. Okay, es sieht also so aus, als hätte ich vergessen, den Prämiencontainer hier in der Level-Up-Auswahl einzustellen . Gehen wir also zur Level-Up-Auswahl. Klicke darauf. Und in der Hierarchie müssen wir dem Prämiencontainer den Prämienbox-Container zuweisen . Das ist also wirklich die Schwäche von Exporteigenschaften, oder? Wenn Sie vergessen, es einzustellen, gibt es dort wirklich keinen Hinweis, außer dass Sie irgendwann im Code auf Fehler stoßen werden. Wir brauchen dort also keine Bestätigung, weil die Verbindung mit dem Signal bereits einen Fehler auslösen wird , sobald sie fehlschlägt. Lass uns schließen und wir laufen wieder. Okay, lass uns unseren Artikel abholen. Bum, wir haben nur eine Option zur Auswahl. Deshalb haben wir den Artikel hier benannt. Ich glaube, ich habe einfach kein Symbol oder keine Beschreibung festgelegt, aber Sie können sehen, dass die Methode Get icon, da wir den Nullfall behandelt haben, uns keinen Fehler geben wird. Wenn wir dagegen direkt auf die Eigenschaft „Punktsymbol“ verweisen würden, weil sie Null ist, würde hier ein Fehler ausgegeben. Wenn wir auf Auswählen klicken, gilt das dann für den Spieler? Lassen Sie uns das herausfinden. Es sollte das Menü schließen. Das tut es, aber ich habe vergessen , das Spiel fortzusetzen. Also müssen wir wieder reingehen und sicherstellen, dass, nachdem wir das Menü ausgeblendet haben oder vielleicht sogar bevor wir das Menü verstecken, wir sagen, dass Geth Dot paused gleich False ist Lass uns das speichern und noch einmal laufen. Also kommen wir her, wir treffen unsere Auswahl, wählen wir den Artikel aus. Bum, es ist schon da. Nun, es schien zu funktionieren, aber der eigentliche Test wäre, wenn wir hier oben eine Anzeige für die Stufen unserer Waffengegenstände hätten eine Anzeige für die Stufen unserer Waffengegenstände , daran werden wir gleich arbeiten. Für den Moment wäre es am besten, auf „nah“ zu klicken und dann zu unserem Speer-Gegenstand zu gehen Ich werde Stufe zwei erreichen und wir werden die Abklingzeit auf 0,1 ändern, weil das sehr offensichtlich sein wird, weil das sehr offensichtlich sein wird, wenn wir auf diese Stufe aufrüsten Drücken wir also erneut auf Play. Ich hole unseren Gegenstand ab, drücke auf Auswählen und wir sehen, dass die Abklingzeit nicht aktualisiert Also stimmt etwas mit dem Code nicht. Also ich denke, das Problem wird tatsächlich in der Waffe selbst liegen. Ich werde hier nachsehen , ob wir das Level tatsächlich höher zuweisen, also den Breakpoint Und lassen Sie mich hier auf Ready sehen, wir haben die Cooldown-Definition für den Aber Sie können hier sehen, dass wir hier die Zeit für den Timer einstellen. Aber ich wette, wir setzen den Timer hier unten nicht auf einen neuen Wert zurück. Also ja, das ist ein sehr klares Problem. Wir müssen den Timer-Punkt sagen. Sagen wir einfach, Start wird der neue Wert sein. Also müssen wir die Sache mit der G-Abklingzeit machen. Wir brauchen den Definitionspunkt Abklingzeit eines aktuellen Levels abrufen Also Definition, Punkt Holen Sie sich die Abklingzeit unseres Levels. Das bedeutet, dass wir jedes Mal, wenn wir den Timer zurücksetzen, die aktuelle Abklingzeit unseres Levels erhalten Wenn wir also sagen, wir haben ein Projektil nach der Hälfte abgefeuert, ändern wir unsere Abklingzeit, weil unser Level gestiegen Das heißt, wenn das Projektil das nächste Mal nach dem Wurf abgefeuert wird, setzen wir den Timer mit Jetzt wird es also die Eigenschaft Stufe zwei verwenden. Und ich glaube, ich brauche diesen Breakpoint nicht einmal. Ich bin mir ziemlich sicher , dass das das Problem ist. Lass uns weitermachen und auf Play klicken. Ich nehme unsere Waffe, drücke auf Auswählen und los geht's. Wir haben im Grunde einen Maschinengewehrspeer weil unser Speer Level zwei erreicht hat, und das wird völlig bahnbrechend sein Ich würde also empfehlen, dass wir am Ende einfach die Abkühlzeit für unser Speerprojektil wieder auf 0,9 ändern unser Speerprojektil wieder , jetzt wo wir wissen, dass es funktioniert, und damit ist dieses Video abgeschlossen 49. P48 Waffenlevel-Statistiken auf Projektil-Spawning und -Instanzen anwenden: Es wurde gezeigt, dass wir unsere Waffen durch die Auswahl der Belohnungen beim Levelaufstieg aufrüsten können , aber wir müssen sicherstellen, dass wir beim aber wir müssen sicherstellen, dass wir beim Leveln unserer Waffen alle richtigen Werte für die Waffe verwenden, nicht nur die Reduzierung der Abklingzeit Gehen wir also zum Drehbuch für Projektil über. Und wir werden hier drinnen sehen, dass wir die Statistiken des Waffenlevels noch nicht verwenden Wir verwenden eine eingebaute Geschwindigkeit, und der endgültige Schaden wird nicht durch irgendwelche Berechnungen verursacht. Es wird nur 100 als lokale Variable übergeben. Wenn Sie also bei der Definition der Waffenebene bemerkt haben , dass diese Statistiken noch nicht verwendet werden, nun ja, das ist der Grund Wenn wir also das Projektil erstellen, müssen wir auch das Waffenlevel angeben Wir könnten dafür eine völlig separate Funktion haben, aber ich denke, es könnte praktischer sein , einfach die Statistiken der Waffenstufe in die Startfunktion zu Statistiken der Waffenstufe in die Startfunktion Die Startfunktion dient also nicht nur dazu, die Richtung, sondern auch die projektilspezifischen Statistiken festzulegen, sondern der Start dient auch dazu, die abschussspezifischen Statistiken für dieses Projektil auf der Grundlage des aktuellen Waffenstands festzulegen die abschussspezifischen Statistiken für dieses Projektil auf der Grundlage des aktuellen Waffenstands Als zusätzlichen Perimeter wollen wir also das P-Level, das ist ein Waffenlevel , durchgehen ist ein Waffenlevel , Das sind also alle Statistiken, die wir hier reinbringen müssen. Und anstatt hier an der Spitze eine Geschwindigkeit zu haben, werde ich sie entfernen und wir sagen stattdessen Var Level des Typs Waffenlevel, und von dort werden wir alle Statistiken abrufen. Wenn wir also den physikalischen Prozess machen und der Geschwindigkeit multiplizieren müssen, machen wir Level. Punktgeschwindigkeit. Okay. Das fügen wir hinzu. Und jetzt beim Start müssen wir das Level gleich dem P-Level setzen. Okay, so holen wir uns die Statistiken und dann müssen wir nur noch unsere Aufrufe aktualisieren, bis sie veröffentlicht werden. Aber hier gibt es noch andere Informationen, die relevant sind. Also, zuerst, wenn die Trefferbox auf eine Rt-Box trifft, müssen wir den Schaden aus den Levelstatistiken ziehen. Hier brauchen wir also eine zufällige Schadensberechnung zwischen dem Schaden unserer Männer für die Waffe und unserem MAX-Schaden. Also entferne ich diese Zeile und wir sagen, dass der Var-Schaden eine Ganzzahl sein wird, und das entspricht einem zufälligen ganzzahligen Bereich zwischen dem minimalen Schaden und dem maximalen Schaden. Also Levelpunkt Minimaler Schaden und dann Levelpunkt Maximaler Schaden , der die Zufälligkeit hier berücksichtigt. Also dann haben wir unseren letzten Schaden. Ich sage einfach, das entspricht dem Schaden im Moment, und dann geben wir unseren endgültigen Schaden an die Hurt-Box weiter. Jetzt haben wir also auch zufälligen Schaden, der auf dem Level und der Geschwindigkeit basiert , die durch das Level festgelegt werden. Wenn wir uns jetzt also ein Waffen-Zwei-D-Skript ansehen, erhalten wir eine Fehlermeldung für Projektilpunktstart, weil wir das aktuelle Level von Waffe zwei D übergeben müssen, das praktischerweise hier auf Waffe zwei D eingerichtet ist . Also sagen wir einfach Koma, Waffenlevel hier, und das sendet es einfach von der Waffenebene zur Projektilinstanz. Wir können diese Änderungen also testen, indem wir das Spiel jetzt ausführen. Also werden wir unseren oder den Feind suchen , wo immer er spawnen möchte. Okay, da ist einer. Und du wirst sehen, dass wir zufälligen Schaden zwischen unseren Männern und MAX haben. Derzeit kannst du sehen, dass es immer noch den Feind durchquert, da ist unser Level gestiegen. Theoretisch sollte das also sowohl beim Abkühlen als auch beim Schaden etwas schneller gehen . Sie können die Schäden dort oben sehen. Also, zum größten Teil scheint das zu funktionieren. Aber es gibt noch ein paar Dinge, die wir anpassen müssen, zum Beispiel, wie viele Treffer es machen kann bevor das Projektil tatsächlich gelöscht wird Treffer mit der Hipbox wollen wir also die Anzahl der Treffer erhöhen , die wir gemacht haben, und wenn die Treffer unseren MAXIMALEN Treffern oder mehr entsprechen, dann wollen wir unser Projektil freilassen Also hier oben haben wir einen Var-Treffer, und das wird eine Ganzzahl sein Es wird bei Null beginnen. Und jedes Mal, wenn wir Erfolg hatten. Ich gehe hier zum Anfang und sage, Var Hit gleich P Hurt Box Dot Tri Damage Und dann sagen wir, ich treffe, dann ist Treffer plus gleich eins. Und dann können wir auch sagen, wenn Treffer größer oder gleich der maximalen Trefferzahl sind, dann schießen wir mit unserem Projektil los Das kann jetzt also freigegeben werden, wenn der Timer abläuft im Grunde in der Spielszene erhalten bleibt, was wir übrigens auch hier durch die Variable ersetzen müssen auch Oder wenn der Treffer seine maximale Trefferzahl erreicht, dann wird er auch sofort Also hier oben wollen wir auch sagen, dass wir, wenn wir den Timer erstellen, die Eigenschaft des Levels übernehmen werden. Also sagen wir Level und ich glaube nicht, dass wir es schon festgelegt haben. Also brauchen wir etwa eine Dauer. Lassen Sie uns eine Dauerstatistik für unsere Waffe erstellen. Okay, also Levelpunkt-Dauer. Das heißt, wir müssen in die Waffenebene springen. Suchen Sie nach dem Symbol und lassen Sie uns die Dauer hier unten erstellen. Wir sagen beim Export, dass die Dauer der Variablen standardmäßig eine Gleitkommazahl ist, die, sagen wir, 5 Sekunden entspricht. Das ist also die maximale Zeit, für die das Projektil in der Spielwelt verbleiben kann , bevor es entfernt wird, vorausgesetzt, es wird nicht durch etwas anderes wie Treffer oder Überschreitung der maximalen Trefferzahl Okay, lass uns weitermachen und noch einmal auf Play drücken . Also drücke ich auf Play. Da ist unser Speerprojektil, wir werden warten, bis ein paar Feinde erscheinen wir werden warten, bis ein paar Feinde erscheinen. Okay? Also haben wir das. Und Sie können sehen, was sehr wichtig ist: Sobald ein Typ getroffen wird, entfernt sich der Speer von selbst Das ist also eine große Veränderung. Und wenn wir auf Level zwei aufsteigen, sollte es immer noch dasselbe sein, aber unser Schaden steigt. Und lassen Sie uns versuchen, dieses Projektil zu beobachten, und es wird nach 5 Sekunden verschwinden. Also 45. Okay, da kannst du sehen, wie sich die Projektile von selbst aus der Das ist sehr wichtig, da sie sonst möglicherweise nie entfernt werden und sie würden einfach grundlos Systemressourcen beanspruchen Systemressourcen beanspruchen Deshalb möchten wir, dass diese irgendwann automatisch entfernt werden. Okay, jetzt gibt es auch ein paar andere Eigenschaften unseres Waffenlevels, die Spawnverzögerung, den Spawn-Offset und die Projektile Also müssen wir sicherstellen , dass wir in unserer Waffe bis D tatsächlich die zusätzlichen Projektile erzeugen, tatsächlich die zusätzlichen Projektile erzeugen wir sie relativ zum Offset spawnen und dass alle zusätzlichen Projektile eine Verzögerung haben, nachdem das Und aufgrund der Verzögerung der Spannweite alle Projektile nach dem ersten eine Verzögerung, haben alle Projektile nach dem ersten eine Verzögerung, bevor sie erscheinen Okay, also lasst uns zu den Waffen auf D übergehen. Also jedes Mal, wenn wir werfen, müssen die Projektile spawnen Also brauchen wir vier Schleifen, sagen wir, vier Indizes im Bereich Null bis zur Waffenebene Punktiert die Projektile und dann erhöhen wir die Zahl um eins. Also wiederholen wir das einfach ein paar Mal. Nach jedem Projektilstart warten wir den Kit Tree Create Timer und wir benötigen den Punkt Span Delay auf Waffenebene Okay. Und dann warten wir auf die Auszeit. Nach dem ersten Loop warten wir also auf das Timeout der kurzen Span Delay bevor wir unsere zweite Instanz eines Projektils pro Einsatz erstellen , und wir erstellen Projektile auf der Grundlage der Anzahl der Projektile , die uns die Waffenstufe erlaubt Später, wenn wir wollten, könnten wir das auch, sagen wir, mit einem Bonus vom Spieler kombinieren sagen wir, mit einem Bonus vom Wenn der Spieler also mehr als ein Projektil für alle Waffen hat , dann haben wir eine Funktion, um diese beiden Zahlen zu addieren , um die Gesamtzahl der Projektile für diese Waffe zu erhalten die Gesamtzahl der Projektile für Schließlich müssen wir also einen zufälligen Offset generieren, der auf der Offset-Entfernung unseres Waffenlevels basiert der auf der Offset-Entfernung unseres Waffenlevels Für unseren Offset wird er also gleich einem Vektor zwei sein, und dann werden wir einen zufälligen F-Bereich für X und Y erstellen. Also zufälliger F-Bereich, negativ 1,0 bis 1,0, und dann zufälliger F-Bereich, negativ 1,0 bis 1,0 Und das multiplizieren wir mit dem Waffenlevel. Punktversatz. Das gibt uns also einen zufälligen Wert zwischen dem negativen maximalen Abstand auf dem Span-Offset und dann dem positiven maximalen Offset hier für das X und den gleichen Wert für das Y und das positive Y. Das ergibt also technisch gesehen eine quadratische Form, weil X und Y sich nicht gegenseitig beeinflussen, sodass es sowohl bei X als auch bei Y negativ 1,0 oder positiv 1,0 sein kann . Ich denke, das ist in Ordnung Wir versuchen nur, einen einfachen Offset zu haben. Es ist nicht wirklich wichtig, ob es ein Quadrat oder ein Kreis ist , es sei denn, Sie möchten, dass es wichtig ist. Also gehe ich hier runter zum Projektil und wir werden den Offset hinzufügen Okay. Und dann wird es so sein, dass jedes Mal, wenn wir das Projektil spawnen, es einen gewissen Versatz hat, wenn wir das an der Waffe haben Wenn ich mir also den Speer-Gegenstand ansehe, können wir sehen, dass wir hier keinen Spannweitenversatz haben Also sollten wir vielleicht einen setzen. Lass uns sehen. Was wäre der maximale Pixelversatz, den ich machen möchte? Vielleicht fünf. Und dann machen wir einfach fünf für alle. Also öffne jedes Waffenlevel und wir machen fünf. Also das kann positiv oder minus fünf oder irgendwas dazwischen sein, sowohl für X als auch für Y. Und dann werde ich rennen und wir werden sehen, wie das läuft Also pass auf, wo die Speere spawnen. Und du kannst sehen, dass sie ein bisschen voneinander entfernt sind, oder? Es ist also nicht jedes Mal genau an derselben Position. Und macht es dann auch etwas interessanter für eine gewisse Varianz. Okay, jetzt möchte ich die Waffe auf Stufe eins testen und wir werden sie auf drei Projektile bringen, und ich werde diese Bondlay auf 0,05 Sekunden erhöhen, Also lasst uns das spielen und laufen lassen, und wir sollten eine Kette von drei Projektilen bekommen Eins, zwei, drei, eins, zwei, drei, eins, zwei, drei. Sie können hier also eins, zwei, drei sehen. Oh, nun, ein kleines Problem hier. Sie können sehen, dass, wenn ich nach dem ersten Projektilstart rotiere, ich auch die anderen Projektile rotiere, wenn sie instanziert ich auch die anderen Projektile werden Okay, für diese Rotation Rads möchte ich das außerhalb der vier Kreisläufe berechnen Ich will es nur einmal machen. Sobald das erste Projektil abgefeuert ist, sollten alle anderen in diese Richtung gerichtet sein Also lass uns weitermachen und auf Play klicken. Und wenn ich mich jetzt bewege, aber ich rotiere, solltest du sehen, dass alle drei immer in dieselbe Richtung gehen, was normalerweise das ist, was du willst, denke ich. Lassen Sie uns also zuerst die zusätzlichen Projektile entfernen . Wir können den benutzerdefinierten Spawn-Offset für all diese beibehalten benutzerdefinierten Spawn-Offset für all diese Wenn du willst, könnten wir sogar festlegen dass eine Standardwaffe einen Span-Offset hat, aber das liegt ganz bei dir, ob du zurückgehen und diese Standardeinstellungen für die Waffenstufen anpassen möchtest zurückgehen und diese Standardeinstellungen für die Waffenstufen anpassen Lassen Sie mich das Waffenlevel-Skript noch einmal durchsehen und sehen, ob wir alles geklärt haben Also minimaler Schaden, maximaler Schaden, Geschwindigkeit, Abkühlzeit von Projektilen, maximale Treffer, Offset, Verzögerung und Dauer Ja, wir verwenden alle Variablen unseres Waffenlevels, und das gibt uns eine Menge Anpassungsmöglichkeiten für alle Waffen, die wir erstellen möchten 50. P49 Bau einer rotierenden Scythe-Waffe: Da wir ein funktionierendes Level-Up-System haben, wollen wir es nehmen und zusätzliche Optionen hinzufügen Jetzt wäre also der perfekte Zeitpunkt , um unserem Spiel eine zweite Waffe hinzuzufügen. Das wird also dem ersten ähnlich sein. Wir fügen eine Sense hinzu, und die Sense wird sich auf dem Bildschirm drehen können, anstatt sich wie der Speer geradeaus Wenn wir also das Speerpunkt-TSC und die Waffen öffnen, können Sie sehen, dass es bereits die meisten Komponenten enthält , die wir für unseren Syth benötigen werden Also werde ich einfach von dieser Szene unten rechts duplizieren , indem ich mit der rechten Maustaste auf die Szene klicke und duplizieren gehe Also lass uns Syth hier Punkt TSCN eintragen. Okay, jetzt kann ich Syth im Projekt suchen und es öffnen Lass uns die Mitte vergrößern. Einige der offensichtlichen Dinge wollen wir zuerst ändern, den Namen des Projektils, also nennen wir es Syth Und dann sollte das Sprite aus der Atlas-Textur für das Sensensprite ausgewählt werden aus der Atlas-Textur für das Sensensprite ausgewählt Also klicke ich hier, erweitere die Seite und wir werden dieselben hölzernen Sprites verwenden Also, wenn ich mich recht erinnere, gibt es hier einen guten Syth, den wir gebrauchen können. Also wählen wir das aus und klicken auf Schließen. Jetzt können Sie sehen, dass das Trefferfeld keinen Sinn mehr macht, weil es hier diese Kurve hat. Also wollen wir auf unsere Kollisionsform klicken, und ich werde hier rüber und sie dann nach rechts erweitern, etwa so, oder es könnte sogar eher zu einem rechteckigen Quadrat werden, wenn ich die gesamte Kante der Klinge abdecken möchte. Also lass uns das machen. Also, wenn wir dieses Projektil instanzieren, funktioniert es immer noch fast genauso wie der Speer, wo es nur vorwärts geht Wir wollten uns also eigentlich um den Mittelpunkt drehen bedeutet also, dass wir einen Offset benötigen, und wir müssen diesen Offset kreisförmig drehen , dann erhalten wir unsere rotierende Animation. Also klicken wir mit der rechten Maustaste auf die Seite. Ich füge einen neuen Knoten zwei D hinzu, und dann wird dieser Knoten zwei D dem Sprite und der Hit-Box übergeordnet sein dem Sprite und der Hit-Box übergeordnet Also lass uns die hier drunter verschieben. Und dann werde ich das in Rotator Two D umbenennen, und lassen Sie uns mit der rechten Maustaste klicken und ein Skript daran anhängen Also Waffen Rotator Two D ist in Ordnung. Lassen Sie uns das erstellen, geben wir ihm den Klassennamen Rotator Two D, und dann wollen wir hier ein paar Eigenschaften eingeben Geben wir ihm also eine Geschwindigkeit für diesen Rotatorknoten. Denken Sie also daran, dass dieser Rotator dem Basisobjekt untergeordnet ist . Das Basisobjekt wird also seine eigene Bewegung haben, und dann wird dieses Unterobjekt die Rotation speziell steuern Sie bewegen sich also beide gleichzeitig, aber sie sind unabhängig voneinander. Also bei der Export-Var-Geschwindigkeit , einem Vektor zwei, habe ich diese Standardeinstellung auf zehn Pixel nach rechts und Null auf der Y-Achse. Das wird sich also auf die Bewegung auf dem Bildschirm auswirken. Wir möchten aber auch, dass sich der Knoten auch physisch dreht, sodass es so aussieht, als würde sich unsere Site drehen. Bei der Export-Vari-Rotationsgeschwindigkeit in Grad ist das also ein Flow, ich setze ihn standardmäßig auf 360, was in diesem Fall eine Umdrehung pro Sekunde bedeuten würde. Und dann müssen wir es nur noch über den Prozess oder den physikalischen Prozess aktualisieren . Ich führe einen physikalischen Prozess durch , damit er mit anderen Bewegungen im Spiel konsistent ist. Nehmen wir an, unsere Menge entspricht dem Grad der Strahlkraft Also werden wir diese Rotationsgeschwindigkeit in Grad in einen Strahlungswert umrechnen einen Strahlungswert Wir benötigen also die Rotationsgeschwindigkeit in Grad multipliziert mit dem Delta, um den Grad der Rotation seit der letzten Frame-Aktualisierung zu ermitteln, und dann werden wir die Rotation um diesen Betrag in Wir können diesen Wert also sogar RDs nennen , wenn wir uns darüber im Klaren sein wollen , dass das ein Maß an Strahlkraft ist , und ich mache daraus auch einen Float, nur um ihm so viel Klarheit wie möglich zu geben Okay, dann müssen wir den Knoten physisch bewegen, und das hängt von unserer Geschwindigkeit hier oben ab. Also werde ich sagen, dass unsere Bewegung gleich Geschwindigkeit mal Delta sein wird . Und dann rufen wir Translate für den Betrag der Bewegung auf, und das ist im Grunde unser Rotator-Skript Wenn Sie also Werte anpassen müssen, haben Sie den Inspektor hier, um sie zuzuweisen. Also wollen wir jetzt eine Waffe mit zwei D entwickeln , die unser Visier instanzieren kann. Also lasst uns nach der Speerwaffe suchen , falls wir sie überhaupt im Projekt gespeichert Also lasst uns jetzt nach der Speerwaffe suchen. Wir werden das öffnen. Wir werden hier einen kleinen Blick darauf werfen. Das ist also der 2-D-Node mit einem AudioStream-Player, der den Slash-Sound abspielt, wenn wir eine Waffe instanzieren Also möchte ich das duplizieren und dann eine Syth-Definition für unsere Waffe erstellen eine Syth-Definition für Also lasst uns die Speerwaffenszene als Syth-Waffe duplizieren. Also lasst uns wieder nach Syth suchen. Doppelklicken Sie auf Syth öffnen benennen Sie die Speerwaffe in Syth-Waffe um Und dann drüben auf der rechten Seite müssen wir eine neue Definition erstellen Also werde ich hier reinzoomen, neue Waffendefinition, und das wird Syth sein Unser Symbol können wir einfach vom eigentlichen Syth-Projektil kopieren vom eigentlichen Syth-Projektil Also gehe ich zur Syth-Szene und dann klicken wir auf das Sprite und klicken mit der rechten Maustaste auf die Textur, kopieren sie, gehen zur Sensenwaffe über und fügen sie dann mit der rechten Maustaste kopieren sie, gehen zur Sensenwaffe über und fügen sie auf Einfügen in das Symbol Okay, jetzt müssen wir hier einige Waffenstufen definieren. Also lass uns unser Set zusammenstellen. Wir beginnen mit Waffenstufe eins, neuer Waffenstufe. Also, wie wollen wir, dass unsere Sense funktioniert? Vielleicht bewegt sich die Sense langsamer als ein normales Projektil. Vielleicht dauert die Abkühlung länger, also könnten wir sagen, 1,5. Bevor Max zuschlägt, setze ich es auf fünf, damit die Sense viele Ziele treffen kann, bevor sie versaut. Wenn es um Schaden geht, erhöhen wir es auch auf 20 bis 30. Und Projektile eins. Okay, lassen Sie uns das Schlüsselwertpaar hinzufügen und dann machen wir Level zwei mit einer neuen Waffenstufe Erweitere Waffenstufe eins, damit ich vergleichen kann. Und dann füge ich, sagen wir, 30 bis 40 Schaden zu, Geschwindigkeit 55, Abklingzeit 1,4. Max. Treffer von sechs, und ich füge das Schlüsselwertpaar hinzu. Lass uns Level drei machen, so weiter und so fort, auch immer du die Zahlen machen willst. Okay, hier sind die Zahlen, die ich bei Waffenstufe drei verwendet habe. Du kannst pausieren, wenn du kopieren willst. Hier haben wir Waffenstufe vier, Waffenstufe fünf. Und Waffenstufe sechs. Und ich denke, das sollte für den Moment reichen. Okay, also wenn ich mich recht erinnere, habe ich in der Waffendefinition noch nicht die Möglichkeit gesetzt der Waffendefinition noch nicht die Möglichkeit , deine vollgepackte Szene auszuwählen. In der Waffendefinition möchte ich also eine Option mit dem Namen G hinzufügen. Vorerst verwenden wir standardmäßig eine Exportvariable. Also sage ich, VR-Szene exportieren, und das wird eine vollgepackte Szene sein. Okay, und dann wollen wir, anstatt dass Getsn den Speer lädt, zur Szene zurückkehren Da wir also die Methode „Gesehen“ verwenden , haben wir die Möglichkeit, später einzusteigen haben wir die Möglichkeit und zu ändern, ob es zusätzliche Szenen gibt , die wir weitergeben möchten, und nicht die Standardeinstellung. Aber das sollte vorerst gut sein, aber wir brauchen im Moment nicht wirklich eine zweite Szene. Okay, jetzt müssen wir nur noch sicherstellen , dass wir in der Sensendefinition die Sense schnell laden Und dann in der Speer-Definition, also suche nach Speer-Definition . Du doppelklickst Und dann müssen wir schnell die Speerszene laden. Okay, und das sollte dort gut sein. Ich denke, das Letzte , was wir für unseren Syth brauchen , ist der Syth-Artikel. Jetzt wollen wir den Spear-Gegenstand in unserem Projekt finden, duplizieren und einen Syth-Gegenstand mit Punkt TRS erstellen Suchen Sie also nach einem Syth-Artikel. Und dem Syth-Gegenstand werden wir natürlich die Definition der Sense zuweisen natürlich die Definition der Sense Damit unsere Websites als Waffe für unseren Spieler hinzugefügt werden können, benötigen wir einen Verweis auf die Waffe zwei D. Den können wir Ausrüstung unseres Spielers hinzufügen , weil sie noch nicht auf dem Spieler vorhanden ist, also muss sie Okay, um unseren Verweis auf die Waffenszene hinzuzufügen, wir können die Paktszene nicht wirklich verwenden , denn wenn wir das tun, wird sie einen zyklischen Bezug haben weil der Waffen-TD bereits auf diese Waffendefinitionsressource verweist. In diesem Fall müssen wir also, um das zu umgehen, eine Exportdatei erstellen, und diese wird in Anführungszeichen stehen, Sternpunkt TSCN, was bedeutet, dass wir sie nach allem filtern können , was den Erweiterungspunkt TSCN am Ende hat. Und wir sagen var weapon two D path, und das wird eine Zeichenfolge sein Das ist der Pfad zur Waffenszene zwei Waffen-Loadouts wie der Spieler hinzuzufügen Okay, wenn wir uns jetzt unsere Speerdefinition ansehen, können wir der Waffe zwei D-Wege zuweisen, was in Waffen sein wird, und dann haben wir hier Speerwaffen Also das ist es, was wir brauchen. Und dann müssen wir dasselbe mit Sense Also suche Sense. Und es sieht so aus, als hätte ich es Sensenwaffe genannt, aber das sollte die Seitendefinition hier unten sein. TRES ist die Definition. Die Szene ist die Waffe vor Ort. Okay, also doppelklicken Sie auf die Seitendefinition und weisen Sie ihr dann den Pfad zu. Sie können also einfach per Drag-and-Drop von hier nach dort ziehen und schon wird es zugewiesen. Ausrüstung jetzt also Wenn die Ausrüstung jetzt also noch nicht über die Waffe verfügt, müssen wir die neue Waffe auf Waffenstufe eins zur Ausrüstung hinzufügen die neue Waffe auf Waffenstufe eins zur Ausrüstung Anstatt hier falsch zurückzugeben und Tri zutrifft, werden wir tatsächlich die neue Waffe erstellen Wir können also sagen, dass Waffe gleich sein wird. Schauen wir uns unsere Definition Waffe zwei D-Pfad an, wollen wir instanziieren. Also sagen wir Laden auf den Pfad und dann instanziieren wir Und das wird unsere Waffe sein. Also müssen wir das zur Ausrüstung hinzufügen. Also Ausrüstung Füge Waffe hinzu und wir werden die Waffe hinzufügen. Wenn das funktioniert, wollen wir true zurückgeben. Wenn wir also unseren Artikel haben, können wir ihn jetzt zur Liste der möglichen Artikel hinzufügen , die von unserer Belohnungs-Benutzeroberfläche generiert werden sollen. Wenn ich also auf die Szene mit der Level-Up-Auswahl klicke und wir zum ersten Knoten hier auf der rechten Seite gehen, haben wir unsere Level-Eins-Optionen, und wir haben den Spira-Item bereits hinzugefügt Fügen wir also das Site-Element hinzu. Laden Sie also schnell unser Seitenelement, geben Sie ihm ein Gewicht von eins und fügen Sie es hinzu. Okay. Und dann lass uns auf Play klicken und sehen, was passiert , wenn wir hierher gehen. Sie können also sehen, dass dort ein unbenannter Artikel steht und wir keine wirklichen Details sehen Wenn ich auf „Wählen“ drücke, wird das neue Projektil nicht gestartet Dafür haben wir also noch einiges zu tun, die Gegenstände anzupassen und sicherzustellen, dass sie richtig geladen werden, und das werden wir im nächsten Teil regeln 51. P50 Erstellen einer Benutzeroberfläche für die Waffenanzeige für das Spielinventar: Project benötigt jetzt wirklich die Möglichkeit, oben links mit der UI-Anzeige zu sehen, welche Waffen wir ausgestattet haben. Und wenn wir aufsteigen, um entweder die erste Waffe zu verbessern oder eine neue Waffe auszuwählen, und ich kenne diese Namen und Beschreibungen auch hier. Das wird auch hier angezeigt, sodass wir zuordnen können , was wir sehen sollten und was wir tatsächlich sehen. Das hilft uns also beim Debuggen, ist aber auch für den Spieler sehr hilfreich Lassen Sie uns also weitermachen und eine neue UI-Szene erstellen, also klicke ich hier oben auf Plus Ich möchte diesen Kontrollknoten also so benennen, dass er, sagen wir, Waffen anzeigt, und ich werde auch rechten Maustaste klicken und seinen Typ in einen Panel-Container ändern. Okay, das gibt uns standardmäßig einen Hintergrund. Also hier drinnen werde ich einen Margin-Container haben wollen und darauf folgt ein HBox-Container für die Organisation Klicken Sie also mit der rechten Maustaste auf Randcontainer hinzufügen und klicken Sie dann mit der rechten Maustaste auf HBox-Container hinzufügen Okay, und dann werden wir hier im Grunde ein Symbol mit einer Füllstandsanzeige für jede unserer Waffen von links nach rechts anordnen ein Symbol mit einer Füllstandsanzeige für jede unserer Waffen von links nach rechts Nehmen wir das Waffendisplay und verkleinern es so, dass es eher so aussieht Und dann werde ich es in unserem Projekt im UI-Ordner speichern , also im UI-Ordner Weapons Display Und lassen Sie uns eine Kopie in unseren Gameplay-UI-Canvas einfügen unseren Gameplay-UI-Canvas damit wir sehen können, wie das ungefähr aussehen wird. Suchen Sie also nach einer Waffe und dann nehmen wir das Waffendisplay und positionieren es unter der Benutzeroberfläche. Und wir können sehen, dass das dort ziemlich groß ist. Ihr könnt also hier klicken und in das Waffendisplay springen und es auf die Mitte des Bildschirms verkleinern auf die Mitte des Bildschirms Beachten Sie das blaue Feld, das unsere volle Größe der Benutzeroberfläche angibt. Das muss also wirklich ein bisschen kleiner sein. Und ich möchte wahrscheinlich auch von der Mitte aus etwas ausgleichen. Lassen Sie uns standardmäßig auch das Layoutcenter verwenden. Jetzt können wir zum Gameplay-UI-Canvas zurückkehren. Wir können dort unsere Waffen ausstellen sehen. Es zeigt sich nicht wirklich so, wie wir es erwartet hatten. In der Waffenanzeige nehme ich also die Voreinstellung „ Anker“ und nehme die Standardeinstellung „Mitte“ oder die obere Mitte . Also mittig oben Und wir können das Problem darin sehen, warum es auf Null geschrumpft Also werde ich die benutzerdefinierte Mindestgröße hier erhöhen und eine Standardgröße festlegen Ich sage 200 für das X und dann 50 für das Y. Das nur so , damit wir es irgendwie sehen und auf unserer Gameplay-Benutzeroberfläche anpassen können und auf unserer Gameplay-Benutzeroberfläche anpassen Also gehe ich zum Canvas der Gameplay-Benutzeroberfläche und jetzt können wir es dort positionieren, wo wir es brauchen Also werde ich es, sagen wir, hier draußen rechts neben unserer Haupt-Gesundheitsleiste und der EXB-Leiste positionieren hier draußen rechts neben unserer Haupt-Gesundheitsleiste und der EXB-Leiste und ich werde es so herausziehen Okay. Und dann können wir ein paar Symbole für unsere Waffenstufen anzeigen lassen. Um das zu erfahren, werden wir unseren Spielerkontext nutzen wollen , damit wir zeigen können, welche Waffen der Spieler hat. Fügen wir also in der Waffenanzeige das Skript Islas Weapons Display Dot GD Und dann wollen wir var den Kontext exportieren, der hier der Spielerkontext ist, und wir können ihn im Inspektor zuweisen Laden Sie also schnell den Player-Kontext. Und dann auf Bereit wollen wir das verwenden, um auf unsere Waffenausstattung Bezug zu nehmen Also Funktion underscore bereit, sie wird void zurückgeben und dann sagen wir Context Dot Player Dot Haben wir einen Hinweis auf das Loadout? Haben wir nicht. Wenn wir das also nicht zu einer weiteren eingebauten Eigenschaft des Players machen wollen und dass das, worauf direkt im Player-Skript verwiesen wird, sich daran anpassen lassen, könnten wir sagen, Kinder finden, könnten wir sagen, Kinder finden, und das Muster wird aus leeren Anführungszeichen bestehen. Der Typ wird Waffenausstattung sein. Das wird uns also ein Array geben. Wir nehmen das erste Ergebnis indem wir eckige Klammern in eine Null setzen, das bedeutet also, dass der Array-Index Null ist. Und das werden wir einem Loadout zuweisen. Unser Underscore-Loadout wird also ein Waffen-Loadout sein ein Waffen-Loadout Und wir werden sagen, dass der Underscore-Loadout dem Ergebnis entspricht , und wir wollen behaupten, dass das nicht Null Assert Underscore Loadout ist also nicht gleich Null. muss eine Ausrüstung haben Der Spieler muss eine Ausrüstung haben, die für die Waffenanzeige angezeigt wird, Prozentzahl am Ende, damit wir den Namen dieses Knotens ermitteln können Und dann wollen wir, dass der Klassenname der Waffen hier oben angezeigt wird Dadurch werden die Waffen und die Level für den Kontext-Charakter angezeigt . Also lass uns noch einen bei Export var machen. Das wird für die UIC sein. werden wir für jede Waffe in unserer Ausrüstung instanzieren . Also mach eine bei Export var. Sagen wir Waffendisplay, das wird vom Typ Waffendisplay sein, aber das haben wir noch nicht erstellt. Und um irgendwie anzudeuten , dass dieses Display auch mehr kann, als nur die Daten anzuzeigen, sondern dass es auch alles miteinander verbindet. Ich werde das tatsächlich umbenennen, um es anzuzeigen. Das hilft auch dabei, sich von der Waffenanzeige, dem Sub-UI-Container, zu unterscheiden . Und dann benenne ich beide Waffendisplays um. Und dann benenne ich sowohl das Waffendisplay Dot GD das TSCN Also das wird jetzt Waffenansicht und hier oben Waffenansichtspunkt TSCN sein Okay. Springt auch in die View-Szene und benennt den Root-Node ebenfalls um. Das ist ziemlich wichtig. Das heißt, Waffen sind dort zu sehen. Jetzt müssen wir unsere individuelle Waffenanzeige so erstellen , dass sie in die Waffenansicht aufgenommen werden kann. Also lasst uns unserem Spiel eine neue Benutzeroberfläche hinzufügen. Dies wird zu Beginn eine Benutzeroberfläche sein. Und ich denke , dass die Wurzel hier vielleicht auch ein Panel-Container sein soll. Sie können ein Panel immer leer machen, aber die Möglichkeit, den Hintergrund zu haben , ist irgendwie hilfreich. Lassen Sie uns das also in einen Panel-Container ändern. Ich benenne das Stammverzeichnis in Waffenanzeige um. Klicken wir mit der rechten Maustaste darauf, fügen einen Container für den Rand eines untergeordneten Knotens hinzu, nur für den Fall, dass wir ihn benötigen, und klicken dann mit der rechten Maustaste auf Textur hinzufügen , um unser Symbol anzuzeigen Wir klicken mit der rechten Maustaste auf „Label hinzufügen“. Und ich denke tatsächlich, dass ich dafür keinen VBox- oder HBox-Container benötige VBox- oder HBox-Container weil ich vielleicht möchte, dass das Etikett die Textur überschreibt Bei vielen Spielen , die eine Textur und dann gleichzeitig Text hätten , würde es den Text tatsächlich über das Textursymbol schreiben Das würde man häufig in Inventarsystemen sehen, um die Anzahl der Gegenstände im Inventar geht. Außer in diesem Fall geht es um das Level der Waffe, mit der der Spieler ausgerüstet ist. Als Testtext könnten wir hier also Level X sagen. Natürlich können wir sehen, dass das Display jetzt den ganzen Bildschirm einnimmt. Lassen Sie uns das also tatsächlich verkleinern. Ich gehe zur Basiswaffenanzeige und wir nehmen das Layout zur Voreinstellung „ Anker“ oben links Okay, das sollte es dramatisch verkleinern. Jetzt können wir also sehen, dass nur der Text angezeigt wird. Lassen Sie uns eine Textur auf diese Textur setzen. Also werde ich eine neue Atlas-Textur erstellen und dann werden wir schnell einen Atlas laden. Lass uns vielleicht nach 16 mal 16 suchen. Sprite Sheet in unserem Spiel für alle Icons, und dann wollen wir die Region bearbeiten und eine auswählen Also etwas, das wie eine Waffe aussieht. Hier haben wir ein Schwert, das gut funktioniert, und wir können es schließen. Okay, wir können sehen, dass das Schwertsymbol da ist, aber es respektiert nicht das Seitenverhältnis, also wollen wir in den Streckmodus wechseln und das ändern, damit das Seitenverhältnis zentriert bleibt, glaube ich. Okay, da haben wir das. Und jetzt wollen wir unseren Hauptwaffen-Ausstellungsbehälter nehmen und wir wollen, dass er auch eine bestimmte Größe hat. Also sage ich benutzerdefinierte Mindestgröße 48 mal 48. Das gibt uns hier ein Quadrat. Und ich nehme den Labeltext und wir wollen, dass er unten mittig ist. also sehen, dass die vertikale Ausrichtung nach unten Sie werden also sehen, dass die vertikale Ausrichtung nach unten nichts ändert, da wir die Größe des Etiketts vergrößern müssen , damit der Text unten zentriert wird. Gehen wir jetzt zum Layout, und ich glaube, wir wollen , dass die Größe des Containers gefüllt wird. Ja. Okay, da. Also, jetzt wird Level X dort unten rechts angezeigt. Und jetzt sieht es so aus, als ob wir einen kleinen Puffer zwischen unserer Textur rect und unserem Label wollen einen kleinen Puffer . Lassen Sie uns das vorerst in unserem UI-Ordner, unserem Waffendisplay, speichern . Und ich denke, was wir wollen, ist ein zweiter Margin-Container. Also werde ich auf den ersten Randcontainer klicken, einen weiteren Randcontainer hinzufügen, und dieser wird das übergeordnete Objekt der Texturect sein Positionieren wir das also wieder oben, sodass der Text zu sehen nun mit diesem Randcontainer Gehen Sie nun mit diesem Randcontainer zu den Theme-Overrides, und wir möchten, dass der untere Rand etwa zehn Pixel beträgt Auf diese Weise wird der Text, Sie wissen schon, nicht über den wichtigen Teilen unseres Symbols angezeigt Vielleicht brauchen wir es sogar mehr als das. Also lass uns 12 versuchen. Vielleicht brauchen wir es sogar mehr als das, wirklich. Damit wir sehen können, wie es besser aussehen wird, wenden wir unser Spieldesign auf das Waffendisplay an. Klicken Sie also auf die Waffenanzeige, suchen Sie das Thema und laden Sie dann schnell unser aktuelles Thema hoch. Okay, das ist jetzt viel kleiner und befindet sich in der unteren linken Ecke. Ich glaube, ich will es unten rechts haben. Klicken Sie also auf das Etikett und lassen Sie uns die horizontale Ausrichtung nach rechts nehmen. Okay? Das sieht ziemlich okay aus, ist aber ein bisschen zu nah am Rand. Also möchte ich den übergeordneten Margin-Container nehmen. Das ist der direkt unter dem Waffendisplay, und ich möchte einige Ränder festlegen. Gehen wir also zu Theme-Overrides und vielleicht zu zwei Pixeln auf jedem davon Okay, das sieht richtig aus. Außer vielleicht der untere Rand. Vielleicht brauchen wir das nicht. Ja. Okay. Das gefällt mir besser. Ordnung, jetzt benötigt unser Waffendisplay einen Verweis auf den D-Node der zweiten Waffe Und jedes Mal, wenn der D-Knoten der Waffe zwei Stufen aufsteigt, ändern wir den Text hier, sodass der neue Level angezeigt wird Lassen Sie uns also ein Skript zur Waffenanzeige hinzufügen. Das wird einfach auf dem Uilashwapon-Display Dot GD angezeigt. Okay. Und das wird eine Waffenanzeige mit Klassennamen sein. Und wir brauchen einen Verweis auf die Waffe Zwei D. Ich könnte sie für den Moment einfach exportieren. Das wird also eine Var-Waffe vom Typ Waffe zwei D sein. Ich sage Festwert, und das wird Waffe gleich Wert sein Wann immer wir die Waffe einstellen, rufe ich einfach eine Aktualisierungsfunktion auf, und das stellen wir hier Also Funktion aktualisieren. Um also den Text auf dem Etikett und dem Symbol festzulegen, benötigen wir eine Exportreferenz für jedes dieser Elemente. Also bei Export var texture, Text direkt vom Typ Textur Rc. Und dann brauchen wir bei Export var label, das vom Typ Label ist. Und wenn wir aktualisieren, wollen wir sagen texrec-Punkttextur dem Punktsymbol mit der Waffenpunktdefinition entspricht . Ja, das funktioniert Und dann sagen wir, dass der Label-Punkt-Text dem Waffenpunkt entspricht, falls wir hier einen Namen haben, Waffenname Nein, wir wollen den Definitionsnamen, weil der Name auf der Waffe eigentlich der Name des Knotens ist , der keine Leerzeichen oder ähnliches enthalten wird, also ist es besser, den Ressourcennamen zu weil das eine benutzerdefinierte Eigenschaft ist, die wir festgelegt haben. Und dann wollen wir sagen, dass Plus einem Leerzeichen plus einer Zeichenfolge auf Waffenpunktebene entspricht . Okay? Also das zeigt im Grunde den Waffennamen und dann, auf welchem Level sie sich gerade befindet. Und nur für den Fall , dass die Waffendefinition kein Symbol hat, lassen Sie uns eine Get-Icon-Methode erstellen. Was genauso funktionieren wird, wie wir es mit einem der anderen Skripte zuvor gemacht haben , das einfach null zurückgibt , wenn diese Eigenschaft zufällig nicht gesetzt ist. Klicken wir also mit der rechten Maustaste auf die Definition. Wir gehen darauf ein, klicken Sie mit der rechten Maustaste auf Waffendefinition. Darauf gehen wir ein. Und dann erstellen wir unsere Funktion G icon, die eine Textur mit zwei D zurückgibt . Also, wenn icon nicht gleich Null ist, dann geben wir icon zurück. Andernfalls geben wir Null zurück, und das sollte verhindern, dass Sie Fehler bekommen , wenn das Symbol hier zufällig Null ist. Okay, und wir wollen wahrscheinlich auch versuchen, R zu aktualisieren, damit die Funktion underscore bereit ist. Ich werde versuchen, eine Aktualisierung durchzuführen Das hilft uns auch zu bestätigen , dass, falls es kein Waffen-Zwei-D-Set gibt, es einwandfrei funktioniert und einfach leer angezeigt wird Die Idee dabei ist , dass, wann immer wir die Waffenansicht einrichten, sie mit Waffendisplays gefüllt wird Wir stellen die Waffe ein und sie wird sofort aktualisiert Gehen wir also zur Waffenansicht. Und hier drinnen, nun, Sie sehen, dass ich eine Waffenanzeige exportiert habe, aber was ich eigentlich tun möchte, ist die Szene zu exportieren. Das wird also eine vollgepackte Szene sein, die wir instanzieren können. Und dann laden wir schnell auf der rechten Seite unser Display für die Waffe, also Waffenanzeige. Also fertig, sobald wir die Ausrüstung haben, möchte ich hier alle Waffendisplays für jede der Waffen, die sich tatsächlich in unserer Waffenausstattung befinden, auffüllen für jede der Waffen, die sich tatsächlich in unserer Waffenausstattung befinden, tatsächlich in unserer Waffenausstattung Also habe ich etwas Ähnliches mit der Auswahlebene gemacht, bei der ich sie einfach jedes Mal lösche und zurücksetze und neue Szenen für jede der Unter-Benutzeroberflächen generierte , die erstellt werden müssen Aber hier werde ich tatsächlich versuchen, es wiederzuverwenden , damit ihr beide Ansätze sehen könnt. Dies wäre technisch gesehen die bessere Nutzung Ihrer Knoten, da Sie sie nicht jedes Mal löschen und neu erstellen Ich denke also, dass es hilfreich sein wird, das nach dem Kurs zu wissen. Eine Möglichkeit, einfach auf all unsere aktiven Waffenausstellungen zuzugreifen unsere aktiven Waffenausstellungen besteht darin, eine Reihe von ihnen zu haben. Also ich sage var underscore displays, und das ist ein Array Ich zoome die Waffenanzeige heran. Lassen Sie uns auch unsere Aktualisierungsfunktion erstellen. Unsere Funktionsaktualisierung wird also den Wert void zurückgeben. Und für jede der Waffen in unserer Waffenausstattung werden wir eine Anzeige erstellen, werden wir eine Anzeige erstellen falls eine erstellt werden muss Andernfalls, falls es in dieser Waffenanzeige bereits vorhanden ist , werde ich es wiederverwenden, indem ich einfach die Eigenschaften mit der neuen Waffe aktualisiere, indem ich die Waffe auf der Waffe auf setze Okay, für unsere Aktualisierungsfunktion wollen wir also alle Waffen in einer Schleife durchgehen und dabei die Indexpositionen verwenden, sodass wir die Waffenausrüstungsindizes mit unseren Waffenanzeigeindizes abgleichen können Waffenausrüstungsindizes mit unseren Waffenanzeigeindizes Also für IN-Range Null, um die Punktgröße der Ausrüstungswaffen zu unterstreichen und um eins zu erhöhen Dann holen wir uns zuerst die Waffe. Also wird unsere Waffe vom Typ Waffe Zwei sein. Entspricht dem Unterstrich der Ausrüstungswaffen an dieser Indexposition, und wir müssen das Display ermitteln oder erstellen Also werde ich sagen, dass var display ein Waffendisplay ist, und wir setzen das gleich, um Display an einer Indexposition von I zu erhalten oder zu erstellen. Und dann auf unserem Display, sobald wir das erworben haben, sage ich, dass die Display-Waffe der Waffe selbst entspricht Und weil die Aktualisierung Teil des Setters und des Skripts ist , wird sie sofort automatisch aktualisiert Nun, ich habe ein wenig über Nebenwirkungen gesprochen , und wenn Sie den Setter so ausführen, ist nicht unbedingt zu 100% klar , ob das Setzen der Waffe die Benutzeroberfläche automatisch aktualisiert Aber weil das so wichtig für das Waffendisplay ist, denke ich, dass es in Ordnung ist, hier einfach zu sagen: Oh, wir haben die Waffe eingestellt Natürlich zeigt die Waffe die aktuelle Waffe. Aber da die Waffenanzeige wortwörtlich das ist, was sie tut, das Einstellen der Waffe und das implizieren, dass aktualisiert würde, welche Waffe auf der Benutzeroberfläche angezeigt wird Ich denke nicht, dass das als Nebeneffekt viel zu problematisch Aber es ist definitiv fraglich. müssen wir nur noch das Display abrufen oder erstellen Also Funktion, Anzeige mit Indexparameter abrufen oder erstellen, und das wird eine Ganzzahl sein, und wir werden eine Waffenanzeige zurückgeben. Nehmen wir an, die Anzeige var vom Typ Waffenanzeige entspricht der Anzeige des Punkts Get at index. Okay, das könnte also Null sein. Wenn Display also nicht gleich Null ist, wir einfach das Display zurück. Andernfalls müssen wir hier eine erstellen und sie zur Anzeige hinzufügen sodass die Anzeige der Instantiierung der Waffenanzeigeszene entspricht Instantiierung der Waffenanzeigeszene entspricht Und ich habe den Namen falsch eingegeben. Also genau hier, Control C, Control V. Und dann wollen wir es als untergeordnetes Element zu dieser Benutzeroberfläche hinzufügen , oder besser gesagt es wird in den HBox-Container aufgenommen. Also, warte mal. Ich benötige einen Hinweis auf den Container. Also exportiere den V-Display-Container, und das wird jede Art von Container sein. Wir müssen das nur auf der Benutzeroberfläche exportieren. Dann nehmen wir den Display-Container und fügen das Display als untergeordnetes Element hinzu. Wir sagen, dass sich Displays auf einem neuen Display öffnen. Und dann, zum Schluss, wollen wir zum zurückkehren, das Display drehen Es sollte also hier erstellt werden , wenn es hier nicht schon existiert hätte. Das wird also die Erstellung der neuen Displays übernehmen. Also, was ist, wenn wir eine Waffe entfernen? Nachdem wir uns die Waffen angeschaut haben und alle Displays eingerichtet haben, wollen wir überprüfen, ob die Waffen-Reihe tatsächlich kleiner ist als unsere Display-Reihe, und dann die zusätzlichen Displays entfernen. Nehmen wir an, wir entfernen eine Waffe aus dem Spiel und möchten, dass unser Display aktualisiert wird. Nun, das wird jetzt eine Nullreferenz auf dem Display sein . Also können wir für Display und Display sagen Ich zeige die Punktwaffe ist Null, dann können wir das Display einfach freilassen. Zeigen Sie also Punkt Q frei an und warten Sie hier. Ich brauche diesen Unterstrich dort , weil das eine private Variable ist Wir haben also unseren Displaypunkt Q frei. Wir haben also unseren Display-Punkt Q frei, und wir wollen ihn an unser Loadout-SI Lassen Sie uns das also tatsächlich als lokale Variable unserer Waffengröße Jetzt können wir die Waffengröße hier und auch hier unten wiederverwenden. Okay, um diese Funktion noch einmal durchzugehen: Sie aktualisiert und erstellt nach Bedarf Displays, Sie aktualisiert und erstellt um alle Waffen anzuzeigen, entfernt alle Displays, die keine Waffen haben, und ändert die Größe der Display-Reihe Also bekommen wir die Anzahl der Waffen. Für jede dieser Waffen weisen wir die Waffe der entsprechenden Anzeigeposition zu . Nachdem wir das getan haben, schauen wir uns noch einmal alle Displays an, und technisch gesehen könnten wir vom Waffenbereich bis zum Ende durchgehen, aber wir haben die Optimierung etwas übertrieben nicht viel zu gewinnen, weil wir hier nur etwa sechs Gegenstände anzeigen. Aber wenn die Displaywaffe Null ist, aber hier, wenn die Displaywaffe Null ist, was es sein könnte, wenn wir eine Waffe entfernen, dann werden wir uns auf dem Display frei in die Warteschlange stellen und die Größe der Displays so ändern , dass diese Größe mit den Waffen übereinstimmt. in unserem G- oder Create-Display Wenn in unserem G- oder Create-Display das Display mit demselben Index existiert , wird es einfach das zurückgeben und wir verwenden Andernfalls wird eine neue Kopie der Szene erstellt, die wir dann unter dem HBox-Container anwenden Okay, jetzt müssen wir im Inspektor diesen HBox-Container zuweisen Wir könnten ihn in Displays Container umbenennen , wenn das hilft Zeigt also den Container an, wobei die Benennung konsistent bleibt. Und wir haben schon die Waffendisplays hier. Also das wird auf Okay funktionieren, also lass es uns laufen lassen und schauen, ob es gerade bei Run funktioniert. Also rennen wir weg und haben die Waffenausstattung nicht gefunden weil ich denke, sie könnte als Waffenausstattung bezeichnet werden. Also du kannst sehen, Fine Children ist so zerbrechlich Also haben wir dort eine Waffenladung. Lassen Sie uns also versuchen, die Waffenausstattung mit dem S zu finden, und dann werden wir es erneut ausführen Okay, wir kommen zu dem Punkt, an dem wir Textur-Punkt-Textur gleich Waffen-Punktdefinition-Punktsymbol haben Textur-Punkt-Textur gleich Waffen-Punktdefinition-Punktsymbol Okay, dann stoßen wir auf ein anderes Problem. Ich habe den Text nicht auf dem Etikett auf dem Waffendisplay angezeigt Gehen wir also zur Waffenanzeige und korrigieren das. Rechts oben, wenn Sie die Waffe verschieben, weisen Sie der Textur per Doppelklick die Textur zu und weisen Sie dann die Bezeichnung und weisen Sie dann Okay, und wir lassen es noch einmal laufen. Mal sehen, ob das die Probleme löst. Okay, also hier, wenn es keine Waffe gibt, wird das ein Problem verursachen Also vielleicht wollen wir wirklich, dass es eine Waffe einstellt, bevor wir es aktualisieren. Da der Refresh also hier stattfindet, wenn wir die Waffe einstellen, werde ich den Ready-Refresh entfernen. Das ist nicht wirklich nötig, und es bereitet uns hier einfach mehr Kopfschmerzen , als wir brauchen. Also drücke ich auf Play. Und okay, los geht's. Wir haben Spear One oben links Ich gehe hierher und wir wählen den neuen Artikel aus. Nun, das wird nicht funktionieren , weil wir keine Signale eingerichtet haben. Okay, also ein Fehler, den ich gemacht habe Wenn du Git für einen Index aufrufst , der in einem Array nicht existiert, bekommst du Out-Out-Bound-Fehler. Was wir also eigentlich tun sollten, ist sicherzustellen , dass sich der Index im Array befindet. Also sagen wir, wenn Displays sagen wir, die Größe größer als der Index ist, dann geben wir hier dieses Bit zurück, zeigt den Punkt Git Index an. Sicher. Dann können wir die Variablendeklaration var display weapon display hier unten entfernen, bis wir die Display-Szene instanziieren, und wir werden diese Zeile oben entfernen 52. P51 Verbinden von Signalen und Konfigurieren der Waffenoberfläche für dynamische Anzeige: Okay, wir müssen in unserer Waffenansicht und auf dem Waffendisplay noch ein paar Signale verbinden unserer Waffenansicht und auf dem Waffendisplay , sodass, wenn wir im Spiel sind, das richtige Waffen-Setup korrekt angezeigt wird , nachdem wir die Benutzeroberfläche aktualisiert haben. Ein sehr wichtiger Punkt wird also sein wenn unsere Ausrüstung eine Waffe hinzufügt, indem die Methode zum Hinzufügen von Waffen aufrufen, die wir mit dem Signal „Waffe hinzufügen “ verbinden, das ich, glaube ich, noch nicht einmal erzeugt habe Lassen Sie uns also zur Waffenausstattung übergehen. Ich klicke hier mit der rechten Maustaste und öffne das Symbol. Jetzt sind wir beim GD-Skript für die Waffenausstattung. Wir haben also die Methode zum Hinzufügen von Waffen, und wir wollen hier ein Signal zulassen , damit unsere Ansicht darauf reagieren kann Lassen Sie uns also ganz oben unsere Signalwaffen ändern. Wenn wir möchten, können wir das Waffenarsenal in das Signal einbeziehen. Also Waffen, das ist eine Reihe von Waffen zwei D. Und jetzt müssen wir es nur noch hier unten zugeben , wenn wir Waffe hinzufügen aufrufen. Waffen wurden geändert, Punkt emittieren, und wir geben die Waffen ab. Okay? Nun zurück zu unserem View-Skript, wir abonnieren so weiter und fertig Nachdem wir das Loadout bekommen haben, wollen wir das Loadout, die Waffen ändern Und wir werden sagen, dass sich die Waffen geändert haben. Wir werden diese Methode hier unten machen. Also hat sich die Funktion der Waffen geändert. Der Parameter ist die P-Waffe, das ist eine Reihe von Waffen das ist eine Reihe von zwei D, wir kehren als ungültig zurück. Jetzt werden wir hier Refresh aufrufen. Das ist alles, was wir tun müssen, denn Refresh kümmert sich bereits darum, die Waffenausstattung zu überprüfen und , welche Waffen wir haben und wie groß sie Wir werden diese P-Waffen hier also nicht direkt einsetzen, also werde ich es unterstreichen, damit wir keine Warnung erhalten Und jetzt, bevor wir auf Play klicken, möchte ich sichergehen , dass unsere Gegenstände tatsächlich richtig definiert sind Also werde ich im Dateisystem unten rechts nach einem Objekt suchen. Wir haben den Syth-Artikel. Schauen wir uns also an, ob wir jetzt nach oben gehen Dies ist ein unbenannter Artikel ohne Beschreibung, und er benötigt auch ein Symbol Außerdem scheint es, als ob ich auch die falsche Artikeldefinition habe, es scheint, als hätte ich die falsche Artikeldefinition Das macht jetzt sehr viel Sinn, warum die Sensenwaffe nicht erschienen ist Laden wir hier also schnell die Sensendefinition hoch. Okay, das ist richtig eingerichtet, aber wir müssen unseren Anzeigenamen festlegen Sense. Für die Beschreibung werde ich also ein Projektil platzieren, das sich auf dem Bildschirm dreht und viele Feinde treffen kann Das ist im Grunde der Hauptunterschied zum Speer. Und was das Symbol angeht, nun, lasst uns zur Definition der Sense übergehen Ich klicke hier mit der rechten Maustaste auf das Symbol und kopiere es und schließe es dann und füge es hier in das Symbol Okay, jetzt müssen wir etwas Ähnliches mit dem Speer-Gegenstand machen . Doppelklicken Sie also auf Spear Dann gehen wir nach oben rechts. Der Anzeigename wird Spear sein. Die Beschreibung kann also ein einfaches Projektil sein, das sich aus der Richtung vorwärts bewegt, in die der Charakter , glaube ich, schaut Und dann das Symbol, wir kopieren es einfach aus der Definition auf das Gegenstandssymbol. Einfach so. Und das sollte im Grunde eine Menge davon erledigen. Also lass uns spielen. Ich glaube, das Einzige, was jetzt passiert, ist, dass wir keine Verbindung zu einem Level-Up-Signal hergestellt haben, aber okay, wir können Speer eins oben links sehen Lass uns unsere Sense holen. erste Sense ist jetzt da oben und unser Sensenprojektil wird auch abgefeuert Wir können sehen, dass es rotiert. Vielleicht reicht seine Bewegungsgeschwindigkeit nicht wirklich aus, weil wir wollen, dass es sich tatsächlich im Kreis um den Spieler dreht. Aber stellen wir sicher, dass es zuschlagen kann. Ja. Okay, es scheint also Feinde zu treffen. Ganz schnell, in den generierten Auswahlmöglichkeiten gibt es einen Hinweis auf die gewählte Abschattung und das bereits deklarierte Signal Also das ist nicht großartig. Ich werde das ausgewählte Array nehmen und Auswahlmöglichkeiten generieren. Das steht im Weapons View-Skript. Das steht hier auf der Prämienbox. Ich nehme das und lasse uns R kontrollieren. Ich werde es in „Ausgewählte Elemente“ umbenennen. Ich werde auf „Ersetzen“ klicken nicht auf „Alles ersetzen“, weil wir nicht mit den Signalnamen herumspielen wollen. Ersetzen Sie also nur innerhalb dieser Funktion, und wir wollen bis hierher gehen. Ich sollte auch die Groß - und Kleinschreibung und ganze Wörter zuordnen , um die Anzahl der zusätzlichen Elemente zu reduzieren , die ausgewählt werden. ausgewählte Datenstift ist jetzt der Datenstift für ausgewählte Elemente und dann geben wir die ausgewählten Elemente zurück Okay. Also das sollte mit dieser Warnung umgehen. Okay, unsere Seiten-Szene rotierte also nicht genau so , wie wir es erwartet hätten. Ein Problem mit den Projektilskripten ist also , dass, wenn ich versuche zu sagen, diese Szene laufen zu lassen, ohne sie vorher von einer Waffe aus zu starten, dass wir diese Ausgabe dort bekommen , wo sie die Assert-Position fertig macht Was wir stattdessen also hauptsächlich zu Testzwecken tun könnten, ist, eine Standardrichtung festzulegen Also werde ich sagen, dass die Richtung dem Vektor zwei Punkt nach rechts entsprechen wird. Also habe einfach diese Standardeinstellung da. Wir werden die Behauptung entfernen. Deshalb werde ich auch das Level var exportieren, sodass wir die Möglichkeit haben, im Inspektor ein Waffenlevel einzustellen . Das sollte für uns nicht erforderlich sein, weil wir meistens mit der Startmethode starten werden , oder? So haben wir das Projektil aufgestellt. Aber nur für den Fall, dass wir es im Editor testen wollen, könnte ich hier und rechts ein Testlevel einrichten , sodass wir eine Standard-Waffengeschwindigkeit definieren können eine Standard-Waffengeschwindigkeit definieren Also lass uns auf Play klicken. Okay, jetzt mit diesem Setup sollte ich in der Lage sein, dieses Skript auszuführen, und wir können sehen, wie es sich standardmäßig bewegen wird, was für uns ganz oben ziemlich hilfreich ist. Ich könnte sogar eine Testszene erstellen, in der wir eine Kamera haben , die in die Mitte unserer Kamera schaut , was uns beim visuellen Debuggen weiter hilft , sodass wir nicht das komplette Spiel ausführen müssen und jedes Mal, wenn wir den Sensengegenstand testen wollen, ein Level aufsteigen müssen. Lassen Sie uns also unsere Testszene erstellen. Das wird also eine neue Zwei-D-Szene sein, und ich werde sie im Stammverzeichnis speichern. Nennen wir es also Test Weapons Dot TSCN. Heb dir das auf und ich werfe die Sensenwaffe rein. Also Sensenwaffe Punkt TSN. Das haben wir da einfach an der Wurzel verankert. Ich benenne den Wurzelknoten um. Testen Sie also Waffen und lassen Sie uns dann mit der rechten Maustaste klicken und eine Kamera zu D hinzufügen . Das hat also einen Zoom von drei. Ich finde es gut. Und lassen Sie uns versuchen, die Szene auszuführen, indem Sie auf die Schaltfläche „ Aktuelle Szene abspielen“ klicken. Okay, der Grund, warum wir hier nichts sehen, ist eigentlich, dass wir die Sensenwaffe hier nicht platzieren Wir sollen das Syth-Projektil platzieren. Also mein Fehler Also lass uns nach dem Sythe-Punkt suchen und das auf die Wurzel legen. Wenn wir jetzt hineinzoomen, sollten wir das sehen können . Okay, das ist gut. Und lass uns die Schaltfläche „ Aktuelle Szene ausführen“ drücken. Jetzt können wir sehen, wie es aussehen wird, wenn unsere Sense nach rechts schießt, und das macht es für uns viel einfacher und schneller, diese Sense zu debuggen Jetzt, wo wir die Testszene eingerichtet haben, können wir sehen, wie sich unsere Waffen auf dem Bildschirm drehen und bewegen, aber das ist nicht genau das, wonach wir suchen Was wir hier also tatsächlich ändern müssen ist wieder in der Sensen-Szene, diesem Rotatorknoten. Wenn wir wollen, dass sich die Waffe oder das Sprite um einen Mittelpunkt dreht, dann müssen wir diesen Rotator tatsächlich nach rechts verschieben diesen Rotator tatsächlich nach rechts während unser Sprite und die Trefferbox an derselben Position bleiben . Also werde ich diese beiden vorübergehend vom Rotator zwei D wegbewegen vom Rotator zwei D , damit sie sich nicht mitbewegen, und dann werde ich die beiden Rotatoren D so nach rechts bewegen . Okay, das gibt uns einen Offset sodass sich alles um ihn herum tatsächlich um diesen Punkt drehen kann , anstatt sich nur hier im Kreis zu drehen Also bringen wir das direkt in der Trefferbox zurück in den Rotator zwei D. Okay, gut. Und wir könnten sagen, die X-Geschwindigkeit auf 25 erhöhen Lassen Sie uns die Szene durchgehen und sehen, ob wir damit das bekommen, wonach wir suchen. Also ja, aber das ist eigentlich ein bisschen zu schnell. Also vielleicht senken wir das einfach wieder auf die Standardeinstellung von zehn und führen es erneut aus. Es ist also die Rotation, die das tatsächlich tut. Also brauchen wir entweder eine langsamere Rotation oder vielleicht brauchen wir sie weiter draußen nach rechts. Ich bin mir nicht sicher welcher. Das ist nur eine Vermutung, die hier für mich nachschaut. Also, falls du zufällig den Rotator mit diesem Sprite und der Hüftbox darunter bewegst , stelle sicher, dass du sie zurück zum Mittelpunkt 00 bewegst zum Mittelpunkt 00 Und dann lass uns die Testszene laufen lassen und mal sehen. Ich schätze, nur 360 Grad sind viel zu schnell. Okay, also ich gehe zurück zur etwaigen Szene und wir werden die Rotationsgrade senken Lass uns das halbieren, vielleicht 180. Lassen Sie uns dann unsere Testszene ausführen. Okay, das entspricht wahrscheinlich viel mehr dem, was wir wollen, aber ich habe den Abstand zum Rotator jetzt auch zu weit gemacht Rotator jetzt auch zu weit Okay, also ich werde den Sprite zwei D herausbewegen und die Hüftbox herausnehmen und dann den Rotator wieder ziemlich weit nach innen bewegen Schieben Sie das Sprite und die Hüftbox wieder unter den Rotator. Und lass es uns in der Testwaffenszene testen. Okay, lassen Sie uns das überprüfen. Äh, fast. Aber vielleicht ist die Geschwindigkeit des Projektils immer noch zu hoch Ich weiß es nicht. Wir müssen es im Spiel testen. Drücken wir also auf Play und das wird tatsächlich das Hauptspiel starten , weil das die Hauptszene ist. Also schnappen wir uns den Speer, das Sensenprojektil. Und so sieht unsere Sensenwaffe im Moment Ich bin mir nicht sicher, ob ich mit dem Muster super zufrieden bin, aber zumindest entspricht es dem allgemeinen Konzept Es geht hauptsächlich darum dass wir die Variablen jetzt optimieren Lass mich versuchen, den Spieler zu treffen und zu vernichten. Okay, er entfernt sich immer noch von der Szene, aber wir müssen das Spiel über den Bildschirm erstellen. Als Teil des Kurses. Also werde ich das noch einmal laufen lassen, damit wir unser Sensenprojektil bekommen Das ist so, als würde man nach rechts gehen. Mir wäre es lieber, wenn es mehr zentriert nach rechts ginge. Lass mich sehen, ob ich das anpassen kann. Vielleicht ist das das Ergebnis der X-Geschwindigkeit. Ich werde versuchen, das auszuschalten und die Szene noch einmal laufen zu lassen. Okay, jetzt ist es ein bisschen so. Hier geht's zurück zum Anfang. Weil der Rotator keine zusätzliche Geschwindigkeit hat. Und in welche Richtung er startet hängt davon ab, ob Sie nach links oder rechts schauen Es ist also zumindest für beide Seiten gleichermaßen anwendbar . Das könnte dir gefallen. könntest du nicht. Es geht meistens nur darum die Variablen zu optimieren, um das gewünschte Muster für die Bewegung zu erhalten gewünschte Muster für die Also zumindest für den Moment würde ich sagen, dass es ziemlich akzeptabel ist Lasst uns die Speerwaffe hier verbessern. Und das wird die Waffe hochstufen, aber wir haben hier kein Signal zur Erhöhung der Stufe angeschlossen. Okay, also wo wir das machen, ist auf dem Waffendisplay. Lass uns zum Waffendisplay springen. Wenn wir die Waffe hier platzieren, müssen wir die Signale verbinden. Aber an diesem Punkt würde ich sagen, dass das tatsächlich zu viel Zeug in einen Setzer für die Waffe steckt zu viel Zeug in einen Setzer für die Waffe Es verbirgt gewissermaßen, wofür es gedacht ist . Die Auffrischung war okay Aber ich denke, wenn wir Signale verbinden und die Benutzeroberfläche aktualisieren, ist das einfach zu viel Lassen Sie uns also eine Waffe mit Funktionssatz erstellen. Was eine Waffe zwei D eingibt. Okay, also wenn Waffe nicht gleich Null und wir sagen, dass Waffenpunkt geändert verbunden ist, und dann werden wir hier einen Rückruf haben, unterstreichen, ob die Waffenebene Das wird uns natürlich eine Fehlermeldung geben, weil die geänderte Stufe auf der Waffe noch nicht existiert Also lasst uns in die Waffe springen und das Symbol nachschlagen. Wir erzeugen hier ein Signal geändertem Signalpegel, das Sie an den Pegel übergeben, der eine Ganzzahl ist. Wenn das alles ist, was ich mit diesem Level machen werde , und ich glaube, das ist es, dann sagen wir Sollwert. Wir sagen, wenn Level gleich Wert ist, kehren wir zurück, Level ist gleich Wert, und wir können Level ändern Punkt für MIT Auf den Ebenen. Also machen wir diese Eigenschaft irgendwie beobachtbar, und das ist alles, was ich dort ändern werde Der Grund für diesen Schutz ist, dass wir, wenn wir das Level auf das Level einstellen, keine unnötigen UI-Signale aussenden wollen , weil sich das Level tatsächlich nicht geändert Wir müssen dieses Update also nur durchführen wenn wir es auf einen neuen Wert setzen. Nun, ich habe hier oben oben einen Doppelpunkt vergessen, damit der Fehler behoben wird. Jetzt haben wir in unserer Waffenausstellung das Level geändert. Wir müssen eine auf Waffenebene geänderte Callback-Funktion erstellen geänderte Callback-Funktion Also Funktion, Copy/Paste auf Waffenebene geändert, und dann haben wir das P-Level, das ist eine Ganzzahl Wir kehren zu void zurück und möchten die Benutzeroberfläche hier aktualisieren. Äh, aber was wir hier tatsächlich tun, ist, dass wir die Verbindung zum alten Waffensignal trennen, falls es existiert Also überprüfen wir, ob die alte Waffe hier existiert, indem wir prüfen, ob sie nicht Null ist Also, wenn das Signal angeschlossen ist, müssen wir es trennen. Höhe des Waffenpunkts wurde geändert Punkt, an dem die Verbindung unterbrochen wurde, wurde geändert. Keine Klammern. Und dieser Teil verifiziert nur, ob das Signal tatsächlich angeschlossen ist, bevor wir ein Signal trennen , das nicht Also nur Sicherheitsleute. Also, wir haben die alte Waffe so vorbereitet , dass sie komplett abgeschaltet werden kann, sodass wir die Waffe jetzt wechseln können Also sagen wir, Waffe ist gleich P-Waffe, und dann wollen wir uns mit den Signalen für den Levelwechsel dieser Waffe verbinden Levelwechsel dieser Waffe Wir können aber auch einen Wachmann einsetzen überprüft, ob es aus irgendeinem Grund bereits eine Verbindung Das ist ein bisschen übertrieben sicher, aber wir könnten einfach sagen, ob der Punkt zur Änderung der Waffenebene schon mit dieser Funktion hier unten verbunden ist , und wir wollen das umgekehrt machen Wir sagen also, wenn es nicht verbunden ist , dann müssen wir es verbinden Also hat sich die Höhe des Waffenpunkts geändert, Punkt Verbinden, Unterstrich auf Waffenebene geändert Und wir wollen auf jeden Fall auch auffrischen . Also lasst uns das auffrischen. Wenn wir also die Waffe einsetzen, aktualisieren wir sie, und jedes Mal, wenn sich das Level ändert, aktualisieren wir sie. Jetzt wollen wir diese Eigenschaft und den Unterstrich nehmen und sie einfach privat machen Das wird also eher eine private Variable sein. Und das wollen wir nicht direkt ändern. Wir möchten allen, die dieses Skript verwenden, dringend empfehlen , stattdessen die Set-Weapon-Methode zu verwenden. Also werde ich hier auswählen und wir werden kontrollieren und im Grunde suchen und ersetzen. Stellen Sie also sicher, dass Sie Groß- und Kleinschreibung mit ganzen Wörtern übereinstimmen, und lassen Sie uns das dann ändern , um die Waffe zu unterstreichen Ich denke, wir können hier mit dem Massenaustausch durchkommen. Also ersetzen alle 11 Instanzen einfach alle. Das ist Control R, um das Menü aufzurufen. Wenn wir das Spiel jetzt starten würden, würden wir natürlich eine Fehlermeldung bekommen, weil wir versuchen, die Waffe einzustellen und nicht die Waffe aus der Waffenansicht zu unterstreichen Wenn wir also in die Waffenansicht gehen, jetzt in unserer Aktualisierung wollen wir jetzt in unserer Aktualisierung das Display Dot Set Weapon auf der Waffe zwei D mit der Waffenwaffe zwei D aufrufen der Waffe zwei D und das entfernen Der ganze Grund für die Übernahme des reaktiven Waffeneinstellungscodes in diese explizite Methode für festgelegte Waffen besteht also darin, dass wir wissen, dass hier mehr passiert , als nur den Waffenwert festzulegen. Übrigens, werd diesen Refresh los . Und wir können das sogar entfernen, aber hier an dieser Stelle ist es im Grunde nur eine reguläre Variable. Aber wir wollen nicht verheimlichen, dass es Signale verbindet und trennt und die Benutzeroberfläche aktualisiert Kann etwas expliziter werden. Also der ganze Code hätte genauso gut unter dem Waffenvariablen-Setter stehen können, aber wenn wir diese große Blockfunktion geschrieben haben , wird uns mehr klar, was unsere Absicht ist Und ich weiß, dass mir das irgendwie widerspricht, als ich vorher gesagt habe, okay, du kannst einfach den Waffen-Setter machen und den Refresh benutzen Aber weil wir auch Signale machen, denke ich, dass einfach zu viel Zeug passiert, und das wollen wir niemandem vorenthalten, der versucht, das Display einzurichten Wir wollen, dass sie wissen, okay, da ist diese große Setwaffen-Funktion. Und das ist der Umgang mit all diesen zusätzlichen Dingen. Oh, richtig. Also lass uns weitermachen und das Spiel starten und ich werde den Speer auf Level zwei hochstufen Ah, okay, Sie können also sehen, dass es noch einen Hinweis auf die Waffenvariable gab noch einen Hinweis auf die Waffenvariable , aber wir haben sie privat gemacht Also wollen wir einen Getter haben , um an die Waffe zu kommen , anstatt dort auf die private Variable zuzugreifen Lassen Sie mich einen Blick auf diese Funktion und sehen, ob wir sie überhaupt brauchen Okay, also da die Waffenansicht das Löschen der alten Displays übernimmt, müssen wir die Display-Punkt-Waffe durch die Display-Punkt-Git-Waffe ersetzen Lassen Sie uns also diese Funktion im Waffendisplay erstellen. Also Funktion hier, Git Waffe, die eine Waffe an D zurückgibt. Wir sagen einfach, wenn wir Waffe unterstreichen, geben wir Waffe mit Unterstrich zurück, sonst geben wir Null zurück Warum sollten Sie sich also die Mühe machen, diese Git-Waffenfunktion verwenden , wenn Sie einfach direkt von der Waffenvariablen ausgehen könnten der Waffenvariablen ausgehen Nun, wir haben diese Waffe privat gemacht , weil wir sichergehen wollen, dass wir alle Entwickler dazu ermutigen , die Funktion „Waffenset“ explizit zu verwenden. Und weil das eine private Variable ist, sollten wir nicht von außerhalb des Skripts darauf zugreifen. Dann brauchen wir also eine öffentliche Get Weapon-Funktion , um darauf zuzugreifen. Es geht also im Grunde um Kapselung und darum, andere Leute daran zu hindern , Dinge mit dem Drehbuch zu tun, die sie mit dem Drehbuch nicht tun sollten Auch hier ist der Unterstrich nur eine Praxis, um anzuzeigen, dass es eigentlich privat sein soll, aber GD Script hat nicht wirklich private oder public Sie können also nicht wirklich verhindern, dass jemand darauf zugreift. Sie können Ihre Absicht nur mit dem Unterstrich angeben. Okay, also lass uns das schließen und die Szene noch einmal laufen Ich werde unseren Speer aufrüsten. Und lass uns das Speer-Upgrade holen. Sie können also sehen, dass Spear genau dort und oben links auf Level zwei gegangen ist Natürlich ist diese Benutzeroberfläche zu klein, ich muss sie vergrößern Gehen wir also zum Gameplay-UI Canvas und ich werde hier klicken. Ich werde das Layout tatsächlich ändern und wir werden es zentrieren. Also, Anchors wird mittig oben sein, und dann möchte ich es von dort aus W verschieben, quasi hier drüben. Springt auch in die Szene mit der Waffenausstellung. Also, wenn ich hier transformiere, sehe ich eher aus wie 400 mal 75. Ich möchte sicherstellen, dass der Anker immer noch zentriert ist, also kann ich hier benutzerdefinierte Einstellungen vornehmen und dann zurück zur Mitte oben gehen, wo er neu zentriert wird Schauen wir uns den Gameplay-UI Canvas an. Okay, das ist immer noch gut. Ich werde von hier aus wieder in die Waffenausstellung springen. Und ich denke, die Hauptsache ist, dass wir nur sicherstellen müssen , dass bei jeder einzelnen Anzeige das Symbol auf eine Mindestgröße eingestellt ist. Wenn ich mir also die Waffenanzeige hier ansehe, nehmen wir die Mindestgröße und stellen sie her. Wir könnten sogar 96, 96 sagen. Wir machen es einfach groß und verkleinern es dann, wenn wir es brauchen Also das Textlabel hier, muss das auch größer sein ? Vielleicht tue ich das. Lassen Sie uns hier einfach die Schriftgröße überschreiben. Und ich mache es , sagen wir, auf 16. Okay, genau das ist es jetzt 32. Okay, also versuchen wir es mit 32. Verkleinern. Drücken wir auf Play. Wie sieht es im Moment in der Benutzeroberfläche aus? Okay, das ist viel besser. Also hole ich die andere Waffe. Wir haben unsere Sense. Also Speer, Sense eins Ich denke, die einzige andere Sache ist vielleicht ein kleiner Margenbehälter helfen würde Also schließe das Spiel und lass uns in der Waffenansicht, unserem Randcontainer, ein Thema überschreiben. Ich denke an Konstanten von zwei auf allen Seiten. Wir drücken auf Play. Lass es laufen. Und das hat nicht so viel geholfen. Lass uns vier Pixel auf allen Seiten machen, schätze ich, und dann auf Play klicken. Okay, das ist zumindest besser sichtbar. Ich mache sechs draus. Also sechs auf allen Seiten, das sollte reichen. Okay, also gehen wir in den Spielmodus. Okay, jetzt haben wir eine Art Barriere zwischen unserem einzelnen Container und der gesamten Waffenansicht. Und das sieht viel solider aus. Es zeigt also die Art der Waffe wir haben, und das Level der Waffe, und das ist wahrscheinlich der Großteil dessen, was wir tatsächlich zeigen müssen. Also ich denke, wir sind bereit , hierher zu gehen. Lass mich für lustige Leute aufsteigen. Lass uns Syth Level zwei holen. Ja, Syth steigt auch richtig auf. Das kümmert sich so ziemlich um die Einrichtung der Waffenansicht und voll damit, alle Signale verbunden zu haben, die Gegenstände zu korrigieren, sicherzustellen, dass sie eine Beschreibung und ein Symbol haben, und einfach diese übersichtliche Benutzeroberfläche zu haben, wo wir sehen können, was tatsächlich mit unserem Spieler vor sich geht 53. P52 Erstellen von Stat-Boosting-Elementen für Spieler-Upgrades: Da unser Levelsystem funktioniert und die Möglichkeit bietet, einen Waffengegenstand auszuwählen und unsere Waffenausstattung die Möglichkeit bietet, einen Waffengegenstand auszuwählen und mit einer neuen Waffe oder einem verbesserten Waffenlevel zu verbessern, wäre jetzt der perfekte Zeitpunkt, um die Möglichkeit hinzuzufügen, ein Upgrade einer neuen Waffe oder einem verbesserten Waffenlevel zu verbessern, wäre jetzt der perfekte Zeitpunkt, zu wählen, das nichts mit Waffen zu tun Zum Beispiel ein Gegenstand, der die Stufe erhöht und unsere HP beim Stufenaufstieg dauerhaft erhöht Und wir könnten es sogar zu einem Gegenstand machen , bei dem die seltene Chance besteht , Feinde fallen zu lassen, wenn wir wollen. In unserem Artikelordner, unten links, werde ich das erweitern und eine andere Art von Objekt erstellen. Ich werde hier mit der rechten Maustaste klicken und ein neues Skript erstellen. Und wir könnten das ein Stat Boost Item dotGD nennen. Dies wird von der Ressource ausgehen. Es ist also eine Art Definitionstyp. Und dann öffne ich das in unserem Stat-Boost-Objekt gebe ihm den Klassennamen Stat Boost-Gegenstand. Oh, und das bezieht sich tatsächlich auf die Basisklasse des Gegenstands, nicht auf die Ressource. Wenn wir uns also den Artikel ansehen, haben wir den Trapply und Can Apply Also lasst uns weitermachen und uns diese schnappen, weil wir sie in unseren Stat Booten implementieren müssen Also werde ich sie einfach hier einfügen. Also für kann ich mich bewerben, wir wollen überprüfen, ob das Ziel A einen Statistikblock hat und B. Hat dieser Statistikblock die Werte, die wir verbessern wollen? Wir könnten eine Menge verschiedener Klassen erstellen, zum Beispiel für einen Gegenstand, der die HP erhöht, oder einen Gegenstand, der die Abkühlzeit reduziert. Aber stattdessen werden wir das vereinfachen, indem wir einen Export-Var-Stat-Namen haben , der ein String-Name ist. Und das setzen wir standardmäßig auf nichts. Und dann ändern wir einen Export-Variablenwert , der ein Float ist. Und lassen Sie uns das auf 0,0 setzen. Also das Wichtigste zuerst, ich möchte den Spblock vom Player entfernen, falls er existiert Also werde ich sagen, dass var Stats ein Statistik-Controller ist, und wir werden das von ptarget dot get entfernen und wir werden den Statistiknamen als Eigenschaft bekommen Das kann also am Ende Null sein. Wenn stats also Null ist, wir hier false zurück. Eine andere Sache, die wir überprüfen möchten, ist die tatsächlich festgelegte Wertänderung. Wenn die Wertänderung also gleich 0,0 ist, werde ich eine Warnung ausgeben. Statistik kann nicht erhöht werden, wenn die Wertänderung auf 0,0 gesetzt ist , oder sagen wir, Prozent um etwas flexibler zu sein, und dann eine Änderung des Prozentwerts. Und wir geben hier Falsch zurück. Der Grund dafür ist, dass, wenn wir das Objekt nicht eingerichtet haben, es nichts bewirken wird , also überspringen wir es einfach, es anzuwenden, und wir werden eine Warnung veröffentlichen, damit wir wissen, dass es sich um ein Problem handelt , das wir beheben müssen , indem wir einfach die Wertänderungseigenschaft auf etwas anderes ändern. Es gibt keine Ready-Funktion , um diese Dinge zu überprüfen, wie es bei einem Knoten der Fall wäre , weil Ressourcen niemals bereit sind. Das scheint also ein guter Ort zu sein, um es abzulegen. Wir werden es einfach überprüfen, bevor wir uns bewerben. Andernfalls denke ich, dass wir den Wert „wahr“ zurückgeben können. Ich denke, das sind die beiden Hauptbestandteile, auf die wir achten Also, die andere Sache, bei der ich sichergehen wollte , war dieser Teil. Wir schauen also, ob die Statistik den Statistiknamen hat, also habe ich das falsch eingerichtet. Wir wollten sagen, ob Ptarget hier keine Statistiken bekommt. Also zuerst bekommen wir den Statistik-Controller und dann wollen wir überprüfen, ob Stats Dot G Stat Entspricht nicht Null. Wenn das gleich Null ist, geben wir Falsch zurück. Also stellen wir zuerst sicher, dass es einen Statistikblock hat, dann stellen wir sicher, dass es die Statistik hat, und dann stellen wir sicher, dass wir dieses Objekt tatsächlich richtig eingerichtet haben , um den Wert zu ändern. Okay, wenn wir das alles einmal bestanden haben, können wir es anwenden. Also hier unten möchte ich den Statistik-Controller noch einmal holen, also kopiere ich einfach und füge das von hier oben nach hier unten Wir holen uns den SATs-Controller und dann wollen wir den aktuellen Wert ermitteln und dann die Änderung zu diesem Wert hinzufügen Unser aktueller Wert entspricht also dem Punkt stats dot GET stat name, und dann nehmen wir diesen und erhöhen ihn. Nehmen wir an, unser neuer Wert entspricht dem aktuellen Wert zuzüglich der Wertänderung Und dann setzen wir diesen Wert auf die Sts. Also setzt Stats Dot den Statistiknamen auf den neuen Wert, und ich füge dort einen kleinen Tippfehler hinzu, also stelle sicher, dass diese Namen korrekt sind Und dann wollen wir true zurückgeben. Also können wir auch hier noch einmal nachschauen, nur um sicherzugehen, dass Statistiken tatsächlich noch gefunden werden. Wenn stats also Null ist, geben wir false zurück. Und vielleicht wollen wir hier tatsächlich einen Fehler, weil wir prüfen sollen, ob wir uns bewerben können, bevor wir ihn anwenden. Statistiken des Controllers für Push und Error konnten also nicht für das Ziel Prozent S, Prozent P gefunden werden . Also das wird den Knoten holen und ihn dort ersetzen. In Ordnung. Ja, also für Statistiken , die einen Namen bekommen, ändern wir das vorerst in einen Float. Der neue Wert ist ein Float, und wir setzen ihn auf den Statistikwert zurück. Nun, einige unserer Statistiken wie HP sind Ganzzahlen. Wenn wir das also auf dem Statistik-Controller wieder einstellen, wird es wieder in eine Ganzzahl umgewandelt und es wird unseren Float-Wert verlieren. Die Idee hier ist also, dass, wenn Sie eine Ganzzahl erhöhen wollen, dann stellen Sie einfach sicher, dass Sie im eigentlichen Statistik-Boost-Element Werte verwenden , die keine Dezimalzahlen sind. Es verliert also ein bisschen an Klarheit, da wir bei der Wertänderung nur ganze Zahlen und Floats gruppieren , aber es gibt uns die Flexibilität, die überwiegende Mehrheit unserer Statistiken in einer Klasse verwalten zu können, anstatt eine für die Änderung der unserer Statistiken in einer Klasse verwalten zu können, anstatt eine HP, eine für die Erhöhung des Schadens in Prozent usw. zu erstellen . Nur viel weniger Skripte, in denen Dinge schief gehen könnten. Lassen Sie uns also unseren HP-Boost-Artikel erstellen. Und im Artikelordner unten links werde ich eine neue Ressource erstellen, es sich um ein SAT-Boost-Objekt handeln wird. Das wird also in demselben Ordner gespeichert. Ich nenne es HP Boost, unterstreiche die Punkte und speichere es Jetzt haben wir auf der rechten Seite unseren SAT-Boost-Artikel. Der SAT, den wir ändern wollen, wird also Max HP sein, und wir würden wollen, dass dieser Wert um 50 steigt. Nun, ich sehe hier einen Fehler, nämlich dass, wenn wir die MX-HP erhöhen, das nicht auch die Basis-HP erhöht Also müssen wir eine Entscheidung darüber treffen , wie wir damit umgehen wollen Eine Möglichkeit wäre, dass wir jedes Mal, wenn wir die MAX HP erhöhen, die HP in unserem Stack-Controller-Skript automatisch um diesen Betrag anpassen . Das ist also eine Option. Lassen Sie mich den SC-Controller überprüfen , ob das Sinn macht. Suchen Sie also nach dem Stack-Controller-Punkt gD und dem Projekt, öffnen Sie das und wir können sehen, dass wir das MAX-HP-Ding haben. Wir können also die Änderung sehen, indem wir den MAXHP minus den berechnen und wir könnten hier einfach sagen, wenn die Änderung positiv ist, dann beeinflussen wir die HP Ich habe jedoch das Gefühl, dass sich dieser Setter dadurch langsam verklumpt, und vielleicht gibt es tatsächlich einige Dinge, bei denen wir die maximalen HP ändern möchten, aber nicht die Basis-HP aber nicht die Ich denke, ein etwas besserer Weg das zu tun, wäre unser Stat-Boost-Item Wir haben tatsächlich ein Wörterbuch Statistiken, die wir ändern möchten, und dann gehen wir sie durch Auf diese Weise können wir MaxHP und HP gleichzeitig ausführen. Wir könnten sogar einen Gegenstand haben, der, sagen wir, Max HP, HP und Angriff auf einmal erhöht sagen wir, Max HP, HP , und das würde nur ein bisschen vier Schleifen erfordern ein bisschen vier Also lassen Sie uns das ändern, machen wir es zu einem Export var Stat changes Und das wird ein Wörterbuch mit Zeichenkettennamen und den Float-Werten sein. Okay? Also werden wir das jetzt loswerden, und das wird uns sofort einige Fehler bescheren. Also wollen wir sicherstellen, dass jeder dieser String-Namen im Stat-Controller existiert. Wir könnten also sagen, dass vier Schlüssel in Stat die Punkttasten ändern. Wir werden einfach überprüfen, ob sich der Schlüssel tatsächlich in diesem Controller befindet . Wenn der Git-Schlüssel für Statistiken also Null ist, hat er keine Statistiken, wir können ihn nicht ändern, das ist ein Problem. Und dann können wir es einfach hier unten machen. Denn der Wert in Stat ändert die Punktwerte. Dann werden wir prüfen, ob der Wert gleich Null ist, dann werden wir dieses Problem haben, also ersetzen Sie diese einfach durch Werte. Okay, technisch gesehen machen wir hier zwei Loops, und das ist suboptimal. Ein besserer Weg, das zu tun, wäre also , einfach den Wert aus dem Schlüssel zu ziehen. Ich würde also sagen, dass der Wert var gleich der Taste Stat Changes Punkt G ist, und dann können wir den Wert ohne die zusätzlichen vier Schleifen überprüfen . Also schneide ich das aus und füge es hier ein, entferne die zweiten vier Schleifen. Das sollte es viel effizienter und leichter lesbar machen , denn jetzt haben wir es nur mit diesen 14 zu tun. Okay, jetzt hier unten müssen wir etwas Ähnliches für die Punkttasten bei Änderungen von Statistiken tun . Wir müssen den Wert für jeden dieser Werte ermitteln. Lassen Sie uns das mit einem Tabulator übergehen, sodass es Teil der Viererschleife ist. Und wir sagen Statistiken Punkt Get Key. Es wird uns den aktuellen Wert geben. Wir nehmen den aktuellen Wert plus die Wertänderung. Das gibt uns den neuen Wert. Woher bekommen wir also die Wertänderung? Nun, wir müssen sagen, dass die Änderung des Var-Werts unverändert ist, was den Änderungen an den Werten entspricht . Punkt Get key. Äh, hm Und dann haben wir den neuen Wert, wenn wir diese zusammenzählen , die Statistiken sind gesetzt Was den neuen Wert angeht, warte mal. Der Satzname ist nicht im Bereich deklariert , da der Satzname der Schlüssel ist. Also wollen wir den Schlüssel mit dem neuen Wert auf dem Statistik-Controller setzen . Okay. Lassen Sie uns nun einen Artikel im Projekt suchen. Ich öffne den HP Boost-Artikel. Jetzt haben wir die Möglichkeit, mehrere Statistikänderungen auf einmal vorzunehmen. Also mache ich einfach MaxHP und das sind 50. Ich möchte MXHP vor HP machen, weil ich die MX HP erhöhen möchte, bevor ich versuche, die HP zu erhöhen Also die HP wird auch hier 50 sein. Also erhöhen wir die MX HP, und dann werden die HP um 50 steigen. Wenn du bei FHP bist, sollte es ein zweites Mal bei FHP sein. Und dann nennen wir den Anzeigenamen hier HP Boost. Die Beschreibung wird die maximale HP um 50 erhöhen. Und dann lassen Sie uns für das Symbol eine neue Atlas-Textur erstellen. Ich werde das erweitern. Lass uns schnell aus unserem Projekt laden und ich hole mir das 16 mal 16 Sprite Sheet Lassen Sie uns also die Region bearbeiten und eine auswählen. Also zoomen Sie rein, haben wir so etwas wie einen Heiltrank, etwas, das für uns Sinn macht Da ist ein Blutstropfen , der lebensfähig sein könnte. Oder hier ist ein Herz. Das ist eine weitere gute Option. Okay, ich mag dieses Mehl irgendwie. Holen wir uns also dieses karmesinrote, blutrote Mehl und wählen es so aus, dass es unser Gegenstandssymbol sein kann Und lasst uns das testen, indem wir es als Option in unserer Spieler-Level-Up-Szene In der Level-Up-Auswahlszene klicke ich also auf unsere LevelUp-Auswahl Und wir haben hier unsere Artikelauswahl. Ich werde schnell einen neuen Artikel laden. Das wird also unser HP-Boost-Artikel sein. Wir geben ihm eine Drop-Chance von eins und klicken auf Schlüsselwertpaar hinzufügen. Okay, jetzt können wir auf Play klicken und wir gehen hier rein. Ich steige auf und wir wählen unseren HP-Boost. Wähle das und du kannst sehen, oh, plötzlich haben wir 160 HP, und so steigt man auf. Ihr könnt also von hier aus sehen, dass es sehr einfach wäre , andere Werte wie Angriffsschaden, Reduzierung der Abkühlzeit, was sonst noch zu erhöhen ? Bewegungsgeschwindigkeit usw. für deinen Charakter, da du Upgrades vornehmen musst 54. P53 Implementieren von HP Boost Pickups und Level Up UI-Korrekturen: Schließen Sie unser Upgrade-System indem Sie eine Abholung einrichten , die es uns ermöglicht , einen dieser Artikel abzuholen und sofort anzubringen , z. B. unseren HP Boost-Artikel Also werden wir unser Projekt nach den Pickups durchsuchen wollen unser Projekt nach den Pickups Wir haben also unsere Objekt-Pickups. Lassen Sie uns einen HP-Boost-Pickup erstellen. Duplizieren Sie zunächst die XP Pickup Two D-Szene. Also klicke ich mit der rechten Maustaste und dupliziere das und dann ist das HP Boost Pickup, unterstreiche zwei D, klar, und doppelklicke darauf und doppelklicke Okay, als Erstes möchte ich hier das Sprite so ändern, dass es das gleiche wie auf meinem Also werde ich auf Animated Sprite TwoD klicken. Gehen wir hier zur Animation und erstellen eine neue Sprite-Frames-Ressource , damit wir ein anderes Symbol festlegen können Ich füge Frames aus einem Spritesheet hinzu. Lass uns in die Kunst gehen. Keine purpurrote Fanta, siehe Raben-Symbole, ganzes Spritesheet, 16 mal 16, heranzoomen Achten Sie darauf, dass Sie auf der rechten Seite die Größe auf 16 mal 16 einstellen, damit das Spritesheet aufgeteilt werden kann Und ja, wir werden die Blume finden, die ich benutzt habe. Also klicken Sie darauf, fügen Sie den Rahmen hinzu. Und bumm, da ist unser Artikel. Ich kann mir den XP-Pickup ansehen, aber das ist eigentlich nur ein Pickup , das sofort Erfahrung bringt. Dieses Skript überspringt also tatsächlich die gesamte Notwendigkeit , das Objekt zu haben Was wir also suchen, ist eher eine Artikelabholung zwei D. Also benennen wir unseren Basisknoten um, Artikelabholung D, und wir klicken mit der rechten Maustaste darauf, trennen das Skript, klicken mit der rechten Maustaste auf ein neues Skript anhängen, und das wird ein Elementunterstrich Abholung sein, zwei D, das wird sich von Abholung bis D erstrecken. Wir erstellen das, geben ihm den Klassennamen item two D. Das wird also zutreffen. vom Abholartikel zu dem Objekt, das ihn abgeholt hat. In der Level-Benutzeroberfläche haben wir den Gegenstand also sofort auf unseren Spieler angewendet. Hier ist es nur ein bisschen anders. Wir müssen den Gegenstand zuerst auf der Spielkarte aufheben, zum Beispiel das EXB und dann wird der Gegenstandseffekt direkt auf den Spieler angewendet Wenn wir Gegenstände zu einem Inventar hinzufügen, wäre diese Methode des Anwendens eher so, als würden wir einen Gegenstand zur Inventaranordnung hinzufügen und von dort aus weitermachen, aber unser Spiel benötigt keine Inventare, also überspringen wir im Grunde genommen Aber unser Spiel benötigt nicht wirklich Inventare, abgesehen von unserer Waffenausstattung, die ein bisschen anders funktioniert Also müssen wir uns für dieses Projekt nicht wirklich darauf einlassen Also unser Artikel Pickup two D, wir wollen natürlich ein Objekt vom Typ Artikel exportieren. Okay? Also speichern wir das, und dann können wir hier klicken und es zuweisen, wenn wir wollen, können wir das Standardelement zuweisen. Vielleicht lasse ich das aber einfach leer. Lassen Sie mich einen Blick auf das Basis-Pickup-Two-D-Skript werfen. Klicken Sie mit der rechten Maustaste hinein. Also müssen wir die Take-Funktion implementieren. Also lassen Sie uns das in Item Pickup Two D kopieren . Ich füge das ein. Wir werden es in einer Sekunde implementieren. Ich mache auch die Funktion underscore ready, gibt void zurück Und wir werden behaupten, dass der Artikel nicht Null ist. Jeder Abholung eines Artikels muss ein Artikel zugewiesen sein, der abgeholt werden kann. Eigentlich finde ich, dass Assert hier etwas zu stark ist. Ich würde mich wahrscheinlich eher für einen Push-Fehler entscheiden. Wir können also sehen, was in der Konsole schief läuft, aber das wird den Spielfluss nicht unterbrechen , denn wenn wir die Abholung von Gegenständen instanziieren, wird sie wahrscheinlich aus dem Drop kommen, und wir wollen nicht unbedingt, dass das den Ablauf unserer Spieletests komplett unterbricht Ich denke also, dass ein Push-Fehler hier etwas besser geeignet ist. Also, wir werden den Unterstrich vom P-Ziel entfernen Also werde ich zuerst sagen, dass ich Punkt Punkt auf das P-Ziel anwenden kann, dann werde ich es auf das P-Ziel anwenden Versuchen Sie also, Item Dot auf pTarget anzuwenden. Und wenn das passiert, werde ich es aus dem Szenenviertel entfernen Nun, vielleicht wäre es besser, wenn die T-Funktion auch einen booleschen Wert hätte, der falsch zurückgibt Hier bedeutet die Art, dies in einen Booleschen Wert zu ändern , dass es zur Basisklasse zurückkehren und diese ändern müsste Basisklasse zurückkehren Und dann müsste jede Klasse, die auch die T-Funktion überschreibt, sie ändern Das ist also einer der Fehler, wenn Sie für Ihre Klassen zu sehr von der Vererbung abhängig sind, anstatt einen Kompositionsansatz zu verwenden, wie Sie es gerade im Inspektor sehen. Komposition wäre eher so, als hätten Sie eine Menge verschiedener kleiner Skripte, die jeweils ihren eigenen Zweck haben, anstatt dass jeweils ihren eigenen Zweck haben, ein Basisskript eine Reihe anderer Skripten erweitert Zum Beispiel könnte der Spieler einen erweiterten Charakter haben, und dann könnte es eine andere Klasse dem Spieler überlegen ist, wie Spearman oder Dragoon, was dem noch mehr Dinge hinzufügt. Aber wenn Sie dann viele Skripte erhalten direkt voneinander abhängen, kann eine kleine Änderung, wie die bloße Änderung in einen Booleschen Wert, bedeuten , dass Sie es an mehreren Stellen aktualisieren müssen , die direkt voneinander abhängen, kann eine kleine Änderung, wie die bloße Änderung in einen Booleschen Wert, bedeuten, dass Sie es an mehreren Stellen aktualisieren müssen. Also nur etwas zum Nachdenken Nicht wirklich so problematisch hier. Okay, also was wir mit diesem Gegenstand machen werden, ist ihn jetzt auf der Spielkarte zu platzieren. Also HP Boost Pickup. Das haben wir. Das haben wir für das Projekt gespeichert. Oh, wirklich, ich glaube, ich möchte das zu einer Basisszene machen, also werde ich sie in Item Pickup Two D umbenennen . Lassen Sie uns nun hier unten nach Tonabnehmern suchen Also klicke ich mit der rechten Maustaste hier und mache eine neue geerbte Szene Und dann kann ich in dieser geerbten Szene das Objekt zuweisen. Ich lade also schnell unseren HP Boost-Artikel und speichere ihn dann wieder bei der Artikelabholung als HP Boost-Pickup ab. Zwei D. Und dann ist das die Szene, die wir in die Spielwelt eingebaut haben. In gewisser Weise ist das Erstellen einer solchen vererbten Szene wirklich vergleichbar Erweiterung eines Skripts und der Übernahme der gesamten Basis in Ihr neues Objekt. Aber unter bestimmten Umständen wie diesen, wo wir einfach ändern, welche Art von Gegenstand Szenenkonfiguration hat, die HP-Boost-Aufnahme hat, die HP-Boost-Komponente hat, aber ansonsten nur eine normale Gegenstandspickup zwei D ist. Ich denke, in solchen Fällen macht das tatsächlich eine Menge Sinn. Also wollen wir unseren Gegenstand jetzt in die Spielwelt bringen. Ich werde nach World Dot TCN suchen. Okay, ich zoome hier rein. Wir haben dort einen Spieler, also werde ich nach dem HP Boost-Pickup suchen und versuchen , ihn in die Spielwelt zu ziehen. Ich könnte es einfach da reinlegen, aber lass es uns zuerst unter Pickups platzieren , damit es das richtige übergeordnete W hat, um es zu bewegen Lass es uns da drüben hinstellen und vielleicht noch ein zweites hier drüben, nur um sicherzugehen, dass wir es zweimal machen können Drücken wir auf Play und dann holen wir unsere Abholung ab. Also werde ich hier rübergehen und bumm, wir haben 150 PS. Hier können wir wählen, ob wir Speer oder Sense wollen. Interessanterweise bietet es keine Option für die dritte Abholung Vielleicht muss ich hinzugefügt werden. Und dann gehe ich hierher und hole mir unseren nächsten HP-Boost. Da ist also unser permanenter SP-Boosting-Gegenstand, und der funktioniert ein bisschen anders als unser EXP , der den Stich nur direkt verändert Schauen wir uns also die Level-Up-Auswahl an und ich werde nur sichergehen, dass der Gegenstand noch da ist Irgendwie hat es angefangen, also werde ich schnell den HP-Boost-Artikelwert von eins laden , hinzugefügt. Also drücken wir jetzt noch einmal auf Play. Ich werde nur sichergehen, dass es wieder funktioniert. Holen Sie sich den HP-Boost von der Stufe höher, wählen Sie das aus. HP steigt, wir wählen hier und hier aus, sodass wir drei HP-Boosts erhalten Das funktioniert gut. Das Letzte, was ich ändern möchte, und das ist schnell, ist, dass unsere Prämienboxen nicht auf dieselbe Größe herunterskaliert werden Wenn eine von ihnen eine längere Beschreibung hat. Also möchte ich in die Szene mit der Belohnungsauswahl springen. Klicke auf die Wurzel und lass es mich hier sehen. Eines davon muss vollständig erweitert werden. Der schnellste Weg, dies zu debuggen, wäre also , auf Play zu klicken Und während das Spiel läuft, gehe ich hier rüber und wir werden testen, die Größe hier ändern Und dann gehe ich zurück und schaue, ob es aktualisiert wurde. Okay, also unser HP-Boost-Bereich, lass mich das Root überprüfen. Das ist so eingestellt, dass es gefüllt und erweitert wird. Vielleicht ist es die Beschreibung , die erweitert und erweitert werden muss. Wir können also sehen, dass die Wurzel hier bereits erweitert und gefüllt ist. Also werde ich den Margin-Container überprüfen und sicherstellen, dass er auch so ist. Also werden wir die Größe des Layout-Containers bestimmen. Füllen. Okay, noch etwas, das ich mir in der Fernansicht ansehen könnte, um die Notizen zu sehen , die gerade im Spiel laufen. Und lassen Sie uns die Ebene World Canvas bis zur Benutzeroberfläche erweitern. Wir haben die Ebene der Auswahl. Darunter befindet sich unser Panel-Container, der Margin-Container, der V-Box-Container und der Rewards-Box-Container sowie unsere drei Auswahlmöglichkeiten Warum sind diese dann unterschiedlich groß? Wir können also sehen, wenn wir hier rechts drüben nachschauen , dass die Größen für das Y alle gleich sind. Das würden wir erwarten, wenn wir uns das ansehen. Die sind alle ganz nach unten gestreckt . Finden wir also die Ebene, auf der sie sich nicht befinden. Der kleinste ist der dritte. Lassen Sie mich das erweitern. Klicken Sie auf Margin Container. Wir können den Margin-Container sehen. Sind die 20 Pixel in voller Größe, das ist es also nicht. Gehen wir runter zum VBox-Container. Der VBox-Container ist 214. Das würden wir auch erwarten, da der Margin-Container eine Marge hat Ich denke also, es ist tatsächlich dieses Beschreibungsfeld. Sie können auf die Knoten klicken und tatsächlich ein Feld sehen , wenn es hier ausgewählt ist. Das ist irgendwie cool. Ich denke, das könnte tatsächlich neu sein. Wir wollen also nur , dass die Beschreibung alles ganz nach unten schiebt. Okay, wir wissen also, was wir erweitern wollen. Also, in der lokalen Ansicht, jetzt hier oben links, klicken wir auf Beschreibung. Ah, und los geht's. Da haben wir's. Da unten, was die Größe von Containern angeht, ist es so eingestellt, dass das Schrumpfen beginnt Ich möchte, dass das tatsächlich gefüllt und erweitert wird. Wenn ich jetzt zurück zum Spiel tippe, geht es ganz nach unten. Okay, du kannst das also sehen, oder? Diese drei werden untergehen. Ich möchte auch, dass die Größen der Symbole gleich sind. Vielleicht müssen wir also eine bestimmte absolute Größe für die Symbole festlegen . Ich denke, vielleicht wurde für das Speersymbol ein größeres verwendet, aber ich möchte sichergehen, dass sie alle die richtige Größe Wenn wir hier also auf das Symbol Rec klicken, versuchen wir, die Größe behalten so zu ändern, dass die Größe ignoriert Und ich denke, das macht sie jetzt gleichwertig. Ja, okay. Ja, es scheint in einer Reihe zu stehen. Wenn Sie andere Probleme haben, wäre das eine Art Debugging-Prozess , mit dem Sie Ihre Benutzeroberfläche reparieren können , während das Spiel tatsächlich läuft Es ist also ziemlich hilfreich, weil Sie sehen können , wie es sofort aktualisiert wird . Sie können Ihre Steuerung innerhalb von Gado und Ihrer lokalen Szene ändern , und es wird sofort in der Remote-Ansicht aktualisiert Das ist also eines der wirklich coolen Dinge an Gudo Okay, also ich denke, dass unsere Upgrade-System-Pickups, alles, was wir in dieser Hinsicht brauchen, jetzt wirklich gut funktionieren Also das ist wirklich der Großteil des Kurses bis zu diesem Zeitpunkt Wir werden nur einige ausgefeilte Dinge durchgehen müssen , wie das Speichern und Laden eines Punktesystems, zum Beispiel, wie viele Gegner wir zwischen den Spielsitzungen getötet haben, und ein Spiel über dem Bildschirm anzeigen , wenn wir tatsächlich verlieren Also können wir in unser Hauptmenü gehen und das Spiel neu starten , solche Sachen Aber das Kern-Gameplay ist jetzt so ziemlich da. Das wird es also für dieses Video sein, und dann werden wir mit der abschließenden und polierten Phase des Kurses beginnen. 55. P54 Einen Heiltrankaufnehmer für feindliche Tropfen erstellen: Ich möchte noch ein Video darüber aufnehmen , wie du deine Spielgegenstände in Gudo abholst Also habe ich den Gegenstand Pickup for HP Boost erstellt, aber ich möchte einen Gegenstand erstellen von den Feinden fallen gelassen wird Das wird nur ein einfacher Gesundheitstrank sein. Also suche ich im Projekt nach unserem HP-Boost-Objekt und lass uns den HP-Boost-Pickup duplizieren Also klicken Sie mit der rechten Maustaste und gehen Sie runter zu Duplizieren und wir nennen es Health Potion. Zwei Punkte TCN. Jetzt wollen wir diese Szene öffnen, Health Potion sagte Punkt tSCN Unser Gegenstand hier wird also Health Potion Two D heißen, nur um anzudeuten, dass er sich auf der Two-D-Spielwelt Für das HP Broca-Objekt auf der rechten Seite klicken wir auf das Drop-down-Menü und machen es dann einzigartig Also nehmen wir im Grunde die Basis und erstellen eine einzigartige Kopie davon, und jetzt werde ich hier mit der rechten Maustaste klicken und sie als Heiltrank speichern Also klicken Sie mit der rechten Maustaste auf Speichern unter und fügen Sie es dann dem Projekt und den Objekten hinzu, und ich mache Gesundheitstrank Unterstreichen Sie das Element TRS. Lassen Sie uns die Änderungen an den Statistiken so ändern , dass sie nur die HP um 25 erhöhen, und lassen Sie uns die maximale HP aus diesem Boost entfernen Nun zu unserem Anzeigenamen, ich sage Gesundheitstrank. Und zur Beschreibung sage ich: Stellt 25 HP wieder her, Punkt Und dann wählen wir für das Symbol ein anderes Symbol aus unserer Region aus und suchen uns einen Heiltrank. Ich bin mir sicher, dass es hier ein paar davon gibt. Also ja, näher an der Spitze haben wir mehr als ein paar. Treffen Sie hier wirklich Ihre Wahl. Ich nehme den typisch aussehenden. Und lassen Sie uns das auswählen. Und dann müssen wir uns auch das gleiche Symbol für das animierte Sprite Two D holen . Also klicken Sie dort, gehen Sie zur Animation, erstellen Sie neue Sprite-Frames und wählen Sie dann aus den Frames eine Auswahl Kunst-Symbole, vollständiges Spritesheet 16 mal 16, vergrößern Sie die obere eingestellte Größe auf Und dann steuere die mittlere Mauswalze, zoomt nach oben und schnappt euch den gleichen Heiltrank , der genau hier ist Es sollte nur einer ausgewählt werden. Klicken Sie auf Hinzufügen. Okay, und da ist unser Gesundheitstrank. Also das sollte schon funktionieren können. Lass es mich als Kopie in die Spielwelt werfen. Wir haben also unseren Heiltrank zwei D. Ich lege ihn für den Moment hier rein, und dann können wir einfach den Heiltrank verwenden Also, die Grundgesundheit beginnt eigentlich bei 50. Also, wenn ich hier rübergehe, können Sie sehen, dass 50 zu 75 von 100 wird . Also das funktioniert. Okay, dann müssen wir in die Skeleton-Szene gehen und unsere Drops-Komponente modifizieren, aber wir haben eigentlich nie einen Drops für das Skelett eingerichtet . Also lass uns zu Oc gehen. Ich wähle es einfach hier aus und drücke C, kopiere es auf das Skelett. Dann haben wir oben rechts unsere Drop-Definitionen, was bereits den EXP-Drop mit einer Gewichtung von 1,0 Deshalb wollen wir die Möglichkeit hinzufügen, manchmal einen HP-Trank anstelle der EXP fallen einen HP-Trank anstelle der Ich füge ein Element hinzu und klicke auf eine neue Drop-Definition Dann, nur zu Testzwecken, gebe ich ihm fünf Tropfen Gewicht, was bedeutet, dass es in 86% der Fälle einen Heiltrank und keine EXP abgibt, nur damit Sie sehen können, wie es funktioniert Und dann laden wir schnell unseren Heiltrank zwei D. Okay, für unsere Tropfen, die tatsächlich wirken, müssen wir sie auch als Aufruf zu unserer Todesanimation hinzufügen Klicken wir also auf den Animations-Player, gehen wir zu Death und wir werden hier einen Call für Drops machen Lassen Sie uns also zu Beginn eine Aufrufmethode für Drops hinzufügen. Und wir klicken mit der rechten Maustaste und fügen einen Schlüssel ein, um Drops mit einem Mal einzufügen. Das ist in Ordnung. Abholung des Artikels habe ich noch einen Fehler gemacht . Wenn wir den Fehler für den Artikel drücken, ist der Fehler nicht Null. Wenn der Wert Null ist, sollte das eigentlich Push sein, weil wir versuchen zu überprüfen , ob wir tatsächlich daran gedacht haben, bei der Artikelabholung einen Exportartikel anzugeben. Das war eine einfache Umkehrung der Logik. Okay, jetzt lass uns weitermachen und auf Play klicken und wir werden versuchen, ein Skelett zu besiegen Ich sammle hier einfach ein paar Gegenstände in XP, hole mir die Seite. Und wir warten einfach darauf, dass ein Skelett auftaucht. In der Zwischenzeit können wir sehen, dass die Kugeln immer noch einfach ihre XP verlieren Das ist immer der einzig mögliche Verlust, und da haben wir ein Skelett Wenn wir diesen Kerl also in etwa 86% der Fälle besiegen , sollte er einen Heiltrank fallen lassen Also dieses Mal nicht. Wir müssen noch ein paar besiegen. Und lass uns sehen. Bringen wir den Heiltrank zum Spawnen Ja, da haben wir's. Gesundheitstrank Wir haben also tatsächlich gesehen, dass beide spawnen können. Ein weiterer Heiltrank kam aus dem Skelett , ein weiterer Heiltrank Ihr könnt also sehen, dass die Gewichtung den allermeisten Fällen definitiv funktioniert wenn wir den Heiltrank statt der EP bekommen Heiltrank statt Jetzt, wo wir wissen, dass es funktioniert, können wir einfach zum Skelett übergehen Wir gehen zu Drops. Nehmen wir die Tropfendefinition für den Trank und machen daraus 0,1 Das bedeutet also, dass zehn von 11 mal die EP fallen, und eines von elf Mal wird der Heiltrank fallen, und so funktioniert die Gewichtung Sie addieren alle Möglichkeiten plus ihre Gewichte und Ihre Chancen sind Ihr Gewicht für diese bestimmte Möglichkeit geteilt durch das Gesamtgewicht aller Okay, und so fügt man dem Spiel so ziemlich einen Gesundheitstrank hinzu Ihr könnt also sehen, dass es wirklich einfach wird, viele verschiedene Dinge an unserem Charakter zu ändern , sobald wir unseren Statistikgegenstand haben , unsere Pickups, die uns einen Statistikgegenstand geben , und wir können sie einfach auf den Spieler anwenden und wir können einfach als Zeichenkette angeben, welche Statistik wir beeinflussen und wir können einfach , und wir können sie einfach auf 56. P55 Implementieren von Kameraverschüttelung für Spielerschlag- und Todeseffekte: Wir kommen jetzt zum ausgefeilten Teil des Kurses, dem wir zum Abschluss noch ein in dem wir zum Abschluss noch ein paar nette Hälften hinzufügen Wir beginnen mit einem Kamerawackeln bei einem Treffer für unseren Spieler, um das Spiel etwas intensiver zu gestalten Und wir werden auch Dinge wie das Hinzufügen eines Spiels über den Bildschirm und die Möglichkeit bieten, Highscores zu verfolgen. Fangen wir also mit dem Verwacken der Kamera an. Lass uns in die Welt gehen. Und auf der Welt haben wir hier eine Zwei-D-Kamera. Also könnten wir einfach ein Drehbuch direkt an Kamera zwei D anhängen . Also werde ich hier klicken, ein Skript anhängen und sagen wir Kamera zwei D schütteln D. Unterstrich zwei D, sollte ich sagen Und wir werden es erstellen und wir werden es, glaube ich, in den UI-Ordner legen glaube ich, in den UI-Ordner Also öffne das und erstelle. Ich gebe ihm den Klassennamen Shake Camera Two D. Und lass uns daran arbeiten, das einzurichten. Zunächst benötigen wir also, wie viele andere Skripte, einen Verweis auf unseren Spieler , damit wir, wenn der Spieler Schaden erleidet, den Shake-Effekt auslösen können. Lassen Sie uns also den Var-Kontext des Spielerkontextes exportieren. Also, genau wie zuvor bei anderen UI-Elementen, erhalten wir über den Kontext Zugriff auf die Statistiken. Und dann fügen wir einige Variablen , um unsere Shake-Stärke zu steuern. Exportieren Sie also zunächst var Max Shake Strength, was ein Float ist, und ich setze das standardmäßig auf 10.0. Wir können auch eine Shake-Dauer angeben. Exportieren Sie also var shake duration, was ein Float ist, und wir setzen diesen Wert standardmäßig auf 0,3 Sekunden. Und dann möchte ich einen separaten Satz von Variablen für den Fall, dass der Charakter stirbt. Das sollte also ein extra starker Shake sein um den Eindruck zu erwecken , du hast deinen Spieler verloren, du hast das Spiel verloren. Also machen wir Export Var Death Shake Strength und das wird ein Float-Up-Standard auf 20,0 sein Und dann haben wir bei Export Var die Deathshake-Dauer, die ich standardmäßig auf einen Float von 0,6 Sekunden setze Wenn unser Skript startet, möchte ich also die Statistiken des Spielers abrufen. Also werde ich sagen, dass var underscore stats hier ein Statistik-Controller sein wird, und dann brauchen wir die Funktion Underscore bereit Also sagen wir Context Player Dot Stats und wir werden die Underscore-Statistiken entsprechend setzen. Lassen Sie uns annehmen, dass das nicht Null ist. G-Statistiken sind nicht gleich Null. Muss einen Bezug zu den Spielerstatistiken haben , damit die Kamera wackelt. Okay, also wenn unsere Kamera überall wackelt, wollen wir uns ihre ursprüngliche Position merken , damit wir, wenn wir fertig sind, zu dieser Position zurückkehren können Lassen Sie uns hier eine weitere Variable haben. Dies wird ein Vektor zwei D sein, ursprünglichen Offset unterstreicht, was ein Vektor 20 sein wird Okay, denk an das Gleichheitszeichen. Wir schließen also, dass es sich um einen Vektor aus Vektor zwei Punkt Null handelt, und das macht ihn auch zu einem Vektor 20. Okay, unser ursprünglicher Offset bei Ready wird also unserem aktuellen Offset entsprechen Das ist also der Offset der Kamera, weil unser Skript diese Kamera direkt erweitert. Und dann müssen wir eine Verbindung zum Statistikcontroller herstellen, das HP Signal geändert hat. Unterstreichen Sie also die Statistiken, die HP gehängt hat, Punkt Connect. Und wir werden eine Verbindung herstellen , mit der wir das verbinden werden , wenn HP geändert Also lassen Sie uns die Funktion hier unten erstellen, Unterstrich auf HP geändert haben, und das wird die Statistikdaten haben Also P-Daten und das sind statistisch geänderte Daten. Dieses Mal, wenn wir unsere Callback-Funktion haben, werde ich die P-Daten direkt verwenden , weil sie hier sehr nützlich sind, um festzustellen, ob wir einen normalen Shake oder einen Deathshake machen Wenn die HP-Änderung bei dem Ereignis also größer oder gleich Null ist, wollen wir einfach zurückkehren, weil wir bei einer Heilung nicht zittern oder wenn sich die HP nicht ändert Jetzt wollen wir also überprüfen, ob der Punkt-U-Wert für das Ereignis größer als Zarel ist Ist der Charakter also im Grunde noch am Leben? Also, wenn das der Fall ist, dann werden wir die normalen Shake-Werte verwenden. Andernfalls verwenden wir den Death-Shake-Wert. Stärke des Underscore-Shakes entspricht also unserer maximalen Shake-Stärke, und dann entspricht die Underscore-Shake-Zeit unserem Halten Unsere Shake-Dauer. Okay, also wir brauchen diese lokalen Variablen hier oben. Also var unterstreicht Shake Strength ist ein Float und Var unterstreicht Shake Time ist auch ein Natürlich wird die Standardeinstellung auf Null gesetzt. Oh, und als ich Event hier einfügte, meinte ich eigentlich Pdta Also pata dot change und pdata dot neu. Okay, ansonsten gibt es hier noch einen anderen Fall, nämlich dass der Gesundheitszustand unter Null oder gleich oder unter Null liegt , sollte ich sagen In diesem Fall setzen wir die Shake-Stärke auf die Todeswerte. Stärke des Underscore-Shakes entspricht also der Stärke des Death-Shakes und die Shake-Zeit entspricht der Dauer des Death-Shakes Okay, hier gibt es noch eine weitere Sache: Je nachdem , wie gesund unser Charakter ist, möchten wir vielleicht die Stärke erhöhen oder verringern Deshalb hatte ich hier MX Shake Strength. Im Moment wird es immer das Maximum von 10,0 sein, das ich dort eingerichtet habe. Ich denke, ein guter Weg, das zu tun, wäre zu überprüfen, wie viel Schaden du verursacht hast und hoch die maximalen HP des Charakters sind. Wenn also ein Angriff die Hälfte seiner Lebenspunkte zerstört , sollte das ein ziemlich starkes Kamerawackeln sein. Aber wenn es nur ein Häkchen mit Schaden über Zeit ist, also, oh, es fügt einen Schaden pro Sekunde zu, dann ist das ziemlich belanglos Du kannst das einfach zu einem sehr kleinen Shake machen oder den Shake ganz weglassen Also var, das Schadensverhältnis wird gleich dem absoluten Wert F des Ereignistunktes hg sein. Das ist die Menge an Lebenspunkten, die wir gerade geändert haben, und sie wird durch das Maximum eines Punktes geteilt , oh. Während der Bearbeitung habe ich festgestellt , dass die Mathematik hier falsch ist. Das Maximum zwischen einem Punkt oh und dem Statistikpunkt MX HP zu nennen oh und dem Statistikpunkt MX HP macht hier nicht viel Sinn, weil wir eigentlich wollen, dass das Verhältnis zwischen Veränderung und Gesundheit ist, der absolute Wert davon sowieso. Und der MX HP. Was wir also wirklich tun wollen, ist eine Veränderung in% zu sagen. Und was wir wirklich sagen wollen, ist der absolute Wert Float der p-Datenpunktänderung geteilt durch den Unterstrich Stats Dot MX HP Das gibt uns also unser Verhältnis, das zwischen 0 und 100 liegen sollte Aber wir wollen das eindämmen. Sagen wir jetzt also Clamped Ratio. Ich schneide das weg und sagen wir klammer F bei der prozentualen Veränderung, und wir werden es zwischen 0,0 und 1,0 erzwingen Wenn also aus irgendeinem Grund unser Änderungswert tatsächlich höher wäre als unsere gesamten MX-HP, sagen wir, wir haben 9.000 Schaden erlitten und unsere maximalen HP wären 100, dann wäre das tatsächlich eine prozentuale Veränderung von 90. Also wollen wir das einfach auf 100% begrenzen oder, wenn wir in die andere Richtung gehen, darf es nicht unter 0% liegen. Unser Gesamtwert wird also bei 0-100 liegen, egal wie groß oder klein die Änderung war Multiplizieren Sie die maximale Schüttelstärke mit dem Verhältnis der Klemmung. Das Letzte, was wir hier tun müssen , um sicherzugehen , dass das nicht zu Null zurückkehrt , ist, die MX HP zu nehmen und sie in einen Float umzuwandeln Das ist wichtig, denn andernfalls würde eine Ganzzahl geteilt durch eine Ganzzahl einfach das Dezimaltrennzeichen fallen lassen , bevor wir sie überhaupt in eine prozentuale Änderung umrechnen. Jetzt können wir losrennen und sichergehen , dass es immer noch wie erwartet funktioniert, also werde ich einen Typen finden, der uns schlägt. Okay, und der Bildschirm wackelt immer noch , oder? Natürlich wird der Todesfall viel größer sein. Weil wir die Mathematik geändert haben, möchtest du vielleicht auch die maximale Shake-Stärke anpassen die maximale Shake-Stärke und sie stärker machen, etwa 20 oder 30. Und denken Sie daran, dass dies immer ein Prozentsatz der maximalen Shake-Stärke sein wird . Sie müssen das also berücksichtigen, wenn Sie tatsächlich herausfinden, wie stark der Shake sein wird Also, mal sehen, bei 30 ist die maximale Stärke ungefähr so. Vielleicht ein bisschen stark. Vielleicht reduziere ich das sogar auf 20. Also eher eine endgültige Zahl. Okay, jetzt brauchen wir endlich den Prozess für den Shake. Also lass uns hier nach oben gehen. Wenn der Unterstrich fertig ist, sage ich, Funktion unterstreicht Prozess Delta Also fülle ich das einfach automatisch aus. Und dann sagen wir, wenn die Shake-Zeit größer als 0,0 ist, dann werden wir den Bildschirm tatsächlich schütteln Also, wie wir das machen, ist mit etwas Mathematik. Also sagen wir, Unterstrich, Shake, Unterstrichzeit ist minus gleich Delta Also entfernen wir die Zeit von der Zeit, die wir hier verstreichen, und dann berechne ich den Wert für X-Shake und Y-Shake und wende diesen Offset auf die Kamera Var Shake X entspricht also einem zufälligen F-Bereich negativen 1,0- bis 1,0-fachen der Shake-Stärke Im Wesentlichen erhalten wir also eine zufällige Richtung multipliziert mit unserer aktuellen Shake-Stärke Und dann var shake Y, du kannst dir natürlich vorstellen, dass das dasselbe ist Entspricht dem zufälligen F-Unterstrich-Bereich, negative 1,0- bis 1,0-fache unterstreicht die Shake-Stärke Wir nehmen beide und wenden sie auf den Kameraversatz an Offset entspricht also dem normalen Offset plus Vektor zwei, und das sind Shake X und Shake Y. Also im Grunde genommen wackelt die Kamera bei jeder Frame-Aktualisierung an eine neue zufällige Position, die leicht vom ursprünglichen Offset entfernt ist , und das tut sie, bis die Shake-Zeit vorbei ist Wenn also die Verwacklungszeit Null oder weniger ist, also sagen wir etwas anderes, dann wollen wir den Kamera-Offset auf seine ursprünglichen Werte zurücksetzen Der Offset wird also dem ursprünglichen Offset entsprechen. Okay, und wenn ich das richtig verstanden habe , ist das so ziemlich unser Drehbuch. Als letztes müssen wir den Spielerkontext und den Inspektor zuweisen. Also schnell hier drüben, Dropdown, schnelles Laden, Spielerkontext. Und lass uns das Spiel starten und unseren Spieler treffen lassen und schauen, ob es wie erwartet funktioniert. Okay, hier ist ein Ork und unsere Kamera wackelt jedes Mal, wenn wir getroffen werden Und beim Tod wackelt unsere Kamera, die viel stärker ist, wie Sie sehen können Das ist also im Grunde unser ganzer Kamerawake-Effekt. Als Nächstes wäre natürlich ein guter Zeitpunkt, um den GameOver-Bildschirm aufzurufen , damit wir zum Startmenü des Spiels zurückkehren können , das wir ebenfalls erstellen müssen 57. F56 Erstellen eines Spiels über Bildschirm mit Hauptmenünavigation: Eines der letzten Dinge, die wir hinzufügen müssen, ist ein GameOver-Bildschirm und ein Hauptmenübildschirm GameOver wird also natürlich auftauchen, wenn unser Charakter besiegt ist Also müssen wir erneut auf den Spielerkontext zugreifen , damit wir überprüfen können, ob I live falsch ist Also öffne ich zuerst das Dateisystem und gehe zur Benutzeroberfläche, und wir werden unseren Haupt-Gameplay-UI Canvas finden , der es etwas einfacher macht, daran zu arbeiten , sodass wir sehen können, wo wir das Spiel auf dem Bildschirm platzieren werden. Ich denke, ich werde vorerst die Level-Up-Auswahl nehmen und sie ausblenden. Das wird es einfacher machen, daran zu arbeiten. Und nehmen wir die Benutzeroberfläche. Ich klicke mit der rechten Maustaste auf Einen untergeordneten Knoten hinzufügen. Deshalb wollen wir ein neues Steuerelement dieses Steuerelement soll zentriert werden. Lassen Sie uns also im Layout die Anker positionieren und zentrieren Jetzt klicken Sie auch auf die Maus und stellen den Filter auf Ignorieren. Und lassen Sie uns mit der rechten Maustaste klicken und diesem Kontrollknoten einen Panel-Container hinzufügen . Also Panel-Container. Das wird der Hintergrund sein. Wir nehmen den Plattencontainer und strecken ihn aus. Zoomen Sie also hinein, stellen Sie sicher Panel-Container hier ausgewählt ist, und lassen Sie uns ihn erweitern. Unser Panel-Container soll also auf unserem übergeordneten Steuerelement zentriert sein. Gehen wir jetzt zum Layout und machen das Layout Anchors Center. Das sollte die Anker der Eltern genau hier in der Mitte platzieren , das ist also Dadurch wird es zentriert auf dem Bildschirm angezeigt. Lassen Sie uns den übergeordneten Knoten in GameOver-Bildschirm umbenennen. Klicken Sie außerdem mit der rechten Maustaste darauf und speichern Sie es als Zweig im UI-Ordner auf dem GameOver-Bildschirm Jetzt können wir einfach loslegen und das rein bearbeiten. Also unser GameOver-Bildschirm, wir werden natürlich so etwas wie ein Rich-Text-Label als Titel benötigen ein Rich-Text-Label als Titel Klicken wir mit der rechten Maustaste auf Rich-Text-Label hinzufügen. Und ich kann in dir einfach GameOver sagen. Wir werden wahrscheinlich das Roots-Thema auch zu unserem Hauptspielthema machen wollen Roots-Thema auch zu unserem Hauptspielthema Laden Sie also schnell das Theme hier hoch, das Spieldesign, das uns die Pix-Art-Schrift geben wird Jetzt können wir auch das Rich-Text-Label verwenden und sagen wir, den Inhalt anpassen Wir möchten auch zentrierten Text sagen, und er scheint auch zu groß zu sein. Ich denke, das wird kein Problem sein, nachdem wir den VBox-Container hinzugefügt haben, klicken Sie mit der rechten Maustaste auf den Panel-Container fügen Sie einen VBox-Container Verschieben Sie das Rich-Text-Label darunter. Okay, das hat die Größe geändert , da sie jetzt vom Container gesteuert wird. Lass uns mit der rechten Maustaste auf die VBox klicken und vielleicht eine Texturratte hinzufügen vielleicht eine Texturratte und dann bekommen wir ein trauriges Symbol dafür Und dann bekommen wir ein GameOver-Symbol. Wenn wir Textur verwenden und Atlas-Textur verwenden, erweitern wir sie. Und dann laden wir für den Atlas schnell unsere Icons. Wir könnten hier einfach den 64 64 verwenden , wenn wir das im Projekt behalten wollen. Region bearbeiten. Okay, und dann müssen wir rauszoomen und einfach etwas auswählen, das gut wäre, zum Beispiel für ein Game Over. Es gibt also eine Menge Optionen, aus denen man wählen kann. Ich denke, dieser Schädel , der aussieht, als würde er schlafen. Es ist nicht zu dunkel, es ist nicht zu süß, also denke ich, dass das funktionieren könnte. Lassen Sie mich das aus dem Weg räumen damit ich den Regionseditor sehen kann. Möglicherweise muss ich die Größe hier tatsächlich ändern. Ich versuche es mit einem Viererschritt auf dem X und vier auf dem Y. diese Weise kann ich das Ganze nach rechts ausdehnen, und dann passen links und rechts zueinander Ich werde den Boden auch ein wenig nach oben ziehen. Okay, mit Schritt 44 hat das ein bisschen gut funktioniert, sodass ich hier näher ran kann. Wir vergrößern unseren GameOver-Bildschirm. Ich glaube, ich werde einen Filterclip haben wollen. Ich denke, auch für den Stretch-Modus müssen wir den Aspekt zentriert halten, und das sieht für mich gut aus. Also werden wir auch ein Beschreibungsfeld hinzufügen. Klicken Sie also mit der rechten Maustaste auf die VBox, fügen Sie ein weiteres Rich-Text-Label hinzu, und wir können sagen, dass Sie besiegt wurden Wir versuchen es erneut. Klar, lassen Sie uns damit weitermachen, passender Inhalt. Ja. Und dann brauchen wir nur noch eine Schaltfläche hier unten, um zum Hauptmenü zu gelangen Klicken Sie also auf VBox fügen Sie eine Schaltfläche für einen untergeordneten Knoten Auf dieser Schaltfläche wird Hauptmenü angezeigt. Ich werde ein Skript daran anhängen. Das wird also ein neuer Button sein. Okay, als Nächstes nehmen wir diese Schaltfläche hier und ich werde sie in Szenenwechsel-Schaltfläche umbenennen , weil wir zum Hauptmenü zurückkehren werden. Lassen Sie uns ein Skript daran anhängen. Das wird also der Scene Change Button Dot GD sein. Erschaffe das. Und wir wollen Export var mit demselben Pfad hinzufügen. Also können wir das tatsächlich zu einer Exportdatei machen, und das wären Anführungszeichen, Stern, Punkt TSCN Okay, unser Szenenpfad ist also eine Zeichenfolge und wenn wir bereit sind, stellen wir eine Verbindung zu dem gedrückten Signal her, also Punkt verbinden , wenn die Taste gedrückt wird, und dann Funktionsunterstrich bei gedrückter Taste und dann Funktionsunterstrich bei gedrückter Taste, wechseln wir einfach zu Lassen Sie uns also Gtree dot change scene to file ausführen und den Szenenpfad eingeben, und dann wird unsere aktuelle Szene zur Hauptmenüszene geändert . Als wichtige Überprüfung wäre es wahrscheinlich hilfreich, wenn wir sagen würden Szenenpfad leer ist Entspricht Falsch und besagt, dass es einen sichtbaren Pfad geben sollte , zu dem man wechseln kann, wenn diese Taste gedrückt wird Okay. Also eine weitere Sache, die ich wahrscheinlich will, ist ein Margin-Container. Klicken wir mit der rechten Maustaste auf den GameOver-Bildschirm und fügen Sie einen Margin-Container Ich werde ihn direkt unter den Panel-Container legen und dann VBox darunter Okay? Jetzt können wir Werte für den Randcontainer und die Theme-Overrides festlegen, etwa vier für alle Seiten, und das wird es ein bisschen schöner aussehen lassen ein bisschen Puffer für den Text geben Und bei unserem Spiel über den Bildschirm müssen wir sicherstellen , dass die Benutzeroberfläche geöffnet wird , wenn das Spiel verloren ist Also werde ich hier ein neues Skript anhängen. UI-Spiel über Bildschirm. Erschaffe das. Vielleicht brauchst du hier einen Klassennamen, Game over Screen. Und lassen Sie uns durch den Kontext einen Verweis auf den Spieler bekommen. Bei Export ist Vara Context also vom Typ Spielerkontext. Wir sagen Function Underscore Ready und bei Bereit machen wir Context Dot Player Dot Stats und wir erhalten die Alive-Änderung Stellen wir eine Verbindung her und sagen, dass sich der Spieler Alive geändert hat. Also haben wir unsere Funktion Underscore bei Player Alive geändert Ich kann mich nicht erinnern, ob das irgendwelche Parameter hatte, also klicke ich auf das Symbol Alive changed und wir werden überprüfen, ob es das Live-Boole hat, also gehe zurück zum Game Over-Skript, und das brauchen wir hier als Parameter P Alive ist also ein boolescher Wert. Dies wird als ungültig zurückgegeben. Und wenn P Live gleich False ist, werden wir hier unser gesamtes Spielmenü anzeigen. Okay, unser Stil mit der Schaltfläche zum Ändern der Szene wird nicht funktionieren, weil wir keine Szene im Hauptmenü haben. Lassen Sie uns also einen Platzhalter erstellen. Fügen Sie eine neue Szenen-Benutzeroberfläche hinzu, und dies wird das Hauptmenü sein Ich werde es im Projekt speichern. Also machen wir das einfach im Stammverzeichnis des Projekt-Hauptmenüs und speichern es. Und dann weisen wir im Game Over-Bildschirm das Hauptmenü als Pfad zum Szenenpfad und der Schaltfläche zum Szenenwechsel wie folgt zu. Du kannst es einfach per Drag-and-Drop ziehen. Das ist der einfachste Weg, es zu tun. Okay, bevor ich es vergesse, gehe zum Game Over-Bildschirm und weise den Spielerkontext zu. Laden Sie also schnell die Spielerkontextressource. Jetzt wollen wir in die Welt gehen. Wir können sehen, dass das Game over UI genau dort ist. Mal sehen, ob wir es einfach ganz schnell testen können. Und stellen Sie sicher, dass wir dadurch zum Hauptmenü gelangen können. Also habe ich auf Play geklickt. Und es ist genau dort. Ich gehe zum Hauptmenü, und das gibt uns einen leeren Bildschirm , weil wir dieser Szene nichts hinzugefügt haben . Es ist im Grunde nur ein leeres UI-Element. Das funktioniert also tatsächlich. Ich denke, die andere Sache, die wir machen wollen, ist Ready for the Game over Screen. Stellen wir einfach sicher, dass es sich versteckt. Also sagen wir, verstecken Sie sich bereit. In unserem Gameplay-UI Canvas möchten wir es vielleicht auch dort verstecken, aber das muss nicht unbedingt bedeuten, ob es hilft. Aber ich lasse es standardmäßig sichtbar , damit wir die Höhe testen können. Es versteckt sich also, und jetzt müssen wir uns nur noch besiegen lassen, und es sollte auftauchen, wenn es richtig funktioniert. Also zwei Treffer, drei Treffer, vier Treffer, fünf Treffer. Da ist unser Game over Pop-up, Hauptmenü, und der Ablauf funktioniert. Ich glaube, das Letzte, was ich hier brauche, ist, die Größe zu ändern. Also übertrage ich das Spiel auf dem Bildschirm in unserem Gameplay-UI-Canvas und lass uns die Layoutform nehmen und die Skala auf drei erhöhen Das sollte groß genug sein. Damit ich es noch einmal ganz schnell im Spiel testen kann. Okay, also ein Treffer, zwei Treffer, drei, vier Treffer, fünf Treffer, das Spiel ist vorbei. Und wir bekommen den Hauptmenü-Button. Und das ist der grundlegende Ablauf. 58. P57 High-Score-Verfolgung und Benutzeroberflächenanzeige für Feindniederlagen und Überlebenszeit: Schön, dass es unserem Spiel fehlt, ist ein Highscore. Wir können verfolgen, wie viele Gegner wir in einem Spiel besiegt haben, und uns diesen Punktestand dann in einer sicheren Datei merken, um Gegner wir in einem Spiel besiegt haben, eine Highscore-Liste zu erstellen, die wir im Hauptmenü sehen können Um das umzusetzen, müssen wir zunächst zählen, wie viele Feinde wir besiegt haben , wenn ein Feind besiegt wurde. Wir benötigen also eine Kombination aus der Meldung des Todeszustands an einen Statistik- oder Highscore-Manager und der Erfassung dieses Werts nach Spielende und dessen Speicherung, um die Safe-Datei zu aktualisieren. Also haben wir zu Beginn des Kurses einen Game Manager Singleton hinzugefügt und nie wirklich viel damit gemacht Tatsächlich hat die Art und Weise, wie ich das Spiel über den Bildschirm implementiert habe , letztendlich nur den Spielerkontext verwendet, anstatt direkt über den Game Manager berichten zu müssen Geben wir dem Game Manager also ein gewisses Ziel, damit wir ihn im Kurs verwenden können. Wir werden also ein Objekt in einem Game Manager für Spielstatistiken haben und das dann während des Spiels verfolgen. Und dann stellen wir das ein, wann immer wir ein neues beginnen. In Systemen klicke ich also mit der rechten Maustaste und mache ein neues Skript. Nehmen wir an, es sind Spielstatistiken, die ein Schiedsrichter gezählt wird, weil wir es eigentlich einfach zu einem Kind des Spielmanagers Singleton machen Kind des Spielmanagers Singleton Öffnen Sie also die Spielstatistiken und sagen wir dann, ob unsere Gegner besiegt sind. Das ist eine Ganzzahl, die standardmäßig Null ist, und wir benötigen einen Klassennamen hier oben Also Spielstatistiken. Und dann starte ich im Game Manager eine Funktion, die den Wert void zurückgibt, und das nimmt unsere Spielstatistiken und setzt sie zurück oder setzt sie auf ein neues Objekt. Also für Statistiken der Spielstatistiken. Das werden Statistiken sein, die GameStats Punkt Nu entsprechen. Lass uns vorerst damit weitermachen. Und wenn die Welt geladen ist, werde ich die Spielstatistiken nehmen und sie zurücksetzen wollen. Also lasst uns der Welt ein Drehbuch beifügen. Alles klar, hier klicken, ein Skript anhängen. Wir werden es in die Basisszene einfügen. Wenn wir das erstellen, sage ich funktionsbereit und wir sagen Game Manager Punkt SAT. Okay, was auch immer unser Spiel zu Beginn laden soll, wir werden es einfach da haben. Solange wir hier also das World-Skript verwenden, werden wir das schaffen können. Vielleicht möchten wir dem auch einen Klassennamen geben. Es könnte ein ziemlich großes Drehbuch werden wenn wir die Serie fortsetzen würden. Ich denke also, es verdient den Klassennamen World. Also, wann immer wir ein neues Spiel starten , werden im Grunde die Statistiken zurückgesetzt. Und dann vielleicht das Spiel als beendet melden. Wir könnten erwägen, etwas später hierher zu gehen und die Highscore-Statistiken zu speichern, wenn es nötig ist. Okay, jetzt möchte ich unsere Statistiken ändern und ich möchte melden, wann immer unsere Statistiken geändert werden. In den Spielstatistiken werden wir also ein Signal dafür setzen, dass unsere Feinde besiegt sind. Also signalisieren Sie, dass Feinde besiegt und verändert wurden. Wir nehmen einen Betrag und eine Ganzzahl als Parameter und folgen einem ähnlichen Muster, und folgen einem ähnlichen Muster bei dem wir jedes Mal, wenn wir den Wert aktualisieren , davor schützen, dass es dieselben Werte sind. Wenn der Wert „Besiegte Feinde“ entspricht, kehren wir einfach zurück. Andernfalls legen wir einen neuen Wert fest. Besiegte Gegner entsprechen also dem Wert, und dann sagen wir, dass besiegte Feinde den Punkt m durch einen neuen Wert ersetzt Okay, also wann immer wir die Immobilie aktualisieren, melden wir das mit einem Signal , sodass wir die Immobilie beobachten können Und ich denke, das ist ungefähr alles, was wir brauchen, um eine Benutzeroberfläche einzurichten. Okay, jetzt, wo das da ist, wann immer wir den Todeszustand aktiviert haben, sagen wir, auf unserem Ork oder unserem Skelett, lassen Sie uns mit dem Todesstatus-Skript beginnen Bezug auf unseren Todesstatus denke ich, dass Enter am sinnvollsten ist sagt, dass Game Manager Punktstatistiken, EMS besiegt plus gleich eins ist, man sagt, dass Game Manager Punktstatistiken, EMS besiegt plus gleich eins ist, und so werden wir diesen Zähler aktualisieren alle Feinde verfolgen, die wir besiegt haben Das Letzte, was wir brauchen, ist eine kleine Benutzeroberfläche, um zu zeigen wie viele Gegner wir besiegt haben also in unserem Gameplay-UI Canvas eine weitere hinzufügen, Lassen Sie uns also in unserem Gameplay-UI Canvas eine weitere hinzufügen, machen wir sie einfach zu einem Panel-Container Fügen Sie hier einen untergeordneten Panel-Container hinzu, und wir werden das Layout als Anker oben rechts platzieren das Layout als Anker oben rechts Ich werde es ein bisschen so ausdehnen. Kompensieren Sie es. Lass mich das Game Stats View nennen. Klicken Sie dann mit der rechten Maustaste auf „ Einen Zweig als Szene speichern “ und die Benutzeroberfläche springt natürlich in die Szene, klicken wir mit der rechten Maustaste darauf und geben ihr ein Skript. Das wird also Gamestts Ansicht sein. Ich kann ihm den Klassennamen Gamests View geben. Und in der 2-D-Ansicht, in der wir es bearbeiten, fügen wir ein Etikett für unsere tatsächlich besiegten Feinde Klicken Sie also mit der rechten Maustaste auf Untergeordneten Knoten hinzufügen. Ich glaube, wir beginnen mit einem HBox-Container und klicken dann mit der rechten Maustaste auf Achil Node, Rich-Text-Label Ich werde das einfach duplizieren. Der erste dient also dazu , den Text anzuzeigen, und dann ist der zweite die Zahl. Das wird also das Statistiklabel sein. Und dann wird das untere das Betragsetikett sein. Okay. Also das SAT-Label wird durchweg besiegte Gegner anzeigen, Doppelpunkt, passen wir zum Inhalt. Und dann die zweite, ich setze eckige Klammern, Null. Das ist also nur ein Platzhalter. Und ich denke, wir müssen sie ausstrecken, damit wir sie tatsächlich sehen können Lassen Sie uns also versuchen, das Layout und die Größe der Container zu ändern und horizontal zu expandieren. Ja. Und dann Betragsetikett, das Gleiche. Gehe zum Layout. Containergröße, erweitern Sie die, erweitern Sie die Horizontale. Okay, also das ist jetzt irgendwie das, was wir gerade bekommen. Okay, jetzt nimm die Spielstatistiken drücke Q, um in den Auswahlmodus zu wechseln, und wir werden ihn auf das reduzieren, was wir brauchen Ein Randcontainer wäre hier auch nett, also klicke ich mit der rechten Maustaste und füge einen untergeordneten Randcontainer hinzu, und lass uns den HBox-Container darunter auf dem Randcontainer platzieren darunter auf dem Randcontainer Das Thema überschreibt Konstanten und vielleicht vier Pixel auf jeder Seite. Das sieht viel besser aus Ich denke, das könnte für den Moment funktionell genug sein. Ich gehe zurück zum UI Canvas des Spiels und stelle sicher, dass sich das wieder in der oberen rechten Ecke als Anker oben rechts befindet, und verschiebe es dann, indem ich W drücke, um es zu verschieben Dann bewege es einfach ein bisschen von der Ecke nach unten. Okay. Und dann muss ich im Skript von GameStts sehen, ich muss mich tatsächlich mit dem Signal auf den Gamests verbinden Also die Funktion unterstreicht schon. Wir werden Game Manager machen, Punktstatistiken Punkt besiegte Feinde geändert, Verbindung zu besiegten Feinden hergestellt, geändert Ich nehme diesen Namen und mache hier unten eine neue Funktion, Funktion bei besiegtem Feind geändert, was den P-Wert und die Ganzzahl für ungültig erklärt, und wir werden den Wert dort aktualisieren. Okay, also im Grunde nehmen wir den neuen Betrag und setzen ihn auf das Etikett. Also bei Export VR. Also wie dem auch sei, wir nehmen die Bezeichnung „Besiegt“ unserer Feinde und setzen den Text auf eine Zeichenfolge dem Betrag, und das ist so ziemlich alles. Wir brauchen hier am Ende nur einen Doppelpunkt. Vielleicht wollen wir auf Bereit bestätigen, dass die Bezeichnung „ Besiegt“ des Feindes existiert. Label „Gegner besiegt“ muss so eingestellt , dass die Anzahl oder das Reittier der besiegten Gegner angezeigt wird. Wir werden etwas genauer sein. Klicke nun auf die Spielstats-Ansicht und springe in die Szene. Und hier wollen wir das Betragsetikett zuweisen. Klicken Sie also auf Zuweisen und wählen Sie das Betragsetikett aus. Und wenn ich es richtig gemacht habe, sollte das alles hier sein. Also lass uns spielen und es versuchen. Wir müssen nur ein paar Feinde besiegen und sehen, wie sie oben rechts auftauchen. Das Problem hier ist also, dass Statistiken in nichts initiiert werden, also möchte ich mit der rechten Maustaste auf das Lou-Symbol klicken Ich denke, das Problem hier ist, dass die Statistiken möglicherweise nicht gesetzt werden, bevor sie auf der Benutzeroberfläche fertig sind, da das der Gipfel der Welt ist, ich denke, die Kinder sind zuerst bereit. Ich denke, ein besserer Weg, das zu tun, wäre zu sagen, dass die Statistiken dem Punkt u entsprechen. Das wird also immer erstellt, wenn das Spiel beginnt Und dann wollen wir Stats Dot Reset nennen. Also machen wir einfach eine neue Funktion dafür. Das bedeutet auch , dass wir die Signale nicht erneut verbinden müssen , weil wir immer noch dasselbe Objekt verwenden Es ist also tatsächlich eine bessere Methode. Lass uns in die Spielstatistiken springen und unsere Reset-Funktion erstellen. Also Funktion zurückgesetzt. Wir setzen einfach alles auf die Standardwerte zurück. Besiegte Feinde sind also gleich Null, und das sollte alles sein, wofür wir im Moment brauchen Jetzt sollten die Statistiken also festgelegt werden, sobald das Spiel beginnt, bevor die Welt überhaupt geladen ist Und von dort aus sollten wir in der Lage sein, eine Verbindung zum Signal herzustellen. Okay, versuchen wir es noch einmal. Okay, spiel. Okay, wir haben oben rechts eine Zählung Natürlich ist es viel zu klein, aber wir können das zumindest irgendwie sehen. Lasst uns also einen Ork besiegen und sicherstellen, dass er funktioniert. Und wir haben einen da, der auftaucht, wenn wir noch einen Kerl töten. Okay? Da haben wir drei. Also ja, die Zählung funktioniert mit Sicherheit. Ich muss nur die Benutzeroberfläche vergrößern. Also im Gameplay-Canvas machen wir das einfach hier. Eine einfache Transformationsskala von drei. Schieb das hier nach rechts. Und jetzt müssen wir tatsächlich einen Großteil dieses zusätzlichen Raums abschneiden. Das nimmt einfach grundlos viel zu viel in Anspruch. Also brauche ich da ein bisschen Nachbearbeitung. Lass uns in die Spielestansicht springen. Das Mengenlabel, ich setze es ohne die eckigen Klammern wieder auf Null zurück ohne die eckigen Klammern wieder auf Null , damit es nicht wackelig angezeigt wird, bevor wir den ersten Feind besiegen es nicht wackelig angezeigt wird Okay, jetzt, da die Größe zu groß ist, ich denke, dass vieles davon einfach darauf zurückzuführen ist, dass ich die Anzeigegröße des Spiels manuell eingestellt habe Also lass uns das hier drüben auf das reduzieren , was wir tatsächlich brauchen. Also können wir sie viel kleiner machen. Und diese zweite Ansicht muss nicht annähernd so groß sein wie die erste. Es gibt also keinen Grund, sie gleich viel Platz beanspruchen zu lassen. Ich denke, was wir vielleicht wirklich wollen, ist eher ein Flow-Container. Lassen Sie mich den Typ eines H-Box-Containers in einen Flow-H-Flow-Container ändern . Okay, jetzt gehe ich runter zum Mengenlabel und deaktiviere hier das Häkchen bei „Erweitern Und dann versuchen wir, die benutzerdefinierte Mindestgröße zu nehmen und sie auf etwa 40 Pixel einzustellen , wahrscheinlich groß genug, damit ich mindestens die Tausenderziffer speichern kann Und dann wird der Rest des Raums von dem besiegten Feind besetzt. Lassen Sie uns auch die Ansicht auf der Basis auf unser Standarddesign des Schnellladespielthemas ändern . Ja, okay, das wird auch große Auswirkungen haben. Also, wenn wir es uns jetzt ansehen, kann ich es tatsächlich verkleinern Ich hätte das am Anfang machen sollen, wirklich. Also so etwas, das ist unser Platz für das Label und die Nummer da drüben. Wir können zur Spieloberfläche auf Canvas gehen und das Ganze drastisch verkleinern Sie können sehen, dass alles, was nicht das Pixel auf der rechten Seite ist , einfach von der Textbeschriftung auf der linken Seite aufgenommen wird Es ist also besser, wenn diese beiden Elemente nicht versuchen, gleichen Anteil an der Ansichtsgröße einzunehmen, sondern eines ist wie eine statische Größe, und der Rest wird einfach erweitert. Und dann lege ich das einfach ein bisschen mehr in die Ecke da drüben. Wir klicken auf Play. Und sehen Sie, wie sich das herausstellt. Okay, das ist viel besser, passendere Größe. Also natürlich nur um nochmal zu testen. Wir werden einfach einen Typen besiegen und das wird aktualisiert, sodass wir unsere besiegten Feinde zählen können. Fügen wir also eine weitere Statistik hinzu, die angibt, wie lange unser Spieler im Spiel überlebt hat, eine weitere nützliche Statistik, die gut für unseren Highscore ist. Also werde ich in unserer Gamests-Ansicht diesen HBox-Container duplizieren Jetzt benötigen wir einen VBox-Container damit sie übereinander gelegt werden können Klicken Sie mit der rechten Maustaste auf Margin Container und fügen Sie eine VBox hinzu. Verschieben Sie diese beiden H-Felder wie folgt darunter und ändern Sie nun die Statistikbeschriftung auf der linken Seite Time Survived Colon Und wenn wir in GameStatsView gehen, wird es ein wirklich ähnliches Setup sein Wir stellen einfach eine Verbindung zu den Statistiken her, wie lange wir gelebt haben, und zeigen das auf dem Gebiet, in dem die Klicken wir also mit der rechten Maustaste auf Statistiken, suchen nach dem Symbol und öffnen es. Wir werden also var time survive haben, was ein Float gleich 0,0 ist. Wir werden den Wert darauf setzen. Wir sollten diesen Wachmann nicht wirklich brauchen. Es ist nur ein Extra. Also sage ich einfach, dass die überlebte Zeit gleichbedeutend mit Wert ist. Und dann hat die Zeit natürlich überlebt, die Emission verändert, die Zeit überlebt Und dann haben wir das Signal hier oben. Die Zeit hat überlebt, sie hat sich verändert. Was eine Zeitreise sein wird. Okay, der ganze Grund, warum wir diese Wache haben , ist einfach, dass aus irgendeinem Grund etwas im Spiel den Wert auf den Wert setzt , auf dem er sich bereits befindet, besiegte Gegner 50 waren, und jetzt sind es wieder 50. Ich würde eine zusätzliche Aktualisierung der Benutzeroberfläche auslösen. Aber ehrlich gesagt ist es zunächst einmal unwahrscheinlich, dass das passiert. Und zweitens sollte es aus nichts wirklich eine große Sache machen . Es ist also eher nur aus technischen Gründen. Es hat sich nur geändert, wenn sich der Wert tatsächlich geändert hat, und es ist nicht wirklich ein Problem für das Spiel Also wollte ich das nur klarstellen. Okay, jetzt muss unser Reset auch Time Survived in Anspruch nehmen und diesen Wert auf 0,0 setzen , weil wir die Zeit zurücksetzen Okay, also lass uns sehen, was sonst noch? In unserer Spielwelt denke ich, dass wir die Zeit erhöhen wollen Wenn die Welt also läuft, werden wir einen Funktionsunterstreichungsprozess haben. Wenn wir den Spielmanager nehmen, Punkt Statistik Punkt. TV plus ist gleich Delta Aber das kann wirklich nur passieren, solange der Spieler am Leben ist. Also machen wir einfach Export für den Kontext unter VR-Kontext exportieren, Spielerkontext. Du kannst überall im Spiel an verschiedenen Stellen sehen, wo wir diese Kontextressource verwenden überall im Spiel an verschiedenen Stellen sehen, wo wir diese Kontextressource . Das als gespeicherte Ressource zu haben, ist also äußerst nützlich , um die Referenz auf all unsere Benutzeroberflächen und andere Knoten verteilen zu können um die Referenz auf all unsere Benutzeroberflächen und andere Knoten verteilen , die auf den Spieler verweisen müssen, ohne dass ein direkter Szenenbezug zum Spieler besteht. Hoffentlich habe ich klargestellt, wie hilfreich das sein kann. Wir haben also den Spielerkontext und wollen die Überlebenszeit nur erhöhen, wenn der Spieler noch am Leben ist Wenn also der Kontaktpunkt der Spielerstatistik Punkt Live ist, dann erhöhen wir die Zeit Andernfalls werden wir das einfach überspringen. Und das sollte vorerst reichen Ich benötige einen Hinweis auf das neue Mengenetikett. Also sagen wir bei Export var, Time Label ist ein Rich-Text-Label, und das ist natürlich die GameTests-Ansicht Sagen wir also Game Manager Punkt Stats Punkt Zeit überleben Veränderung Punkt Connect, on Time Survive hat überlebt, geändert Und wir haben gerade noch einen Rückruf hier unten. Die Funktion „On Time Survived“ wurde geändert und erhält den PT-Float. Wir geben void zurück und setzen dann den Text auf das Etikett. Der Punkttext auf der Zeitbeschriftung entspricht also einer Zeichenfolge aus dem PT, und das ist wahrscheinlich gut genug. Ich mache einfach auch eine Bestätigung auf dem Zeitetikett . Stellen Sie sicher, dass es eingestellt ist. Die Zeitbeschriftung muss eingestellt sein, um die verbleibende Zeit zu aktualisieren. Okay. Und lassen Sie uns in unserer Spielests-Ansicht das andere Betragsetikett zuweisen Möglicherweise möchten wir diese HBox-Container umbenennen. Der erste Container war also der besiegte Container des Feindes Und dann ist der zweite der Container, der die Zeit überlebt hat. Also nur klarstellen , welcher welcher ist. Stellen wir sicher, dass es in der Gameplay-Benutzeroberfläche ist. Wir werden in die Welt hinausgehen und sehen, ob es immer noch da ist. Drücken Sie auf Play, um zu testen und zu starten und zu sehen , wie das aussehen wird. Ah, okay, ich habe den Kontext der Welt natürlich nicht festgelegt . Auf dem Weltknoten müssen wir also schnell den Spielerkontext laden. Okay? Und jetzt, wenn wir weglaufen, sollte sich die Zeit erhöhen können. Und dann haben wir oben rechts die Zeit. Nun, das funktioniert größtenteils. Ich denke, hier gibt es ein paar Probleme. Erstens, es sieht so aus, als müssten wir das vertikal etwas vergrößern. Oh, nett. Wenn das Spiel positiv ist, hört es auch auf. Das ist wichtig. Und zweitens glaube ich nicht, dass wir alle Millisekunden anzeigen müssen Ich denke, das auf eine Dezimalstelle zu reduzieren, wäre etwas weniger stressig Sie können sehen, dass die zweite und dritte Dezimalstelle fliegen Du kannst es nicht einmal lesen . Es macht also keinen Sinn , diese Informationen zu zeigen. Okay, um unsere Texteinstellungsfunktion zu ändern, werden wir stattdessen Prozent eins F in Anführungszeichen setzen. Das gibt uns also den Gleitkommawert mit einer Dezimalstelle und dann geben wir ein Prozentzeichen, sodass wir die PT-Variable hinzufügen, um diese Zeichenfolge tatsächlich einzurichten. Okay, und jetzt können wir auf Play klicken und wir werden sehen, dass die Zeit nur die erste Dezimalzahl anzeigt. Das ist zehnmal besser lesbar und weniger ablenkend. Großes Upgrade. Ich denke, das sieht gut aus für unsere Spielstatistiken. Ich denke, das Einzige, was ich ändern könnte ist, die überlebte Zeit nach oben zu setzen und den Feind unten zu besiegen und noch einmal auf Play zu klicken. Ich denke, das wird einfach ein bisschen besser aussehen. Die Zeit hat überlebt. Ich glaube, ich will die auffälligste oben rechts und dann die anderen, kleineren Statistiken darunter, die, die weniger aktualisiert werden Nur eine kleine visuelle Präferenz. Okay. Und nur um zu zeigen, dass wir Orks immer noch besiegen können und dass die Zähler funktionieren. Die Spielstatistiken sind also zumindest im Gameplay gut. 59. P58 Speichern und Laden von Highscores mit JSON: Okay, jetzt, wo unsere Spielstatistiken funktionieren, wollen wir das nehmen und nach einer Niederlage wollen wir die Highscores aktualisieren und in einer JSON-Datei speichern. Das wäre also im Grunde der Start eines Save-Load-Systems. Und speziell bei dieser Art von Spiel gibt es nicht so sehr einen Speicherstatus, sondern nur Highscores, aber der Prozess wäre wirklich ähnlich, wenn Sie eine Spieldatei speichern müssten. Im Grunde müssen Sie Daten in eine Datei serialisieren, und eine der bequemsten Möglichkeiten dies zu tun, ist das JSON-Format Zum Speichern und Laden der Daten möchte ich also ein Save-Load-Objekt haben Normalerweise würde ich das zu einem separaten System machen, aber das einzige Mal, dass wir die Daten speichern müssen , ist, wenn unser Charakter besiegt ist, und das regeln wir über den Game Manager. Ich gehe also einfach in die Systeme, erstelle ein neues Skript und nenne es Save Load. Ich werde es nicht System nennen, weil es eher eine Komponente für den Game Manager selbst ist. Und das wird per Referenz gezählt. Also werde ich das Drehbuch erstellen. Lassen Sie uns die Systeme erweitern. Öffne es. Wir könnten ihm den Klassennamen Save Load geben. Und wir werden hier zwei Funktionen benötigen , nämlich Statistiken speichern, und das wird die aktuellen Spielstatistiken als Parameter verwenden. Also Statistiken der Spielstatistiken, und wir werden hier ungültig zurückgeben. Das wird also die aktuellen Statistiken nehmen und daraus ein Datenwörterbuch machen, und dann werden wir diese Daten serialisieren Also VR-Daten sind gleich und ich gebe sie ein und ich setze sie in geschweifte Klammern hier bei Colon, Statistik Punkt zwei Nun, diese Methode gibt es natürlich nicht. Wir werden das in einer Minute schreiben. Und sobald wir die Daten in einem Wörterbuch haben, das ist übrigens ein Datenwörterbuch, ich könnte es klarer machen, indem ich den Typ dort deklariere Aber wann immer Sie diese geschweiften Klammern und das GD-Skript sehen, sprechen Sie von einem Wörterbuch Als Nächstes verwandeln wir diese Daten in eine JSON-Zeichenfolge. Das ist also auch sehr einfach zu machen. Wir sagen, dass die Zeichenfolge var JSON gleich JSunnu sein wird. Wir haben also ein neues JSON-Objekt, das es uns ermöglicht, diese Zeichenfolge der Pi-Methode für unsere Daten aufzurufen, und das macht sie in einem JSON-lesbaren JSON-Zeichenkettenformat Jetzt müssen wir den Dateipfad öffnen. Wir sagen also, dass die var-Datei gleich dem Dateizugriffspunkt OP sein wird gleich dem Dateizugriffspunkt OP Das ist also eine weitere statische Klasse in der Godo-Bibliothek, und wir müssen ihr einen Pfad und dann den Dateizugriff von right geben und dann den Dateizugriff von Also sagen wir Dateipfad speichern, was wir noch nicht definiert haben, und dann wollen wir hier Zugriff Also, wo bekommen wir den sicheren Dateipfad hier oben her? Wir sagen var, der Speicherdateipfad ist eine Zeichenfolge. Dies entspricht dem Benutzer-Slash LASH gametatt JSON. Okay, was dieser Fopath im Grunde bedeutet, ist, dass er in der App Daten speichert, vorausgesetzt, Sie verwenden Windows Für dieses spezielle Spielprojekt im Stammverzeichnis dieses Ordners wird es im Stammverzeichnis dieses Ordners eine neue Datei namens gamesatt Also hat jedes in GADO erstellte Spiel einen Benutzerordner in Windows, das ist der App-Datenschlitz Gdolah, der Name Und dann wird GameStatst JSON im Stammverzeichnis gespeichert. Diese JSON-Datei ist also effektiv Ihre Speicherdatei. Für ein Survivor-Spiel ist die Say-Datei eigentlich nur deine hohen Statistiken, ist die Say-Datei eigentlich nur deine hohen Statistiken denn jedes Mal, wenn du ein neues Spiel startest, hast du einen neuen Charakter, du speicherst und lädst das Spiel nicht wie bei einem typischen Rollenspiel Aber der Prozess ist mehr oder weniger derselbe. Also, wenn die Datei existiert und wir sie zum Schreiben öffnen müssten, richtig? Wenn wir sie also nicht finden, muss es einen Fehler gegeben haben. Aber wenn wir ihn finden, sagen wir file dot store string weil wir dort oben einen JSON-String haben, richtig, also speichern wir einfach den JSON-String in der Datei und dann machen wir file dot Close. Und so schreibt man in die Datei. Und andernfalls, wenn die richtige Operation fehlschlägt, dann wollen wir natürlich Push und Fehler machen. Push-Fehler wird also dazu führen, dass eine Datei nicht zum Schreiben geöffnet wird, und ich könnte sagen, bei Pfad, Prozent s, und wir machen es und die Anführungszeichen. Dann hier drüben, Prozent speichern den Dateipfad. Also geben wir so viele Informationen wie möglich, und dann können wir von dort aus debuggen, wenn es ein Problem gibt Natürlich musst du Porti Error richtig buchstabieren. Das würde helfen, und das ist die sichere Funktion. Okay, jetzt wollen wir unsere Funktion zum Laden von Statistiken ausführen. Also Funktion Statistiken laden, und wir werden das Statistik-Objekt haben , in das wir die Daten laden. Statistiken sind also vom Typ Spielstatistiken. Natürlich bekommen wir das später vom Game Manager. Und zuerst wollen wir die Datei öffnen, damit R darauf zugreifen kann. Die VR-Datei ist also Gott gleich, ich kann im Moment nicht tippen. VR-Datei entspricht dem Dateizugriffspunkt OP im Speicherdateipfad Wir laden und speichern also im selben Dateipfad. Und dann haben wir Fleaccess dot RED. Dann gehen wir Nehmen wir an, wenn nicht Datei, also wir konnten nicht öffnen, dann können wir sagen, Push-Fehler, Fehler beim Öffnen der Datei zum Lesen bei Pfadprozenten, Prozent, Dateipfad speichern Vielleicht möchten wir das sogar zu einem booleschen Wert machen. Wenn wir es also zu einem booleschen Wert machen, können wir hier false zurückgeben, als ob wir die Operation nicht bestanden haben Das könnte ein bisschen hilfreicher sein. Später können Sie Safsts so ändern , dass es dasselbe tut, wenn Sie möchten Und wir geben false zurück, nicht wörtlich das Schlüsselwort, sodass unsere Dateien zu diesem Zeitpunkt für den Lesezugriff geöffnet Jetzt müssen wir die Zeichenfolge aus der JSON-Datei abrufen. Unser JsoText entspricht also dem Dateipunkt Als Text abrufen. Okay. Und der Grund , warum das nicht angezeigt wird, ist wahrscheinlich, dass ich das hier nicht eingegeben habe. Ich könnte also Dateizugriff sagen. Mal sehen, JSON-Text sollte dort auch unterstrichen sein, und wir können weitermachen Wir haben also den Text aus der Datei, also sind wir mit der Datei fertig Lassen Sie uns die Datei schließen, das Filet schließen. Wenn die Datei leer ist, können wir hierher zurückkehren. Der JS-Punkttext ist also leer. Dann können Sie hier entweder wahr oder falsch zurückgeben. Es hängt irgendwie davon ab, was du willst. Ich gebe „true“ zurück, damit wir angeben können, dass der Vorgang erfolgreich war, aber keine Daten geladen werden konnten. Wir sagen also, dass die Statistikdaten auf das Spielstatistikobjekt geladen werden. Wenn die Datei also nicht leer ist, müssen wir sie konvertieren. Also wird var JSON gleich Jsunt Nu sein. Wir haben also ein neues JSON-Objekt, und dann wollen wir den Text analysieren Nehmen wir an, der var-Fehler entspricht JSON-Punktanalyse im JSON-Text Wenn es also ein Problem damit gibt, wird ein Fehler zurückgegeben Wenn also ein Fehler auftritt, dann wollen wir den Fehler pushen, weil wir JSON nicht mit Prozentwerten parsen konnten, und ich sage prozentualer Fehler und ich sage prozentualer Ich denke, das könnte einige zusätzliche nützliche Informationen hinzufügen. Und dann geben wir hier false zurück, denn wenn es beim Parsen der Datei einen Fehler gab, dann liegt natürlich wenn es beim Parsen der Datei einen Fehler gab, ein großes Problem mit unserer SAI-Datei Es war wahrscheinlich nicht richtig formatiert. Okay, also wenn es keinen Fehler gab, wissen wir, dass die Analyse korrekt funktioniert hat , also können wir var sagen Die Daten eines Wörterbuchs entsprechen den JSON-Dot-G-Daten. Wir verwandeln es also im Grunde genommen in das GIDORcognized-Format als Wörterbuch Und dann sagen wir, Varsats Daten sind ein Wörterbuch, das dem Datenpunkt Get in Quote Stats entspricht Get in Quote Und die Standardeinstellung ist hier ein leeres Wörterbuch. Diese Statistiken sollten also mit dem übereinstimmen , was wir hier oben haben. Wir haben die Statistiken im Statistik-Schlüsselwertpaar gespeichert und müssen sie aus dem Statistik-Schlüsselwertpaar abrufen. Sobald wir also unsere eigentlichen Statistikdaten haben, bei denen es sich um ein Wörterbuch handelt, können wir Stats Dot From dict für Wörterbuch verwenden, und wir werden die Statistikdaten weitergeben Und das ist alles, was wir für das Laden tun müssen, also geben wir true zurück Okay, ich denke, das sieht ziemlich richtig aus. Was wir jetzt brauchen, ist eine Methode mit zwei Wörterbüchern und zwei Wörterbüchern für unsere Spielstatistiken. Wenn wir also Spielstatistiken öffnen, sagen wir, function to dict gibt ein Wörterbuch zurück, und dann nimmt function from dict ein Datenwörterbuch und gibt void zurück Um daraus ein Wörterbuch zu machen, benötigen wir ein solches VR-Wörterbuch , das einem neuen Wörterbuch entspricht Und dann, weißt du, können wir das alles in einer einzigen Sache zusammenfassen und jedes neue Schlüssel-Wert-Paar in eine neue Zeile setzen. Also sagen wir, besiegte Feinde sind gleichbedeutend mit besiegten Feinden. Doppelpunkt-CD für das Schlüssel-Wert-Paar. Auf der linken Seite haben Sie den Namen der Zeichenfolge und auf der rechten Seite den tatsächlichen Wert. Auf der linken Seite haben wir also die Zeit überlebt. Und dann Doppelpunkt, und wir haben die Zeit bis zur Variablen auf der rechten Seite überlebt, und dann geben wir das Wörterbuch zurück. Und es ist wirklich so einfach. Als Nächstes wollen wir also aus dem Wörterbuch die alten Werte in die aktuellen Werte laden. Also machen wir Gegner besiegt, entspricht p data dot git, das Schlüsselwertpaar Feinde besiegt Und dann den Standardwert, lassen Sie uns auf Null setzen, sodass wir, falls dieser Wert nicht vorhanden ist, tatsächlich auf einen Fehler stoßen, weil wir ihn sonst auf etwa Null laden würden, was alle unsere Speicherdaten dauerhaft überschreiben Irgendwie fraglich, welchen Weg du hier einschlagen willst. Willst du zum Beispiel, Laden des Speichers sofort fehlschlägt, oder willst du, dass es erfolgreich ist, aber dann die alten tatsächlichen Daten überschreibt, was nicht wirklich wünschenswert klingt, oder? Sie möchten den Fortschritt des Spielers nicht außer Kraft setzen. Also vielleicht wäre es eher so müsstest du einen Hotfix oder etwas Ähnliches veröffentlichen. Wenn Sie auf diesen Umstand stoßen der JSON einfach nicht richtig geladen wurde, haben Sie dieses Feld nicht, es fehlt der Name, so etwas in haben Sie dieses Feld nicht, es fehlt der Name, so etwas Deshalb gehe ich eher in Richtung , oh, es sollte Null sein Wenn es also versucht, den Float auf Null oder die Ganzzahl auf Null zu setzen , wirst du auf einen Fehler stoßen und er muss repariert werden, sonst macht alle Spiele deiner Spieler kaputt. Ich denke, das ist wahrscheinlich der richtige Weg hier. Time Survived wird also gleich pdta dot get on time survived als Zeichenfolge sein , und dann ist der Standardwert Okay, also haben wir die Spielstatistiken Derzeit sind die einzigen Spielstatistiken unsere Hauptspielstatistiken, unsere aktuellen Spielstatistiken, aber wir wollen auch persistente Spielstatistiken haben , unsere Highscore-Spielstatistiken Deshalb möchte ich hier eine Funktion einfügen, die im Vergleich zu aktuellen Spielstatistiken den höchsten Wert annimmt. Also sage ich, Funktion auf höchste Stufe gesetzt, sagen wir, hohe Punktzahlen setzen. P die aktuellen Spielstatistiken, und das wird dann ungültig. Wir werden das also nur bei unseren Highscores Spielstatistiken nennen , aber im Grunde genommen nehmen wir den höheren der beiden Werte. Die Anzahl der besiegten Gegner entspricht also der Höchstzahl der besiegten Gegner oder der Anzahl der aktuell besiegten Gegner. Okay, wir nehmen einfach den höheren Wert und setzen ihn auf die ganze Zahl besiegter Gegner. Und wir machen dasselbe mit der überlebenden Zeit. Überlebte Zeit entspricht max. Die Zeit hat überlebt, und der aktuelle Punkt P hat überlebt. Okay, so kommen wir also zu den Highscores. Wir vergleichen einfach die aktuellen Statistiken am Ende des Spiels und schauen , ob sie höher sind als unsere aktuellen Highscores. Wir benötigen also das Objekt zum Speichern und Laden und wir benötigen auch die Highscore-Spielstatistiken in unserem Game Manager. Also lass uns jetzt den Game Manager öffnen. Spielmanager Punkt GD. Also werden wir hier auch die Var-Highscore-Statistiken haben, was ein GamestStnu sein wird und wir werden hier auch den var-Saveoad haben , der unserem Save Load Dot Neu-Objekt entspricht Das ist also nur eine lokale Komponente unseres Game Managers. Wir könnten es sogar privat machen. Ja, warum nicht? Mach es privat. Weil die Saveoad-Logik hier wirklich so ist, wollen wir nur dem Game Manager gehören Es ist nicht wirklich etwas, worauf sich andere Skripte beziehen sollten, also machen wir es privat Also diese Funktion hier, sagen wir Funktion End Game, ist meiner Meinung nach eine etwas bessere Umbenennung. Das wird für nichtig erklärt. Am Ende des Spiels wollen wir also unsere Highscore-Statistiken nehmen und mit unseren aktuellen Statistiken Highscores aufstellen. Und dann möchten wir vielleicht die aktuellen Statistiken zurücksetzen, aber das werde ich eigentlich nicht tun , weil wir vielleicht im Hauptspielmenü die Ergebnisse der letzten Sitzung anzeigen möchten , sodass wir sie erst zurücksetzen , wenn wir das Spiel wieder richtig starten. Ich denke, das ist etwas besser. Oh, und nachdem wir die Highscores erreicht haben, wollen wir natürlich Save Load Dot Save Stats aufrufen. Also werden wir die Highscore-Statistiken speichern. Und ich glaube, fertig. Ja, bei der Funktion Bereit. Und denk dran, das ist Auto Load Singleton, also sobald das Spiel startet, wird es schon geladen Und ich möchte Underscore Load Dot Load Stats auf die Highscore-Statistiken speichern Und ja, das erledigt eigentlich den Rest. Die Logikwarteschlange zum Speichern und Laden ist also im Grunde genommen in diesem Speicherlade-Objekt versteckt oder eher gekapselt Der gesamte Speichervorgang ist also hier drin, aber der Game Manager kümmert sich tatsächlich darum wann er diese Daten speichern und laden soll Und du kannst sehen, dass der Game Manager dadurch viel einfacher zu lesen ist, weil wir seine Funktionen in verschiedene Komponenten aufteilen, anstatt alles in ein riesiges Game Manager-Skript zu stopfen ein riesiges Game Manager-Skript Dieses Video wird also etwas lang, also werde ich das nächste Video über den Aufbau des Hauptmenübildschirms drehen Wir haben bereits die Vorlage dafür , weil unser Game-Over-Button hierher springt, aber wir haben hier nichts eingerichtet. Also verbinden wir das mit den Highscore-Statistiken , haben ein Display, eine Schaltfläche „Spiel starten und irgendeine Art von Splashscreen-Hintergrund 60. F59 Entwerfen eines Hauptmenüs mit High-Score-Display und Spielstart-Funktion: Nehmen wir das Layout im Highscore-Container und platzieren es auf den Ankern oben oder rechts. Dann kann ich hineinzoomen Dann drücke ich Q, um diese Position ein wenig dorthin zu bewegen. Lassen Sie uns unseren Highscore-Container ausdehnen und dann bauen wir hier einige andere Kontrollknoten auf. Also klicke ich hier und füge einen untergeordneten Knoten hinzu. Sagen wir Margin Container. Gleiche Geschichte mit dem Margin-Container. Wir wollen ein Theme-Override, vier Pixel auf all diesen. Und um dann etwas Zeit zu sparen, könnten wir wohl zur Gamesets-Ansicht gehen Und ich werde die Zeit, die überlebt und die Feinde besiegt haben, kopieren und einfügen Zeit, die überlebt und die Feinde besiegt haben, kopieren und Ich aktiviere einfach alles anzeigen und füge es dann in das Hauptmenü ein. Also da drin. Und ich habe einen VBox-Container vergessen, also füge einen VBox-Container hinzu und verschiebe dann diese beiden Textcontainer darunter. So wie das Und so ungefähr wird es jetzt aussehen. Speichern wir den Highscore-Container in einer eigenen Szene, klicken wir mit der rechten Maustaste, sagen wir Branchien-Szene, so Und dann möchte ich die Layout-Transformation nehmen und die Skala auf diese Weise verdreifachen Okay, wenn wir das machen, wird es ein wenig mit unserer Voreinstellung „Anchors“ herumspielen, also werde ich das einfach dort drüben positionieren Sie müssen es nicht wirklich perfekt machen. Lassen Sie uns auch den Highscore-Container öffnen und einen Titeltext hinzufügen. also hier im VBox-Container heranzoome, klicke ich mit der rechten Maustaste und füge ein Rich-Text-Label Und lassen Sie uns das oben auf dem VBox-Container positionieren. Markieren Sie Fit Content und sagen wir Highscores, aber ich werde das mit, sagen wir, Regenbogen voranstellen Beenden Sie die eckigen Klammern und gehen Sie zum Ende Rainbow Damit das funktioniert, müssen wir natürlich überprüfen, ob der BB-Code aktiviert ist, und dort erhalten wir einen Standard-Regenbogen. Also ich denke, ich möchte die Frequenz verringern und das Ganze weniger dramatisch machen. Nehmen wir an, die Frequenz entspricht 0,5. Nun, lassen Sie uns sogar auf 0,25 gehen. Ja. Ja, das ist viel besser. Und dann brauchen wir SAT für die Sättigung. Sagen wir also eine Sättigung von 0,2, vielleicht 0,5. Okay, das ist ein bisschen zahmer. Also das ist gut Und wir machen das horizontale Alignment Center. Okay, das ist nicht so schlimm. Also im Hauptmenü können wir sehen , wie das aussehen wird. Zurück im Highscore-Container weisen wir das richtige Label zu. Etikett „Max besiegt“ ist also das Mengenlabel unter dem besiegten Behälter des Feindes. Und dann befindet sich das am längsten erhaltene Etikett im Behälter mit der Zeit überlebten Zeit. Okay, speichern Sie das und zurück zu unserem Hauptmenü benötigen wir einen Texturhintergrund. Also werde ich mit der rechten Maustaste auf das Hauptmenü klicken. Lassen Sie uns einen Textur-Act hinzufügen. Ich werde das so umbenennen, dass es im Hintergrund beschädigt ist. Darauf werden wir zurückkommen. Außerdem möchten wir auf dem Hauptmenübildschirm sicherstellen, dass wir die Mausfilterung ausschalten. Also Maus auf der rechten Seite, wir schalten den Filter auf Ignorieren. Das ist wichtig. Andernfalls würde das Hauptmenü tatsächlich die Schaltflächen darunter blockieren. Also lasst uns jetzt einen Button für unser Startspiel hinzufügen. Also füge einen Button hinzu. Benennen wir das in „Spiel starten“ um. Und wenn ich mich recht erinnere, habe ich nur ein Skript, mit dem ich sofort zwischen den Szenen wechseln kann. Also die Schaltfläche für den Szenenwechsel, ich ziehe sie per Drag & direkt auf die Schaltfläche Spiel starten. Und dann müssen wir ihm den Szenenpfad der Welt geben. also oben rechts, dem Szenenpfad, Wählen Sie also oben rechts, dem Szenenpfad, den Weltpunkt TCN aus, und jetzt sollte diese Schaltfläche in der Lage sein, die Welt zu öffnen, die unsere Gameplay-Szene ist Diese Schaltfläche ist natürlich sehr klein, also müssen wir zum Layout gehen Und ich werde die Skala hier unten verdreifachen. Positionieren wir es auch in Ankern und sagen dann in der Mitte unten. Wir können hier hineinzoomen. Ich treffe W. Lassen Sie uns das bis hierher ausgleichen. Geben wir ihm den Text Spiel starten und wir möchten vielleicht auch ein Symbol auswählen. Also lasst uns Icon als Atlas-Textur, Quick Load und Atlas aus unserem Spielprojekt machen. Ich mache 64 oder 64. Wählen Sie die Region aus und wählen Sie einfach ein beliebiges Symbol aus, um das Spiel zu starten. Also ich weiß es nicht. Da es sich um ein Kampfspiel handelt, wäre vielleicht eines dieser Schwerter gut Also werde ich mir das einfach schnappen und sicherstellen, dass ich alle Pixel Also muss ich das nach links ausstrecken und auf „Schließen“ klicken. Nur für den Fall, dass ich auch den Filterclip überprüfe. Wir wollen nicht, dass Kantenpixel da reinkommen. Dann ist das im Grunde unser Startspiel. Drücken Sie W und stellen Sie sicher, dass es sich innerhalb der Grenzen unseres Hauptmenüs Gehen wir auch zu Project und wir nehmen das Hauptmenü und machen es zu unserer Startszene für das Spiel Also im Allgemeinen Run, anstatt die Welt jetzt zu starten, werden wir sie laden. Die Punkte im Hauptmenü sind TSCN. Okay, jetzt wollen wir mal sehen , wo wir uns befinden. Ich drücke auf Play. Wir haben den Highscore da oben, wir haben Start Game. Lass uns auf Spiel starten klicken, wodurch unsere Haupt-Gameplay-Szene gestartet wird. Das würden wir erwarten. Und ganz schnell, lasst uns besiegt werden, sodass wir den Highscore in unserem Hauptmenü sehen können . Natürlich habe ich Game Manager Dot Report Game Over umbenannt , also müssen wir das in Game Manager Dot End Game ändern. Das ist im Status „Spieler besiegt“. Okay, lass uns jetzt noch einmal starten. Also werde ich dafür sorgen, dass ich mich von einem dieser Werke unterkriegen lasse, drei Treffer, vier Treffer, fünf Treffer. Und lass uns sehen. Die Spieler wurden bereits befreit. Es steht auf der World Note , weil wir den Spieler tatsächlich befreit haben. Das müssen wir auch für die Welten sagen. Wenn der Prozess funktioniert, wo wir die überlebende Zeit hinzufügen, müssen wir sagen, ob der Kontext nicht der Spieler ist. Und wir müssen sagen, dass nicht gleich Null ist. Ich denke, wenn Sie bei zuvor freigegebenen Referenzen nur den Context Out Player ausführen, wird immer noch ein Fehler angezeigt, aber wenn Sie sagen, dass nicht gleich Null ist, dann wird das umgangen. Okay, also im Grunde genommen, wenn der Spieler nicht mehr existiert oder der Spieler nicht mehr am Leben ist, dann werden wir die Überlebende Zeit zu den Spielstatistiken hinzufügen. Da der Spieler entfernt wurde, wird dieser Teil davon erledigt , und wir sollten startklar sein. Okay, also noch einmal auf Play drücken, um sicherzugehen, dass das auch wirklich läuft. Oh, wir können aber sehen, dass der Highscore hier aktualisiert wurde, also das ist gut. Möglicherweise müssen wir die Größe der Benutzeroberfläche ein wenig ändern. Wie Sie sehen können, besteht das Problem hier darin, es etwa 12 Dezimalstellen anzeigt, also werden wir das in einer Minute ändern Mal sehen, ob wir schneller als 7 Sekunden besiegt werden können . Okay, lass uns gehen. Eins, zwei, warte. Rüste diese Ausrüstung auf und sie ist gescheitert. Okay. Also müssen wir noch ein oder zwei Feinde finden. Da haben wir's. 12 Sekunden. Hauptmenü. Sie können sehen, dass unsere längste Überlebenszeit jetzt 12,6 Sekunden beträgt. Gegner haben zwei besiegt. Und lass uns das Spiel schließen und auf Play klicken. Dadurch wird überprüft , ob das Laden aus der Datei tatsächlich funktioniert. Also lass uns schließen und auf Play klicken. Ich habe es vielleicht noch nicht eingerichtet. Es ist interessant zu sehen, ob dies der Fall ist oder nicht. Okay, also ja, wenn das Spiel geladen wird, ist der Game Manager quasi eines der ersten Dinge, die geladen werden, und er lädt schon in den Highscore was der gespeicherte Highscore aus der Datei ist. Okay, als coole Zeit, um zu zeigen, wo das ist, lassen Sie uns App-Daten im Windows-Datei-Explorer präsentieren, und dann wollen wir Godot finden Und dann glaube ich, es sind App-Benutzerdaten, das neueste GD-Skript von Script Survivor Und genau hier haben wir ArjsOfle. Okay, also lass uns in Notepad bearbeiten. Und da kannst du genau dort sehen. Unsere aktuellen Spielstatistiken wurden in einer Datei gespeichert. Wir haben Gegner, die zweimal besiegt wurden, haben bei 12,6 überlebt, und das sind unsere gespeicherten Spieldaten, die aktualisiert werden, wenn wir besiegt werden , falls wir zufällig eine dieser Zahlen Okay, also für den Highscore-Container, den Text mit der längsten Überlebenszeit, wollen wir einfach nur das kopieren, was wir in der Spielstatistikansicht gemacht haben in der Spielstatistikansicht gemacht Also werde ich direkt in das Drehbuch einsteigen. Und dann möchte ich diesen Teil genau hier kopieren , der den Fluss nimmt und uns eine Zeichenfolge gibt , die nur eine Dezimalstelle hat. Gehe zum Highscore-Container und ich ersetze ihn hier durch diesen. Der PT wird natürlich tatsächlich der Game Manager sein, Punkt High Scorstts Punkt Die Zeit Wenn wir jetzt spielen und zum Spielmenü kommen, sollten wir hier 12,6 Sekunden sehen Das ist viel lesbarer als unser Highscore. Nun zu unserem Hintergrund Ich mache buchstäblich einen Screenshot des Spiels. Und du könntest dafür die Benutzeroberfläche ausschalten , wenn du einen Screenshot machen möchtest. Das wäre wahrscheinlich etwas hilfreicher. Okay, lassen Sie uns auch die Kollisionsformen ausschalten , bevor wir den Screenshot machen. Debuggen Sie also Kollisionsformen aus. Okay, also lass uns weitermachen und unsere Seite als Upgrade schnappen, damit wir das zeigen können Ich lasse ein paar dieser Pickups auf der Spielkarte stehen. Wir warten, bis das Skelett erscheint, und dann schauen wir, ob wir einen schönen Screenshot im Spiel machen können einen schönen Screenshot im Eine Sache, die ich in Betracht ziehen würde, wäre die Spawn-Rate zu erhöhen, wenn wir hervorheben wollen, wie viele Feinde es im Spiel gibt Okay, lass uns hier einen Screenshot machen. Ich mag den nicht so sehr. Lass uns dort vielleicht einen Screenshot machen. Drucken Sie also den Bildschirm aus, um einen Screenshot zu machen, falls das nicht offensichtlich war. Und ich werde Gap öffnen. Gap ist also ein kostenloser Bildeditor. Es ist ein bisschen wie Photoshop. Aber kostenlos. Dann machen wir File New und ich mache 1920 mal 1080 Pixel. Öffne es. Drücken Sie V, um unseren Screenshot einzufügen , und lassen Sie uns so etwas schnappen. Es ist hier nicht wirklich ein Tutorial zur Bildbearbeitung, aber ganz schnell, ich werde dort eine obere Leiste einfügen. also eine schwarze Füllung verwenden, können wir ihr den Text geben, wenn wir dies wünschen. Ich wähle eine Schrift. Also lass uns mit Pixel Regular weitermachen. Sie müssten diese Schrift installieren, wenn Sie sie verwenden möchten. Okay, ich habe einfach ein bisschen Zeit damit verbracht, so etwas wie ein benutzerdefiniertes Vorschaubild zu erstellen, außer dass wir es im Endspielprojekt verwenden werden im Endspielprojekt Also einfach oben auf einen schwarzen Hintergrund klopfen, etwas Pixar-Text, erwähnen, dass es ein GD-Kurs ist, erwähnen, dass es ein Do-Kurs ist, und dann das Gudo-Symbol Das wird wahrscheinlich nicht das endgültige Vorschaubild für den Kurs sein , aber wir können es vorerst zumindest für den Menübildschirm des Spiels verwenden Menübildschirm des Spiels Und ich werde das öffnen. Ich habe es natürlich in das Projekt exportiert. Wo Sie das gespeichert haben, können Sie sehen, dass ich hier den Hauptmenübildschirm habe. Also was ich tun möchte und die Benutzeroberfläche, das ist eigentlich der falsche Bildschirm. Wir wollen das Hauptmenü. Wir gehen zum Hintergrund Rec. Ich gehe zum Schnellladen und suche nach dem Hauptmenübildschirm. Steck das da rein. Eventuell muss ich hier die Größe erhöhen, also gehen wir in den Layoutmodus, ankern und das komplette Wrack machen Okay, mit all dem und jetzt wollen wir sichergehen, dass nichts dadurch blockiert wird Also ich denke, wir müssen das nach oben links verschieben. Okay, die Highscores zeigen, dass wir spielen können. Okay, und wir können spielen und wir sollten es uns dort ansehen. Drehbuch: Survivors stehen hier oben hoch. Es ist ein Gado-Kurs Wir haben die Schaltfläche Spiel starten und das Gado-Symbol, was ich meine, ziemlich solide für etwa fünf, zehn Minuten Arbeit, ich denke, kann natürlich verbessert werden Okay, jetzt, an diesem Punkt, ist das Spiel fast fertig Wir haben dort unseren Begrüßungsbildschirm. Wir können das Spiel starten, die Highscores werden während des Spiels für die aktuellen Punktzahlen und auf dem Hauptmenübildschirm für die Highscores aller Zeiten angezeigt. Wir können die Feinde besiegen. Wir können das Spiel verlieren. Wir können aufrüsten, vielleicht wollen wir ein bisschen aufräumen, Beispiel diese Startverbesserungen von der Spielkarte entfernen Das ist ein bisschen komisch dort. Aber das war nur zu Testzwecken da. Vielleicht wollen wir den Schwierigkeitsgrad erhöhen und neue Gegner hinzufügen. Wir könnten unseren Hauptcharakter, weißt du, den Speer zeigen lassen, wenn wir wollen, dass er da ist und nicht irgendwie armlos Aber ich meine, es funktioniert für das, was es jetzt ist. Und wir können mehrmals aufsteigen. Es ist natürlich noch nicht bereit für die vollständige Veröffentlichung. Dort gäbe es noch viel zu tun, aber im Grunde funktioniert alles wie beabsichtigt. Das Spiel ist vorbei. Da ist unser Highscore. Vielleicht könnte das Hauptmenü einen Soundtrack gebrauchen , also könnte ich noch ein Video aufpolieren, um den Kurs irgendwie aufzuräumen, aber das ist so ziemlich alles. Ich hoffe also, dass ihr alle bis zum Ende viel gelernt habt. Ich weiß, das war ein ziemlich langer Kurs, 11 Stunden plus Gesamtbearbeitungszeit. Also, ich meine, wenn du hierher gekommen bist und alles verfolgt hast und dein Spiel so läuft, wie es ist, ich meine, gute Arbeit, denn das war eigentlich ziemlich viel. Okay, vielen Dank, dass ihr euch grob gesagt, das Ende meines Skript-Survival-Kurses, GD-Skript in Gadot 4.4, angeschaut das Ende meines Skript-Survival-Kurses, GD-Skript in Gadot 4.4, GD-Skript in Gadot 4.4 61. P60 Polierskript Überlebende ~ Spielverbesserungen und Debugging: In diesem Video werden wir also versuchen, dem Prototyp unseres Skripts Survivor etwas Feinschliff zu verleihen unseres Skripts Survivor etwas Feinschliff zu Also zunächst, am Ende des letzten Videos, habe ich sieben Fehler in der Konsole Also das ist das Erste, worum wir uns kümmern werden. Jedes Mal, wenn Sie einen Fehler sehen, ist es ein guter Zeitpunkt, ihn zu lösen, debuggen und herauszufinden, was schief gelaufen ist Wir haben also Artikelabholungen, denen kein Artikel tatsächlich zugewiesen ist Ich denke, was hier wirklich praktisch wäre , wäre, Prozent Süd zu sagen, und das geben wir dann hier in Prozent Okay, Sie können also sehen , dass die Fehlermeldung hier nicht so klar ist, wie sie sein könnte Abholung eines Artikels muss es einen Artikel geben, aber wir wissen nicht, welcher Artikel bei der Abholung tatsächlich gescheitert ist. Wie Sie das machen können, steht im D-Skript „Artikel abholen “ am Ende von „Zur Abholung zugewiesen“, geben Sie ein Prozent ein und folgen Sie dann der Zeichenfolge mit einem Prozent selbst Das ersetzt also die Prozentzahlen durch den Knoten, der dann zu einem Knotennamen aufgelöst wird, oder mit dann zu einem Knotennamen aufgelöst wird anderen Worten, welchem Knoten das Objekt eigentlich nicht zugewiesen Okay, lassen Sie uns das noch einmal ausführen. Ich spiele einfach ein bisschen, um zu sehen, ob wir auf neue Probleme stoßen. Okay, also seit den Artikelabholungen und dem Gesundheitsteil heißt es, dass der Artikel nicht auf Bereit gesetzt ist, was komisch ist, weil der AT-Export das auf jeden Fall tun sollte Wenn der Artikel also gleich Null ist, melden wir einen Fehler Oh, okay, richtig, richtig. Also habe ich hier einen Fehler gemacht. Wenn das eine Behauptung wäre, würde das gut funktionieren. Aber was wir eigentlich tun wollen, ist zu sagen, I item ist gleich Null, dann haben wir den Fehler verschoben. Ich war dort immer noch in der Assert-Logik . Also lass uns das durchgehen. Wenn der Artikel Null ist, geben wir einen Fehler zurück. Wenn wir jetzt spielen, sollte es natürlich funktionieren. Andernfalls würde es immer zu einem Fehler kommen. Sie können also im Debugger hier unten sehen, dass es jetzt keine Probleme gibt Ich sammle ein paar Gegenstände. Lass uns Feinde dazu bringen, sie fallen zu lassen, und das sollte dafür gut funktionieren. Bisher scheint es keine weiteren neuen Fehler zu geben. Mir ist hier ein kleines Problem mit dem UI-Layout aufgefallen. Ich denke also, wenn ich hier die Sense nehme, könnte das diese Benutzeroberfläche auf seltsame Weise neu positionieren Oh, okay, genau das ist passiert. Die HB-Box wurde tatsächlich erweitert, um größer zu werden. Um das zu beheben, muss ich entweder die Größe fixieren. Junge, ich sollte es einfach größer machen und das dann nach rechts verschieben. Ich denke, das wäre besser. Okay, für diese Player-Benutzeroberfläche müssen wir sie ein wenig erweitern , damit sie Platz zum Grillen bietet. Also gehe ich in die Player-UI. Und dann nehmen wir den Root-Panel-Container strecken ihn nach rechts aus, sodass er zusätzlichen Platz hat. Ich gehe zur Game Play-Benutzeroberfläche. Lass uns das nach rechts verschieben. Wenn ich jetzt auf Play drücke und wir zufällig unsere Gesundheit aktualisieren und es die Größe ändert, sollte es es eigentlich nicht mehr weiter nach rechts verschieben, weil es bereits Platz für das vollständige Textlabel hat Und ich muss die Größe des Waffenlayouts ein wenig ändern. Ich habe es ein wenig falsch verschoben, also richte ich es einfach nach oben aus, wir drücken auf Play, Spiel starten Okay, und das sieht ziemlich solide aus. In der Welt möchte ich all diese Tonabnehmer standardmäßig entfernen Die waren nur zum Testen. Diese sollten nicht im endgültigen Prototyp enthalten sein, also werde ich sie mit Control X herausschneiden und sie alle auswählen lassen. Und ich glaube, ich möchte das Standard-Gameplay etwas schwieriger machen . Also gehe ich zum Spawner-System und lass uns die Span-Rate erhöhen Also werde ich das am Anfang herunterfahren, um eine höhere Spawn-Rate zu Füge hier auch einen zusätzlichen Punkt hinzu, so ungefähr. Passen Sie den Lenker an, so etwas in der Art. Ich möchte nur die Kurve steiler machen, damit wir mehr Gegner schneller spawnen , sodass ich mit einem intensiveren Gameplay prahlen kann In der Demo. Okay? Und alle spielen. Lassen Sie uns es ein bisschen testen und sehen, wie das läuft. Also werde ich das Spiel starten. Wir wollen, dass unsere Feinde in den Mittelpunkt rücken. Vielleicht sind die Orks etwas zu langsam. Ich könnte die Bewegungsgeschwindigkeit sowohl der Orks als auch des Skeletts erhöhen sowohl der Orks als auch des Es besteht also wirklich kein Grund , es hier einfach zu machen. Okay. Da haben wir also unsere Skelette und die Also werde ich die Bewegungsgeschwindigkeit der beiden erhöhen. Ich werde den Orc-Stat-Controller nachschlagen. Lass uns die Ork-Statistiken ändern. Die Geschwindigkeit kann, sagen wir, 35 sein, und dann gehen wir zum Skelett Sat-Controller-Geschwindigkeit von 60. Ich mache es mir hier einfach schwer und dann kann der MX HP etwa 100 sein. In Ordnung. Und die HP des Orks ist 40. Das ist okay. Lass uns spielen. Spiel starten. Eine Sache könntest du noch hinzufügen, ich werde es hier nicht tun, aber wenn du zu Beginn einen gegnerischen Spawn-Burst hättest, Beginn einen gegnerischen Spawn-Burst würde das anfängliche Gameplay etwas intensiver machen, wenn du das Spiel startest, indem du sofort zehn Typen spawnen würdest, die auf dich zukommen Das könnte helfen. Aber ich denke, das ist ein bisschen übertrieben, nur für den Prototyp Die Werke bewegen sich also etwas schneller, und die Skelette sind jetzt ziemlich Also das wird definitiv viel schwieriger sein. Ich muss die aktuellen HP nehmen und sie am Anfang auf 100 setzen . Okay, vielleicht sind die Skelette sogar ein bisschen zu schnell, ehrlich Okay, also lassen Sie uns die Startpunkte der Spieler, Spieler, Statistik-Controller, Spielerstatistiken, HP auf 100 korrigieren Statistik-Controller, Spielerstatistiken, HP auf 100 Und ich werde die Skelette ein bisschen nerven. Sagen wir Tempo 50. Ich finde das ziemlich fair. Okay, was die Definitionen auf Spielerebene angeht, werde ich den Levelaufstieg auch ziemlich einfach machen. Also nehme ich Level drei und setze das auf fünf. Stufe vier kann zehn XP sein, Stufe fünf kann 15 sein, Stufe sechs kann 20 sein und Stufe sieben kann 25 HP sein. Und dann füge ich einfach noch einen hinzu für 100. Und das wird wie das sein, zu dem du nicht wirklich kommst. Lassen Sie uns sogar noch einen hinzufügen. Nehmen wir an, 1.000 neue Leveldefinitionen. Der Grund, warum ich es schwierig mache, ist nur , damit es nicht wirklich passiert. Ich habe das irgendwie vermasselt Das war Level 1.000 braucht zehn XB. Das ist nicht das, was ich will Was ich wollte, und lassen Sie uns das streichen, ist, dass Level 9 eine Leveldefinition sein wird bei der 1.000 EXP benötigt werden, fügen Sie das hinzu Das macht es einfach so , dass ich diese Skalierung in der Prototyp-Demo nicht einplanen muss Skalierung in der Prototyp-Demo nicht einplanen Für den Moment wäre es einfach etwas übertrieben. Also lass uns auf Play klicken und ich werde sehen, wie das Spiel läuft. Starte das Spiel und wir warten, bis die ersten Feinde erscheinen. Okay, ich denke, am Anfang ist es etwas zu einfach. Ich möchte, dass es schnell intensiv wird. Ich denke also, ich werde diesen sofortigen Spawn von zehn Typen Also, sagen wir mal bei Export V, die ersten Spawns, und ich setze das so ein, dass N gleich Die Welt wird sich auf das Spawner-System beziehen, also auf das Spawner-System Und dann auf „Bereit“ sage ich, Anfangsspanne Dann sagen wir Spawner-System. Lass mich sehen. Wie hießen die Funktionen? Zufälliger Spawn. Und rufe ich das zehnmal an? Halte durch. Okay. Ja, und es sieht so aus, als müsste ich das zehnmal anrufen oder so oft wie viele Anfangsspannen Also für eine Weile werden wir Spaorsystem Dot Random Span nennen Also zehn anfängliche Spawns, das sollte uns dazu bringen, zu Beginn des Spiels zehn Typen zu spawnen zehn Typen zu Okay, vergiss nicht, das Sponsorensystem in der Welt einzurichten das Sponsorensystem in der Welt Also weise das Sponsorsystem zu. Direkter Knotenverweis, lassen Sie uns auf Play klicken. Und wenn das funktioniert, werden wir zu Beginn des Spiels zehn Typen haben , was es viel schwieriger machen sollte Okay, ja, das sind eine Menge Leute für den Anfang des Spiels Also müssen wir sie einfach alle vermeiden. Das könnte tatsächlich zu schwer sein, ehrlich. Ich werde das auf fünf ändern, und das werde ich im Drehbuch auch auf fünf ändern. Ich denke, zehn Leute am Anfang, wenn man noch nicht einmal aufgestiegen ist, ist es einfach eine Menge , auf einmal fertig zu Okay, wir haben jetzt also unsere fünf Leute. Holen wir uns ein XP. Ich werde mit dem Syth aufrüsten, das gibt uns eine zusätzliche Möglichkeit, Feinde zu treffen. Jetzt ist es viel einfacher Und ich werde hier einfach weitermachen. Lass uns ein paar Upgrades besorgen, da wir die EXP-Kurve viel einfacher gemacht haben, dann sollten wir in der Lage sein, ziemlich einfach aufzusteigen Aber ich muss sagen, wenn die Geschwindigkeit der Gegner erhöht wird, ist es definitiv viel schwieriger, ihnen auszuweichen, also sollten Sie das im Hinterkopf behalten Lasst uns den Speer weiter verbessern. Ich denke also, ab einem bestimmten Level trifft der Speer zwei Typen gleichzeitig . Er ist schon da Ein Speer der Stufe drei kann zwei Typen treffen. Was definitiv ein riesiges Upgrade ist. Ich gehe hier gerade das Gameplay durch. Die Skelette bei Geschwindigkeit 50 sind ziemlich robust. Tempo 60 für die Skelette wäre definitiv zu viel. Lass uns einfach mit dem Speer weitermachen. Aufgrund der aktuellen Einstellungen habe ich eigentlich keine Ahnung, habe ich eigentlich keine Ahnung ob der Speer oder die Sense Wahrscheinlich wäre die Sense bei großen Gruppen wie diesen besser geeignet, weil sie, weißt du, sie alle gleichzeitig treffen kann Aber manchmal ist ein einzelnes Ziel auch wichtig. Ich meine, wir fangen gerade erst an, wie man das Spiel spielt. Das sind also eine Menge Leichen, und irgendwann werden sie mich irgendwie erwischen Wir können ein kleines Problem erkennen, nämlich diese Art von Klumpen, die zu sehr zusammenfallen. Ich möchte also, dass sie sich nicht übereinander stapeln, aber ich denke, ihre Kollisionsformen sind momentan wahrscheinlich zu groß Das macht sie irgendwie unfähig, sich zu bewegen. Wir stoßen also tatsächlich auf ein nettes Problem, das wir beheben können. Lass uns das Spiel unterbrechen und dann nehme ich die Skelette Nehmen wir bei allen Szenen die Kollisionsform und ich werde sie stark verkleinern Lass uns das wie eine Zwei machen und dann gehen wir zum Ork. Wir nehmen seine Kollisionsform an. Das ist die Kollisionsform des Grundcharakters . Nehmen wir diese Kollisionsform, erweitern sie und setzen sie ebenfalls auf zwei. Wenn wir das Spiel unterbrechen, wenn das richtig funktioniert, und ich denke, das ist es auch Ich kann nicht 100% sagen. Da ihre Kollisionsform kleiner ist, verklumpen sie weniger Aber ja, es ist immer noch ziemlich schwer, wenn so viele Typen auf dich zukommen Wenn es auch Projektile gäbe, dann hast du im Moment definitiv ein ziemlich schwieriges Spiel Damit ich noch ein paar Sachen besorgen kann. Lass uns diesmal die Sense aufrüsten. Lass uns das Spiel einfach über den Bildschirm spielen. Ich könnte wahrscheinlich eine Weile herumlaufen, aber wir wollen nur überprüfen, ob alles noch funktioniert, mit dem fruchtigen, soliden Prototyp des Spiels . Und lass uns zum Hauptmenü gehen. Wir haben unsere Zeit überlebt. Ich glaube, ich muss das ein bisschen nach links bringen , damit in diesem Fall Platz für das Komma ist . Abgesehen davon finde ich, dass wir ziemlich gut aussehen. Also im Hauptmenü, also werde ich das einfach ein bisschen nach links erweitern, alles in einer Zeile zusammenfassen. Das wird besser aussehen. Und vielleicht mache ich auch die Musik im Hauptmenü an. Also klicke ich mit der rechten Maustaste auf einen Knoten. Lass uns AudioStream Player machen, nicht zwei D, denn ich meine, es gibt jetzt keine Zwei-D-Welt Wir schauen uns nur das Spielmenü an. Laden wir schnell unseren AudioStream, so.p3, weil ich ihn im Projekt suchen muss Okay, also fügen wir es jetzt aus dem Audioordner zum Audio jetzt aus Wir haben drei Red Hearts Box Jump. Wir verwenden das einfach auch für das Hauptmenü. Ich setze mir Kopfhörer auf, damit ich das selbst testen kann. Lass uns spielen. Oh, ich habe nicht wirklich Audio abgespielt. Okay, also lass uns die automatische Wiedergabe machen. Ja. Und dann spiel. Okay, eigentlich will ich in der Hauptspielwelt nachschauen und sehen, wie laut die ist. Es sind -40 Dezibel. Okay, ich möchte sogar, dass es Hauptmenü etwas leiser Also machen wir das auf -45 Dezibel. Ich drücke Play Teste es aus. Okay, und dann gehen wir zu Spiel starten. Hier ist es etwas lauter. Vielleicht ist die Endgame-Musik , die ich mache, auch etwas lauter Okay. Also die Endgame-Welt, ich nehme das und setze es auf minus 35. Ich glaube, ich habe es während des Kurses sehr leise gemacht , weil ich einfach nicht wollte, dass es zu Störungen kommt , wenn ich darüber gesprochen habe Okay, lass uns auf Play klicken. Wir können das Spiel starten. Okay, das ist gut. Ein weiterer Soundeffekt, den ich vielleicht hinzufügen möchte, ist jedes Mal, wenn wir den Level-Up-Auswahlbildschirm aufrufen. Ich denke, das könnte einen Soundeffekt gebrauchen. Abgesehen davon finde ich, dass wir gut aussehen. Gehen wir also zum Level-Up-Auswahlbildschirm. In Ordnung, klicken Sie hier auf AudioStrem-Player hinzufügen. Lassen Sie mich sehen, ob wir im Projekt einige gute Soundeffekte Es wird also im Audio-UI-Menü sein . Klar, lass mich nachschauen. Okay, benutze den Artikel, als würde er funktionieren. Also nehme ich den Audio-Stream-Player hierher. Wir werden einen gebrauchten Artikel einpacken. Dies wird nicht automatisch abgespielt, also muss ich zur LevelUp-Auswahl gehen Wir werden ein Export-Var-Popup hinzufügen. AudioStream, der ein AudioStream-Player sein wird. Also sagen wir Pop-up Audiostream Dot Play, und ich muss nur den Export korrigieren Okay, und dann stellen Sie sicher, dass Sie den Popup-AudioStream zum Export hinzufügen Popup-AudioStream zum Export Also müssen wir das hinzufügen. Wir könnten bei Ready Assert machen, wenn wir wollen, dass das Assert-Popup AudioStream Denken Sie daran, den AudioStream-Player so einzustellen er Sound abspielt Okay, jetzt drücken wir auf Play. Wir können zu „Spiel starten“ gehen. Und lasst uns testen, indem wir einen Feind besiegen, wir steigen auf. Und dann nehmen wir unser Upgrade. Die Musik geht weiter. Und ich finde, das fließt ziemlich gut. Es ist auf jeden Fall schön, einen echten Soundeffekt für den Veo Up zu haben. Also lass uns dieses Mal mit Syth weitermachen. Der Syth führt hier definitiv Krieg. Es könnte sogar OP sein. Okay, also Syth vier, lass uns sehen, wie das läuft. Definitiv, es ist wirklich schwer. Das ist eine große Sache. Da es sich im Grunde um ein AOE handelt, sollte es wahrscheinlich nicht so viel Schaden anrichten, seien wir ehrlich Okay, ich glaube, ich habe dort genug gesehen. Ich werde einfach den Speer polieren. Und dafür sorgen, dass es mehr Spaß macht, den Speer tatsächlich zu benutzen. Also lasst uns auf den Spieler, die Speerwaffe, losgehen. Lassen Sie uns mit der Szenendefinition beginnen. wir können es einfach aufpolieren denke, wir können es einfach aufpolieren, so sehr wir Stufe eins kurz. Wir können das als Standard belassen. Stufe zwei, drei, vier, fünf. Lass uns sehen. Für Level zwei lasse ich es einfach 20 bis 30 Schaden verursachen und dann wird es abgekühlt. Ja, wir können 0,9 machen. Stufe drei wird zwischen 30 und 35 liegen. Ich denke, der Speer kann auf Stufe zwei auch zwei Treffer erzielen. Das ist in Ordnung Und dann Level drei, wir werden 30 oder 40 Schaden anrichten. Okay, das Maximum trifft zwei, und dann erhöhen wir die Projektile auf Stufe vier auf zwei, und das ergibt 35 bis die Projektile auf Stufe vier auf zwei, 45 Schaden bei einer Abklingzeit von 0,8. Und dann lasst uns 40 bis 45 Schaden anrichten. Es kann schneller gehen. Lass uns den Cooldown auf 0,6 stellen. Die Projektile können sein, warum nicht? Sagen wir einfach drei Projektile. Das klingt ziemlich verrückt, aber hey. Und dann mache ich einen kurzen Abstecher mit dem Speer. Mal sehen, ob der Speer überhaupt mit der Sense mithalten kann. Okay, mehr Speere. Das sollte uns zwei Projektile geben. Das sollte viel besser Es war ein bisschen schwierig, auf Level vier zu kommen. Ich werde das nicht zu sehr ausbalancieren, aber ich wollte es zumindest erträglich machen Oh Gott. Das Laichen wird langsam lächerlich Oh, ich habe vergessen, die Musik zu loopen. Okay, öffne die Spielwelt. Das ist ziemlich wichtig. Also Spielwelt. Öffnen wir diese Szene. Wir haben den Audio-Stream-Player. Wir wollen diese Musik nehmen und die Schleife checken. Also ich denke, das müssen wir im Projekt machen. Lass uns drei machen. Doppelklicken Sie darauf und aktivieren Sie das Looping Ordnung. In der Nähe. Und dann Autoplay also auf Ihrem Audio-Stream-Player Lassen Sie uns also auf Ihrem Audio-Stream-Player nach Looping on für das Audio suchen Das sollte für alle Fälle auch auf dem Hauptmenübildschirm sein. Also hier die Parameter, in der Endlosschleife, und dann werde ich das Spiel unterbrechen Also das fängt erst an, wenn wir wieder da rein sind. Also, seit wir Level 5 mit Speer erreicht haben, können wir Speer nicht mehr auswählen ist gut, das noch einmal zu überprüfen und sicherzustellen, dass es nicht ins Stocken gerät, wenn man versucht, Level sechs zu erreichen Also können wir uns natürlich immer noch für die Sense entscheiden. Okay. Und ich werde mich an diesem Punkt einfach sterben lassen. Ich denke ja. Alles scheint ziemlich in Ordnung zu sein. Oh, und der Highscore-Bildschirm hier, falls der immer noch nicht richtig angezeigt wird, lassen Sie uns hineinspringen. also für die Highscores sicherzustellen, dass hier genügend Platz vorhanden Lassen Sie uns also für die Highscores eine Mindestgröße festlegen, um sicherzustellen, dass hier genügend Platz vorhanden ist. Ich werde diesen Wert auf 60,0 setzen und dann die Highscore-Basis nach links erweitern Okay, nimm auch das Mengenetikett und lass uns eine Mindestgröße von 60 angeben, okay? Und wir können die Highscores nehmen und sie nach links noch größer machen. Ordnung. Und dann drücken Sie Play. Und achte nur darauf , dass die Highscores nirgends über den Rand gehen. Das wäre also gut für mindestens eine weitere Ziffer, denke ich, ohne die Kante zu überschreiten und zu wickeln oder so. Okay, zum jetzigen Zeitpunkt denke ich, dass der Prototyp relativ ausgefeilt ist. Ich bin mir sicher, dass wir Änderungen am Code und an den Inhalten vornehmen können , um sie dem Spiel hinzuzufügen und es einfach zu einem vollwertigen Spiel zu machen Aber was den Kurs angeht, der die Grundlagen zeigt, wie man das alles einrichtet, ein Survivor-ähnliches Spiel und GD Script Gudo 4.4. Ich denke, das ist so ziemlich alles, was es zu Ich hoffe, es hat euch wirklich Spaß gemacht Long bis zum Ende zu verfolgen Es mag ein paar kleine Update-Videos geben, aber das ist so ziemlich alles. Nochmals vielen Dank, dass Sie sich Iben Chris angesehen haben, und ich werde euch in meinen zukünftigen Videoinhalten sehen