Godot, 1000 kleine Dinge

Kürzlich entdeckte die Godot-Engine, eine Open-Source-Game-Engine. Ich teile einige Tricks und Notizen, hauptsächlich aus dem 3D-Bereich, Code oder allgemeinen Punkten.





Godot hat im Allgemeinen den Ruf, eher eine 2D-Engine zu sein, die recht gut ausgearbeitet wurde, aber vor nicht allzu langer Zeit ermöglichen uns 3D-Funktionen, 3D-Spiele zu erstellen. Vor allem, wenn Sie in der Lage sind, einige Dinge selbst zu optimieren, machen Sie kein zu schweres und komplexes Spiel, und Sie sind auch mit den aktuellen Renderoptionen zufrieden. Oder Sie können auf zukünftige Optimierungen und das Erscheinen von Vulkan warten.



Der Motor ist sofort einsatzbereit und verfügt über einige physikalische Eigenschaften, einschließlich Gelenke und Radfahrzeuge. Es gibt keinen eingebauten Terrain-Editor, aber Sie können das Plug-In verwenden, aus speziellen Programmen importieren oder einfach wie ein Netz aus einem 3D-Paket. Im letzteren Fall müssen Sie die Landschaft aus Gründen der Leistung unabhängig voneinander in Blockfragmente schneiden und diese höchstwahrscheinlich für Kollisionen zu getrennten Netzen machen. Bei den Maschen für die Form der Kollision der Landschaft müssen Sie das Modell beim Export aus dem 3D-Paket triangulieren, damit keine visuellen Inkonsistenzen auftreten. Eine der einfachsten Möglichkeiten, dies in Blender zu tun, besteht darin, das Netz im Collada-Format (.dae) zu exportieren. Standardmäßig ist ein Triangulations-Kontrollkästchen aktiviert.

Manchmal muss ein Modell von Blender in Godot um 180 Grad gedreht werden. Seien Sie also nicht überrascht, wenn Ihr Gelände nicht sichtbar ist - höchstwahrscheinlich wird es von Normalen in die falsche Richtung gedreht.



Godot praktiziert den Ansatz „Alles ist eine Szene“ und ist auf die Baumstruktur der Elemente ausgerichtet. In der Praxis bedeutet dies, dass der Ebene neue Objekte als Verzweigungen zu bereits darauf vorhandenen Knoten hinzugefügt werden. Sie können in Fertighäuser umgewandelt und separat geöffnet werden, als wäre es ihre separate kleine lokale Welt. Daher ist es sehr praktisch, alle Arten von gespeicherten zusammengesetzten Objekten zu bearbeiten. Der einzige Moment besteht darin, dass Sie, wenn beispielsweise Licht auf Ihre Ebene eingestellt wurde, diese Beleuchtung nicht sehen und beim Einrichten seiner Materialien nicht verstehen, wie sie aussehen Licht. Dieses Problem kann auf verschiedene Arten gelöst werden, indem beispielsweise zum Ebenenfenster gewechselt und die mit dem Charakter vorgenommenen Änderungen ausgewertet werden, nachdem seine Szene dort gespeichert wurde. Oder werfen Sie die Lichtquelle mit dem Charakter nur vorübergehend in das Fertighaus.





theEnergy, . Area, , , .



Wenn Sie bei Sprachen die Low-Level-Methode nicht berücksichtigen, sind die häufigsten Optionen die Skriptsprachen GDScript und C # sowie die visuelle Skripterstellung für etwas Einfaches. GDScript ist besser in die Engine integriert, verfügt über mehr Beispiele, erfordert nicht den Start einer externen Umgebung, und in Bezug auf die allgemeine Struktur geschieht hier alles wie in der C # -Version - Deklarieren von Variablen, Aufrufen einer Initialisierungsfunktion, einer Prozessschleife, einer physischen Prozessschleife usw. Daher ist es sinnvoll, GDScript als primäre Entwicklungsskriptsprache zu wählen. Wenn wir zu lokalem C # wechseln, erhalten wir nur eine größere Genauigkeit und Detailgenauigkeit des Datensatzes, verlieren an Prägnanz, erhöhen jedoch die Verständlichkeit und Kontrolle über die Situation - geschweifte Klammern anstelle von Tabulatoren, Zeilenende-Markierungen und formellerer Eingabe.





Code, der an das oben genannte Objekt angehängt ist (in GDScript). Es wird eine Bezeichnervariable eingerichtet, deren Wert im Editor festgelegt werden kann. Als nächstes eine einmalige Initialisierungsfunktion, bei der nichts Besonderes passiert (und die gelöscht werden konnte). Im Folgenden wird eine Signalhandlermethode beschrieben, mit der ein Objekt entfernt wird.



Um globale Variablen sowohl in GDScript als auch in C # zu verwenden, müssen Sie ein globales Skript / Skripte zum Start in den Projektparametern hinzufügen, auf deren Variablen global zugegriffen werden kann.

Auch in Godot gibt es eine Einschränkung - es kann nicht mehr als ein Skript für jedes Objekt geben. Dieser Moment kann jedoch umgangen werden, indem beispielsweise das zweite Skript an das untergeordnete Objekt gehängt wird.



Signale



Um Daten zwischen Knoten in Godot auszutauschen, können Sie auch die Hierarchie verwenden, da Objekte wie Zweige eines Baums miteinander verbunden sind. Dieser Ansatz hat zwar seine Tücken, da in unserem Spiel die Hierarchie dynamisch geändert werden kann. Darüber hinaus ist es eine Sache, sich auf die Hierarchie innerhalb derselben Szene zu beziehen. Wenn Sie jedoch eine Szene innerhalb einer Szene innerhalb einer Szene haben, gibt es einige Schwierigkeiten, auch wenn es nur darum geht, zu verstehen, was passiert.

Eine Möglichkeit, all dies zu verwalten und sich nicht zu sehr an eine bestimmte aktuelle Hierarchie zu binden, sind Signale. Eine bestimmte Anzahl allgemeiner Signale ist bereits voreingestellt. Sie können in das Objektsignalfenster schauen, um eine Zeile mit der Verarbeitung des Empfangs eines dieser Signale an das Skript desselben Objekts oder eines anderen Objekts mit einem Skript innerhalb der Szene anzuhängen. Wenn Sie Ihr eigenes Signal erstellen müssen, können Sie dies folgendermaßen tun:





Wir starten das Signal. Wir senden



es im selben Skript aus, wenn Sie auf eine Schaltfläche oder andere Bedingungen klicken. Damit ist



alles in Ordnung, bis Sie Signale von einer Szene zur anderen übertragen müssen. Zum Beispiel, weil Sie eine Ebene aus Szenen codieren und wissen müssen, wann Sie die aktuelle Ebene zerstören und beispielsweise die nächste zusammenstellen müssen.

In diesem Fall können Sie dem Objekt einen Signalhandler hinzufügen, der direkt zum Zeitpunkt der Erstellung des Levels durch den Code ein Signal an die Root-Szene sendet. So starten wir sozusagen einen Spionageagenten in diesem generierten Zweig und hören zu, was er uns sagt.





Zum Zeitpunkt der Level-Assemblierung finden wir ein Raumschiff darauf und fügen einen Signal-Listener hinzu, der die Methode angibt, mit der die Nachrichten dieses Signals verarbeitet werden.



Sie können dem Signal auch einige Variablen hinzufügen, was sehr nützlich sein kann. Anstatt beispielsweise verschiedene Signale für das Objekt zu starten, können wir eines ausführen, aber wir senden es mit unterschiedlichen Parametern und verarbeiten es zusätzlich nach dem Empfang.





Und hier ist die Beschreibung der Methode selbst, die wir oben begonnen haben. Er empfängt ein Signal und verarbeitet die damit gesendete Variable.



Eine weitere nützliche Sache, die die Anzahl unnötiger Signale reduziert, ist, dass anstelle eines persönlichen Signals ein Objekt an ein anderes klopfen kann, so dass er selbst das bereits darin enthaltene Signal senden kann. Beispielsweise empfängt eine Explosion ein Signal, dass sie einen Spieler berührt hat, und im Handler dieses Signals findet sie heraus, ob der Spieler über eine Selbstzerstörungsmethode verfügt, und startet sie, wenn sie erkannt wird. Der Spieler sendet bei dieser Methode ein Signal an die Wurzelszene, dass er tot ist. Im Root-Szenen-Skript löscht der Todessignal-Handler des Spielers die Welt und stellt das Spielmenü zusammen.





Ein Ereignis tritt ein und wir prüfen, ob das Objekt, das die Zone betreten hat, die richtige Methode hat.





, , . , , .



CSG-





Eines der nützlichen 3D-Werkzeuge in Godot sind konstruktive Grundelemente mit fester Geometrie. Einfach ausgedrückt sind dies Objekte, die boolesche Operationen unterstützen - Schnittmenge, Ausschluss, Vereinigung. Zusätzlich zu den Grundelementen gibt es ein universelles CSG-Netz, für das ein beliebiges Netz als Form festgelegt werden kann.







Der CSG Combiner-Dummy wird zur Verwendung in der Hierarchie benötigt, um die Priorität der Anwendung von Operationen zu steuern, wenn dies beim Sammeln einer komplexen Struktur erforderlich ist.





Ein Kugelpaar, aus dem Kinderkugeln geschnitzt werden.



Die Hauptanwendung von CSG ist die Bequemlichkeit und Einfachheit der statischen Prototyping-Ebene und einiger ihrer Elemente. Tatsächlich können Sie ein Netz in einem 3D-Paket erstellen und dieselben resultierenden Formen darin wiederholen, es sei denn, Sie müssen dies außerhalb des Spieleditors tun.



Die nächste Anwendung statischer CSGs besteht darin, Zerstörbarkeit und Beschädigung zu simulieren. Dazu müssen Sie CSG-Grundelemente im Ausschlussmodus wie Löcher, "Stummel" und Dellen anordnen und dann vorübergehend ausblenden, einschließlich der Sichtbarkeit zum richtigen Zeitpunkt. Die Einschränkung hierbei ist, dass wir nur die Oberfläche des CSG-Objekts „beschädigen“ können. Außerdem muss der „Schaden“ zunächst als Kind oder durch Code als Kind angehängt werden. Diese Option hinsichtlich der Anpassungsflexibilität gewinnt jedoch bereits im Vergleich zu dem im 3D-Paket vorbereiteten zerstörbaren Objekt erheblich.





Im Ausschlussmodus sind 3 Zylinder in die Brücke eingebaut. Während sie die ganze Brücke versteckt sind.



Wenn aktiviert, wird der Bereich, den sie ausschließen, ausgeschnitten.



Als nächstes bewegen wir CSG. Durch Code oder aufgezeichnete Animation. Im Allgemeinen können Sie mit dieser Methode einige Effekte implementieren. Es ist jedoch sehr wünschenswert, dass sich solche Animationen nicht in einer Schleife auf der Bühne drehen. Mehrere animierte CSGs können die Leistung erheblich beeinträchtigen. Außerdem optimiert Godot nicht alle Dinge. Wenn Sie animierte CSGs nicht selbst deaktivieren, verbrauchen sie weiterhin die Leistung außerhalb der Sichtweite der Kamera.

Trotzdem sind die Effekte von animierten CSGs bereits schwer durch 3D-Paketlösungen zu ersetzen, sodass Sie möglicherweise daran interessiert sind, sie zu verwenden (zumindest, wenn Sie kein erweitertes 3D durch Code zeichnen möchten). Die Hauptsache ist, die richtige Verwendung für sie zu finden. Es ist am besten, sie an bestimmten Stellen punktweise zu verwenden, einschließlich der Animation auf dem Auslöser. Als Effekt des Öffnens des Durchgangs oder eines anderen einmaligen Spezialeffekts. Je einfacher die Form von CSG-Objekten ist, desto besser. Und sie üben die Hauptberechnungslast genau im Prozess des Kontakts in Bewegung aus, außerdem gibt es keinen besonderen Unterschied, welches Objekt relativ zu einem anderen bewegt wird.





Es gibt einen Moment im Video, in dem die Maschine durch ein Loch in der Brücke fällt, wenn die animierte CSG-Kapsel mit einem Modell der Brücke durch das CSG-Netz läuft.



Multimesh





Wenn Sie ein Netz in großen Mengen replizieren müssen, z. B. um Steine ​​oder Bäume über die Ebene zu streuen, ist der Knoten MultimeshInstance hier hilfreich.

Nach dem Hinzufügen des Multimesh zur Szene müssen Sie angeben, über welches Objekt Kopien verteilt werden sollen und was als Beispiel für Klone verwendet werden soll. Unterwegs können Sie die Größe der Klone und ihre Anzahl auswählen. Wenn ein Multimesh "gebacken" wird, handelt es sich um eine Reihe von Klonen, und die Ziele, mit denen er generiert wurde, können gelöscht werden, wenn sie nicht mehr benötigt werden.





Eine Schaltfläche zum Auswählen von Multimedia-Zielen wird bei Auswahl im Editorfenster oben rechts angezeigt. Wenn Sie darauf drücken, wird dieses Fenster mit den Einstellungen für die Generierung ausgeblendet.





Hier haben wir zwei Objekte als MeshInstance-Knoten zur Szene hinzugefügt. Als nächstes klonen wir das linke Objekt nach rechts.





Wir bekommen Multimesh. In dieser Situation wurden 10.000 Klone in den Einstellungen festgelegt. Übrigens, wenn es 3-4 Tausend von ihnen gäbe, wäre das Ergebnis visuell nicht sehr unterschiedlich.



Das "gebackene" Multimesh kann an eine beliebige Stelle verschoben werden. Außerdem verfügt es über einen Parameter für die sichtbare Instanz, der anfänglich die Anzahl der während der Generierung angegebenen Klone anzeigt. Durch Ändern dieses Werts können Sie steuern, wie viele Klone gerade angezeigt werden. Standardmäßig gibt es -1, dies ist jedoch ein spezieller Wert für die Anzeige des Maximums an Klonen. Wenn Sie 10 setzen, gibt es 10 Klone. Wenn 100, dann 100. Wenn das Maximum 50 war, dann bei 100 und bei 1000 und bei -1 bleiben sie 50.

Mit dieser Multimesh-Funktion können Sie Spezialeffekte erstellen, indem Sie den Parameter Visible Instance durch Code oder aufgezeichnete Animationen animieren. Für eine genauere Kontrolle über die Dichte von Klonen können Sie das 3D-Paket verwenden, um ein separates Netz mit einem festen Netz genau dort zu erstellen, wo die maximale Dichte von Klonen benötigt wird, und an den Stellen, an denen sie nicht vorhanden sein sollten, nicht mit Polygonen zu bedecken oder Brüche in ihnen zu machen.





Wir setzen die sichtbare Instanz auf 500 und die Fülldichte sinkt dramatisch.



Verschiedenes





Die Steuerung in Godot kann konfiguriert werden, indem Sie das Projektelement im oberen Bereich des Editors öffnen . Nächste Projekteinstellungen , Registerkarte Aktionsliste .





Sie können sehen, wie die Standardschaltflächen aufgerufen werden, damit Sie wissen, auf welche Namen Sie im Code verweisen müssen. Und fügen Sie auch Ihre eigenen hinzu.



Der Standardname für die PgUP-Schaltfläche lautet beispielsweise "ui_page_up". Sie können das Drücken im Code verarbeiten, indem Sie die folgende Zeile in GDScript schreiben - wenn Input.is_action_pressed ("ui_page_up"):

Wenn für ein einzelnes Drücken eine Aktion erforderlich ist, sollte is_action_pressed durch is_action_Just_pressed ersetzt werden. Das Ende des Drückens - gedrückt wechselt zu freigegeben.



#



Wenn Sie das Flackern eines Materials animieren müssen, können Sie dies über einen benutzerdefinierten Shader tun. Wählen Sie dazu New ShaderMaterial als Objektmaterial aus. Wählen Sie anschließend VisualShader









in einem leeren Feld aus.





Klicken Sie darauf. Der visuelle Editor wird unter dem Editor geöffnet.



Fügen Sie einige Knoten hinzu, zuerst Input - All - Time , dann Scalar - Common - ScalarFunc , und legen Sie ihn beispielsweise in der Dropdown-Liste fest Sünde. Im Prinzip gibt ein solches Design bereits ein Flimmern zwischen Schwarz und Weiß, aber zum Besseren fügen Sie einen weiteren Skalarknoten hinzu - Common - ScalarFuncund wählen Sie dort Abs. Wir verbinden die Knoten miteinander (beachten Sie, dass Sie durch Klicken auf das geschlossene Auge jedes Knotens diesen öffnen und sehen können, wie sich das Bild in jeder Phase ändert) und verbinden sie mit dem Alpha-, Emissions- oder Albedo-Kanal. Das war's, unser Objekt flackert jetzt.







Dies ist natürlich alles andere als der einzige Weg, aber eine der sehr einfachen Möglichkeiten. Und wenn Sie möchten, dass das Flimmern farbig wird, müssen Sie einige Knoten mit Farbe erstellen, sie in einem speziellen Knoten (mit Blick auf Albedo) mischen und die Ausgabe dieser Knotenkette, die wir oben gesammelt haben, daran anhängen. Somit wirkt diese Kette als Mischfaktor für diese Farben.



#



Um den ausgewählten Knoten in eine separate Szene zu verwandeln, klicken Sie mit der rechten Maustaste darauf und wählen Sie die Option „Zweig als Szene speichern“. Legen Sie dann einen Namen für diese Szene fest. Danach wird neben dem Knotennamen das Symbol „Im Editor öffnen“ angezeigt, von dem aus Sie die resultierende Szene in einem neuen Fenster bearbeiten können.

Wenn Sie zum Beispiel die umgekehrte Manipulation durchführen möchten, um die Objekte des gespeicherten Zweigs in die aktuelle Szene zu bringen, um sie irgendwie neu zu erstellen oder zu ändern, klicken Sie mit der rechten Maustaste auf einen solchen Knoten, der die Szene in sich verbirgt, und wählen Sie das Element "Lokal machen". Die gespeicherte Szene, die er war, wird nicht gleichzeitig zerstört.



#



Um globale Variablen zu verwenden, müssen Sie ein Skript erstellen und in das automatische Laden werfen: Projekt -Projekteinstellungen - Start . Ein Singleton muss überprüft werden.





Der Inhalt des SaveTheWorld-Skripts, dessen Variablen wir als global verwenden möchten. Momentan werden hier ein bestimmter Gesundheitsindikator und eine Reihe feindlicher Staaten angekündigt, die beim Initialisierungsschritt ausgefüllt werden.



Um über den Code auf diese globalen Variablen zuzugreifen, müssen Sie zuerst einen Verweis auf den Singleton abrufen und dann seine Variablen verwenden:





Suchen Sie unsere SaveTheWorld und überprüfen Sie dann, ob der Status dieses bestimmten Feindes Null ist. Wenn ja, wird der Feind entfernt.



UPD. Sie können direkt über seinen Namen auf die Variablen eines Singletons zugreifen, dh im obigen Beispiel müssten wir keinen Link verwenden, und anstelle von main.enemy_arr [myID] verweisen wir auf SaveTheWorld.enemy_arr [myID]. Sie müssen jedoch sicherstellen, dass dieser Knoten beim Start ein Häkchen in der Spalte "Singleton" hat.



#



Der Szene wird ein AnimationPlayer-Knoten hinzugefügt, um Animationen aufzunehmen und abzuspielen. Es kann sich an einer beliebigen Stelle in der Hierarchie befinden. Um ihm die Möglichkeit zu geben, Animationen aufzunehmen, müssen Sie auf die Schaltfläche "Animation" über der geöffneten Zeitleiste klicken und eine neue Animation erstellen.

Danach werden auf jedem ausgewählten Knoten in der aktuellen Szene rechts im Inspektor Schlüsselsymbole angezeigt. Wenn Sie auf die Taste klicken, bietet der Animator an, eine neue Animationsspur hinzuzufügen.







Bewegen Sie als Nächstes den Timeline-Schieberegler zu den gewünschten Punkten. In jedem dieser Punkte ändern wir diesen animierten Wert im Objektinspektor, indem Sie erneut die Taste drücken, sodass dieser Punkt auf der Timeline angezeigt wird. Sie können die verfügbare Zeitspanne im Feld mit der Uhr rechts erweitern. Standardmäßig gibt es 1 Sekunde. Rechts von der Uhr befindet sich eine sich wiederholende Animationsschaltfläche. Unten ist die erste in der Zeile eine der häufig verwendeten Optionen, mit denen der nervöse, diskrete oder kontinuierliche, glatte Charakter der Animation festgelegt wird.

Rechts neben dem zentralen Bereich mit dem Namen der Animation befindet sich die Autorun-Taste. Wenn Sie darauf drücken, wird die ausgewählte Animation beim Start der Anwendung abgespielt. Wenn Sie mehrere animierte Objekte benötigen, die ständig in einer Schleife abgespielt werden, können Sie ihre Spuren in einem AnimationPlayer erstellen, indem Sie eine gemeinsame Animation für sie erstellen. Wenn Sie Animationen für ein bestimmtes Objekt wechseln müssen, können Sie einen separaten AnimationPlayer für dieses Objekt starten und mehrere Animationen für verschiedene Objekte erstellen, während nur eine davon als automatisch gestartet markiert werden kann.



#



Für verschiedene Knoten, z. B. MeshInstance oder CollisionShape, können Sie im Feld Mesh (Shape) aus einer vorbereiteten Liste von Grundelementen auswählen (einschließlich des Ladens Ihres benutzerdefinierten Modells im Fall von MeshInstance).







Für MeshInstance ist eines der teuersten Grundelemente die Kugel und die Kapsel, da sie höchstwahrscheinlich viele Polygone enthalten. Daher ist es für 3D-Partikel besser, ein Polygon, einen Würfel oder ein Prisma auszuwählen. Bei Kollisionen hingegen ist die Form der Kugel am schnellsten lesbar, da sie von den Parametern nur einen Radius hat. Tatsächlich gilt das oben Gesagte nicht nur für Godot, sondern auch für andere Spiel-Engines.

Godot kann auch automatisch eine Kollisionsform für MeshInstance erstellen, indem Sie auf die Schaltfläche Array klicken, die oben rechts im Editor angezeigt wird, wenn MeshInstance ausgewählt ist. Wählen Sie dann aus den vorgeschlagenen Optionen aus, aber in der Regel ist dies für dasselbe Gelände das erste Element - "Erstellen eines konkaven statischen Körpers" (danach wird ein StaticBody-Knoten mit einer genauen darin verschachtelten Kollision an das Objekt angehängt). In allen anderen Fällen, in denen keine besonders präzisen Kollisionen erforderlich sind, können Sie mit unabhängig belichteten CollisionShape-Grundelementen auskommen oder optimale Netze für Kollisionen in einem 3D-Paket sammeln, diese dann über MeshInstance hinzufügen und über die Schaltfläche "Array" eine Kollision basierend auf ihrer Form erstellen.



#



Wenn in einem der numerischen Felder im Inspektor beispielsweise eine bestimmte Zahl zum Parameter hinzugefügt, der Wert multipliziert usw. werden muss, können Sie die folgenden Schritte ausführen: "315-180", "20 + 40", "64 * 5" ... der Herausgeber selbst das Endergebnis der Operation vor Ort berechnet und ersetzt.



All Articles