Visual Logic Editor für Unity3d. Teil 1

Einführung


Hallo liebe Leser, im heutigen Artikel möchte ich auf ein solches Phänomen bei der Entwicklung von Anwendungen auf Unity3d als visuelle Entwicklung oder genauer Entwicklung unter Verwendung der visuellen Darstellung von Code und Logik eingehen . Und bevor ich fortfahre, möchte ich gleich klarstellen, dass es nicht um visuelle Programmierung geht. Vom Wort "absolut" gibt es keine Blueprint- Variationen in der Unity-Welt und keine C # -Code-Generationen. Was versteht man dann unter einem visuellen Logikeditor? Wenn Sie an der Antwort auf diese Frage interessiert sind, begrüßen Sie unter Katze.

Artikel in der Reihe:
Visual Logic Editor Teil 2

Was ist ein visueller Logikeditor?


Sehr oft und einige argumentieren, dass Programmierer während der Entwicklung immer viel unterschiedlichen Code schreiben, der viele verschiedene Dinge tut, vom System bis zur Spielmechanik. Wenn der Programmierer "real" ist, wird dieser Code normalerweise vereinheitlicht und isoliert, damit er wiederverwendet werden kann (innerhalb von Unity handelt es sich bei diesem Code um Komponenten, sie sind auch Erben von MonoBehavior ). Es ist nicht schwer vorstellbar, dass es viele solcher Codes geben kann, insbesondere wenn dies nicht das erste Projekt ist. Stellen Sie sich nun vor, wir starten ein neues Projekt und müssen viele schnelle und unterschiedliche Prototypen erstellen. Das Team der Programmierer ist begrenzt und das Ganze ist mit dem Hauptprojekt oder den Hauptprojekten beschäftigt. Spieledesigner sind empört, sie müssen testen, überprüfen, Produzenten laufen um Manager herum und versuchen, einen Programmierer für sich selbst herauszuholen, Geld ist begrenzt, Zeit läuft ab usw.

Auf der anderen Seite der Medaille haben wir (Programmierer) viel Code in Form von Komponenten geschrieben, sie hängen in einer großen Liste an verschiedenen Objekten in der Szene. Und so erweitern wir das Team, stellen einen neuen Programmierer ein, er öffnet die Bühne, um das Problem zu lösen, und ertrinkt in einem Durcheinander von Fragen: Wer verursacht wen, in welcher Reihenfolge, welche Komponente ist mit welcher verbunden und wie usw. Sie sagen vernünftigerweise: „Und Dokumentation? " Es gibt eine Dokumentation (obwohl überhaupt keine Tatsache), aber hier geht es darum, dass die Schwelle für neue Mitarbeiter so niedrig wie möglich und die Zeit für diesen Prozess so kurz wie möglich ist.

Wie können die oben beschriebenen Situationen gelöst werden? Die Antwort im Titel des Artikels lautet Visual Logic Editor. Was ist das Dies ist eine Umgebung, in der Sie verschiedene Komponenten der Logik visuell bearbeiten und ihre Beziehungen (in der „weichen“ Version) konfigurieren sowie Objekte der Szene indirekt von der Szene aus bearbeiten können. Wenn Sie es in einer sagenhaft einfachen Form beschreiben, dann ist es wie in der Kindheit, verschiedene Designs aus Würfeln zusammenzusetzen (nur in unserem Fall sind die Würfel nicht fest miteinander verbunden, entfernen den Boden, unser Design fällt nicht).

Also haben wir die Definition herausgefunden, aber was gibt uns das am Ende?

  • Sie können universelle Designs zusammenstellen, die in Projekten wiederverwendet werden können, wodurch die nachfolgende Routine reduziert wird. Stellen Sie sich eine Art reines Feld vor, das unser Projekt ist. Wir nehmen einfach die zusammengebaute Konstruktion aus einem anderen Spiel, legen sie auf das Feld und fertig.
  • Sie können eine Datenbank mit isolierten „Cubes“ (Mechanik, Logik, Funktion) erstellen, aus denen Personen, die keine Programmierer sind, selbst Konstrukte erstellen können.
  • Es ist möglich, Designs im laufenden Betrieb durch andere zu ersetzen und dadurch das Verhalten der Logik zu ändern.
  • Sie können Konstruktionen im verzögerten Modus verwenden. Wenn der NPC beispielsweise derzeit nicht auf der Welt vorhanden ist, ist auf unserem „Feld“ keine damit verbundene Logik vorhanden.
  • Da unsere Würfel nicht durch starre Beziehungen verbunden sind, können wir sie nach Belieben ein- und ausschalten und beliebig komplexe bedingte und bedingungslose Verzweigungen implementieren.

Klingt das ziemlich gut? Aber was in Wirklichkeit? Wenn Sie den Asset Store öffnen und den Abschnitt Visual Scripting anzeigen , sehen Sie im Prinzip eine große Anzahl verschiedener Plugins. Die meisten davon sind Variationen des Blueprint-Themas der Unreal Engine, d. H. Im Wesentlichen der Codegenerierung. Es gibt praktisch keine Systeme, die den Konzepten eines visuellen Logikeditors entsprechen. Die nächsten Bedeutungen sind:

  1. Spielmacher Ja, es ist ein FSM-Plugin, aber Sie können trotzdem Ihre eigenen Aktionen schreiben. Es ist aus Sicht der Benutzeroberfläche nicht so bequem, aber für bestimmte Dinge ist es sehr gut. Blizzard wurde in Hearthstone nicht umsonst verwendet.
  2. Verhaltensdesigner / MoonBehavior usw. State Tree Plugins. Es ist näher an dem, was oben beschrieben wurde, aber es gibt viele Einschränkungen, schließlich ist der Statusbaum keine vollwertige Logik für die Komponenten.
  3. ICode Dies ist ein Analogon des Spielmachers, das heißt auch eine Zustandsmaschine.

Gibt es einen Ausweg, liebe Leser? Ich habe nur eines gefunden, schreibe mein System, was ich getan habe, aber der Weg dorthin war ziemlich lang und dornig.

Der Weg


Die Idee, ein Plugin für den Visual Logic Editor für Unity3D zu entwickeln, ist schon lange entstanden. Anfangs waren es nur Gedanken, dass es cool wäre, wenn ja. Diese Gedanken tauchten bei der Arbeit an einem Projekt auf, in dem es viele ähnliche Spiele gab, mehr als 20 Teile, die sehr, sehr schnell erledigt werden mussten. Die erste Implementierung war in Bezug auf die Benutzeroberfläche schrecklich, obwohl es uns natürlich ermöglichte, die gesamte Reihe von Spielen mit einer bestimmten Geschwindigkeit erfolgreich zu entwickeln.

Für das nächste Projekt wurde beschlossen, einen vollwertigen visuellen Editor zu erstellen. Aufgrund der geringen Erfahrung war die Implementierung jedoch erfolglos, alles war sehr langsam, die Anzahl der Verbindungen usw. Die Dinge gingen aus dem Rahmen, so dass es unmöglich war, herauszufinden, was und wo (siehe Screenshot und keine Angst).

Bild

Danach wurde die Idee für einige Zeit verschoben. Die folgenden Projekte habe ich bereits mit reinem Code gemacht, aber die Idee schwebte immer noch in meinem Kopf. Nach und nach wurden unter Berücksichtigung früherer Fehler die endgültige (wie mir schien) Vision und Liste der Anforderungen erstellt. Und 2017, nach Abschluss des nächsten freiberuflichen Projekts, habe ich beschlossen, dass ich es mir leisten kann, 6-7 Monate an diesem Plugin zu arbeiten und es in den Asset Store zu stellen (es liegt immer noch und heißt Panthea VS ). Aus der Sicht der Erfahrung bei der Arbeit an einem so komplexen Projekt war alles sehr cool, die finanzielle Seite ist leider traurig, immer noch programmieren und verkaufen zu können, sind zwei verschiedene Dinge. Es war November 2017, nach dem ich meine Motivation ein wenig verlor, mich scheiden ließ, meine Stadt veränderte, mein Leben komplett veränderte und um nicht in Samojedismus zu verfallen, beschloss ich, das Thema des visuellen Logik-Editors aus einem anderen Blickwinkel zu betrachten. Das Ergebnis war uViLEd , das ich kostenlos veröffentlichen wollte. Da ich einen Vollzeitvertrag unterschrieben hatte, musste ich an Wochenenden und Feiertagen daran arbeiten und es dauerte das ganze Jahr 2018 und Anfang 2019. uViLEd ist ein großes Umdenken von Panthea VS , einer vollständigen Überarbeitung des Codes für den Roslyn-Compiler (C # 7+), sodass alles nur ab der Unity3d 2018.3-Version funktioniert.

Hinweis : Panthea VS hat mehrere Projekte gestartet (Android und iOS, insbesondere Levs Truck und Autos). Im Prinzip war die Erfahrung mit der Verwendung erfolgreich, aber in dem Moment, in dem sich herausstellte, dass es eine Sache ist, einen Editor zu schreiben, ist eine andere Sache, zu lernen, wie man ihn richtig benutzt (egal wie seltsam er sich anhört). )

uViLEd und wie man es benutzt


Einführung


Also, was am Ende passiert ist, schauen wir uns zuerst das Bild an und fahren dann fort (es wird mehr Bilder geben).

Bild

Worauf basiert der visuelle Logikeditor?

Bild

Hier:

  • Komponenten - Dies ist unser Code, der die eine oder andere Funktion implementiert, in der Tat ein Analogon von MonoBehaviour . Nur in unserem Fall werden alle Komponenten von der LogicComponent- Klasse geerbt, die wiederum ein ScriptableObject ist .
  • Variablen sind spezielle ScriptableObjects , in denen Daten gespeichert werden dürfen (alle, einschließlich benutzerdefinierter Strukturen und Klassen, Verweise auf Szenenobjekte, Fertighäuser und Assets). Variablen werden benötigt, wenn Daten zwischen Komponenten gemeinsam genutzt werden müssen, dh jede Komponente kann auf eine Variable des gewünschten Typs verweisen, und es wird eine sein.
  • Beziehungen sind eine visuelle Beschreibung, welche Komponenten, wie und in welcher Reihenfolge sich gegenseitig aufrufen. Die Beziehungen zwischen Komponenten werden unter Verwendung von zwei speziellen Feldern der Typen INPUT_POINT und OUTPUT_POINT bestimmt . Eine Verknüpfung wird immer als Ausgabepunkt einer Komponente zum Eingabepunkt einer anderen Komponente gebildet. Diese Verbindungen sind nicht starr, das heißt, sie sind für den Programmierer nicht sichtbar und sie sind auch nicht im Code enthalten. Sie sind nur im Editor vorhanden, und wenn die Szene beginnt, versteht die Logiksteuerung selbst den Code. Wie dies geschieht, werden wir in einem separaten Artikel besprechen.

Alles im Fach - Komponenten, Variablen und Beziehungen - bilden die Logik . Im Allgemeinen ist der Programmierer nicht sehr kompliziert. Er schreibt den Code der Komponenten und Variablen, und der Spieledesigner oder ein anderer (oder derselbe) Programmierer / Scripter bildet die Logik, indem er diese Komponenten in den Editor legt und die Verbindungen und Parameter einrichtet.

Hauptmerkmale von uViLEd


  • Ausführen von Logik (eine Reihe von Komponenten, Variablen und Beziehungen) im verzögerten Modus, einschließlich Starten von einer externen Quelle (Festplatte oder Server)
  • Einrichten von Verbindungen zwischen Komponenten (Anrufreihenfolge, Aktivierung und Deaktivierung)
  • Einfache Integration von Komponenten und anderem Code, einschließlich MonoBehavior-Nachkommen
  • Überschreiben des Erscheinungsbilds von Komponenten im Editor (analog zu CustomPropertyDrawer)
  • Konfigurieren der Komponenteneinstellungen über den Unity3d-Inspektor
  • Fügen Sie der Logik ganz einfach Komponenten über die Drag & Drop-Skriptdatei oder über ein Verzeichnis hinzu
  • Gruppieren von Komponenten im Logikeditor
  • Einstellen der Anzeige von Komponenten im Editor (Inversion, Minimierung, Aktivierung und Deaktivierung)
  • Öffnen des Komponentencode-Editors direkt aus dem Logikeditor
  • Zeigen Sie Debugging-Daten beim Start im Editor direkt im Logikeditor an
  • Skalieren des visuellen Logik-Editors
  • Wenn plötzlich eine große Anzahl von Komponenten in der Logik enthalten ist, besteht die Möglichkeit, diese bei der Auswahl mit Fokus zu suchen (dies gilt für Variablen).
  • Schrittweises Debuggen im Szenenstartmodus im Unity3d-Editor mit Verfolgung aller übertragenen Daten zwischen Komponenten und Variablenwerten
  • Unterstützung für MonoBehaviour-Methoden und Festlegen der Reihenfolge ihres Aufrufs. Hinweis : Hier meinen wir, dass es in SO standardmäßig keine Methoden wie Start, Update usw. gibt. Daher wurde ihre Unterstützung den Komponenten selbst hinzugefügt. Gleichzeitig können Sie mithilfe des ExecuteOrder-Attributs die Reihenfolge konfigurieren, in der Start, Update usw. aufgerufen werden.
  • Unterstützung für Coroutine, async / await und alle Unity3d-Attribute für den Inspektor sowie Unterstützung für CustomPropertyDrawer

Arbeite mit dem Editor


Um mit dem Editor arbeiten zu können, müssen Sie die Szene öffnen und dann den Editor selbst starten.

Bild

Nach dem Starten des Editors initialisieren wir die Szene (die Schaltfläche zum Aktualisieren im Editor). Danach können Sie vorhandene Logik erstellen oder zur Szene hinzufügen.
Nachdem Sie die Logik erstellt haben (eine Datei, die die Komponenten, ihre Parameter, Beziehungen zwischen Komponenten, Variablen und ihren Werten beschreibt), können Sie sie mit Bedeutung füllen. Um eine Komponente oder Variable hinzuzufügen, ziehen Sie einfach das entsprechende Skript in den Bereich des Logikeditors. Eine alternative Option ist die Verwendung eines Verzeichnisses, das automatisch mit dem ComponentDefinition- Attribut generiert wird.

Bild

Nachdem wir der Logik mehrere Komponenten hinzugefügt haben, können diese verschoben werden, auch in Gruppen, oder zu einer visuellen Gruppe zusammengefasst werden.

Bild

Lassen Sie uns genauer betrachten, was wir die Komponente selbst in einem visuellen Editor darstellen.

Bild

Hier:

  • Die Menüschaltfläche der Komponente öffnet ein Dropdown-Menü, mit dem Sie:
    • Aktivieren oder deaktivieren Sie eine Komponente
    • Minimieren Sie die Komponente (dies kann auch durch Doppelklicken auf die Kopfzeile erfolgen)
    • Komponente invertieren (Eingangs- und Ausgangspunkte tauschen)
    • Bereich für Komponentenoptionen ein- oder ausblenden
    • Öffnen Sie den Code-Editor für die Komponente
  • Der Bereich der Komponentenparameter ist der Ort, an dem die Werte der Schlüsselparameter der Komponente angezeigt werden, deren Zusammensetzung vom Programmierer abhängt

Um Parameter (öffentliche Felder oder Felder mit dem SerializeField-Attribut) zu konfigurieren, müssen Sie die Komponente im Logikeditor auswählen und den Unity3d-Inspektor öffnen.

Bild

Hier:

  • In der oberen rechten Ecke befindet sich eine Schaltfläche, mit der Sie die Farbe der Kopfzeile ändern können, die im Logikeditor angezeigt wird
  • Name - Feld zum Festlegen des Namens der Komponenteninstanz
  • Kommentar - Ein Feld zum Festlegen eines Kommentars für die Komponenteninstanz. Es wird im Logikeditor angezeigt, wenn Sie den Mauszeiger über die Komponente bewegen
  • Komponentenparameter - Der Bereich, in dem die Komponentenparameter angezeigt werden (öffentliche Felder und mit SerializeField gekennzeichnete Felder).
  • Variablenverknüpfungen - Ein Bereich zum Festlegen von Verweisen auf Variablen (weitere Informationen hierzu finden Sie im Abschnitt zum Arbeiten mit Variablen).

Um Objekte visuell zu gruppieren, müssen Sie sie auswählen, dann die rechte Taste drücken und das entsprechende Element im Menü auswählen. Gruppen können umbenannt und ihr Farbschema geändert werden.

Bild

Um die visuelle Darstellung der Komponenten mit dem Mausrad zu skalieren, ist alles ganz einfach.

Und das Letzte, worauf ich achten möchte, ist die Arbeit mit den Verbindungen zwischen den Komponenten.
Um eine Verbindung herzustellen, muss der Ausgangspunkt einer Komponente mit dem Eingangspunkt einer anderen Komponente verbunden werden.

Bild

Bild

Bild

Beziehungen werden basierend auf der Typanpassungsregel hergestellt, die ein Punkt sendet und empfängt. Ausnahmen werden an einem Eingabepunkt gemacht, der keine Daten empfängt, und jeder Ausgabepunkt kann mit diesem verbunden werden. Wenn eine Verbindung hergestellt wird, überprüft das System automatisch die Typübereinstimmung und zeigt an, ob diese Verbindung hergestellt werden kann oder nicht. Eingabe- und Ausgabepunkte werden im Komponentencode mithilfe der folgenden Klassen festgelegt:

INPUT_POINT OUTPUT_POINT INPUT_POINT<T> OUTPUT_POINT<T> 

Die ersten beiden Klassen werden für Eingabe- und Ausgabepunkte verwendet, die keine Parameter akzeptieren, die zweite umgekehrt. T kann ein beliebiger Typ sein.

 public INPUT_POINT <float> InputFloatValue = new INPUT_POINT<float>(); public OUTPUT_POINT <float> OutputFloatValue = new OUTPUT_POINT<float>(); 

Um eine Verknüpfungskette aufzurufen, müssen Sie die Funktion Ausführen verwenden.

 OutputFloatValue.Execute(5f); 

Um einen solchen Aufruf zu verarbeiten, muss ein Handler für den Eingabepunkt im Komponentencode festgelegt werden (darüber, wo genau wir etwas später sprechen werden).

 InputFloatValue.Handler = value => Debug.Log(value); 

Und schließlich möchte ich einen wichtigen Punkt über Verbindungen erwähnen. Wenn es mehrere Links von einem Punkt gibt, ist es im Editor möglich, die Reihenfolge ihres Anrufs anzupassen.

Arbeiten Sie mit Variablen


Wie bereits erwähnt, sind Variablen spezielle Objekte, mit denen Sie Daten zwischen Komponenten über Links zu diesen austauschen können. Variablen werden wie Komponenten von Programmierern erstellt.

 [ComponentDefinition(Name = "Float", Path = "uViLEd Components/Base/Variable/Base", Tooltip = "Variable for a floating-point number", Color = VLEColor.Cyan)] public class VariableFloat : Variable<float> { } 

Wie Sie sehen können, ist die Basisklasse für Variablen die generische Klasse Variable, wobei T der Datentyp ist, der in der Variablen enthalten ist. T kann ein beliebiger Typ sein, der serialisiert werden kann.

Im Editor werden die Variablen wie folgt angezeigt:

Bild

Um die Anzeige von Variablenwerten zu ändern, definieren Sie einfach die ToString-Methode in Typ T neu.

 public struct CustomData { public readonly int Value01; public readonly int Value02; public CustomData (int value01, int value02) { Value01= value01; Value02= value02; } public override string ToString() { var stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Value01 = {0}".Fmt(Value01)); stringBuilder.Append("Value02 = {0}".Fmt(Value02)); return stringBuilder.ToString(); } } 

Eine Variable dieses Typs sieht also folgendermaßen aus:

 public class VariableCustomData : Variable<CustomData> { } 

Um einen Verweis auf eine Variable in einer Komponente hinzuzufügen, müssen Sie eine spezielle Klasse verwenden.

 public VARIABLE_LINK<CustomData> CustomVariableLink = new VARIABLE_LINK<CustomData>(); 

Danach kann der Link im Inspektor festgelegt werden, und im Dropdown-Menü werden nur Variablen vom Typ CustomData angezeigt, was die Arbeit mit ihnen erheblich vereinfacht.

Um die Arbeit mit Variablen zu vereinfachen, gibt es spezielle Methoden, mit denen Sie feststellen können, wann eine Variable ihren Wert geändert hat oder wann Daten darauf festgelegt wurden.

 CustomVariableLink.AddSetEventHandler(CustomDataSet); CustomVariableLink.AddChangedEventHandler(CustomDataChanged); 

Es sollte berücksichtigt werden, dass geänderte Arbeiten durch die Gleichheitsbedingung funktionieren. Wenn daher Strukturen und Klassen verwendet werden, muss diese Methode neu definiert werden, um einen korrekten Betrieb sicherzustellen.

Arbeiten mit Unity-Objekten


Aufgrund der Natur des uViLEd-Systems können keine direkten Verknüpfungen zu Unity-Objekten verwendet werden, da sie beim Laden der Logik nicht wiederhergestellt werden können. Um dieses Problem zu lösen, wurde eine spezielle VLObject- Shell erstellt, mit der Sie solche Links erstellen sowie speichern und laden können. Diese Shell verfügt unter anderem über einen speziellen Eigenschafteneditor, mit dem Sie Komponenten von jedem Objekt in der Szene abrufen können (siehe Abbildung unten), wenn Sie darauf zugreifen möchten. Mit VLObject können Sie Links nicht nur zu Szenenobjekten und ihren Komponenten speichern, sondern auch zu Fertighäusern und Ressourcendateien wie Texturen, Sounds usw.

Bild

Hinweis : Wenn die vorhandene Logik in einer anderen Szene verwendet wird, gehen Verweise auf Objekte verloren, einschließlich Verweise auf Fertighäuser, da die Szene als Speicher fungiert. Dies sollte auch berücksichtigt werden, wenn Sie Logik als Vorlage verwenden möchten. In diesem Fall besteht die beste Option darin, die erforderlichen Links von außen darauf zu übertragen (z. B. von der an die Szene angehängten Logik).

Es ist auch möglich, den Typ des Unity-Objekts einzuschränken, das in VLObject installiert wird . Dies betrifft nur den Unity-Inspektor und wird für die bequeme Arbeit mit ihnen verwendet.

 [SerializeField] [TypeConstraint(typeof(Button))] private VLObject _button; 

Erstellen einer Logikkomponente


Um eine Logikkomponente zu erstellen, muss ein Programmierer dem Projekt lediglich eine einfache C # -Skriptdatei hinzufügen (Sie können eine Komponente oder eine Variable auch sofort über ein spezielles Menü auf der Registerkarte Projekt erstellen) und den darin enthaltenen Code wie folgt ändern:

 [ComponentDefinition(Name = "MyComponent", Path = "MyFolder/MySubfolder", Tooltip = "this my logic component", Color = VSEColor.Green)] public class MyLogicComponent : LogicComponent { } 

Wie bereits erwähnt, ist ComponentDefinition ein Attribut, mit dem Sie automatisch einen Katalog von Komponenten erstellen können. Hierbei ist zu beachten, dass Color (die Farbe des Headers) in der Zeichenfolge als HEX-Format festgelegt ist.

LogicComponent ist die Basisklasse aller Komponenten, die wiederum ein Nachkomme von ScripatableObject ist .

Das Folgende ist ein einfaches Beispiel für eine Komponente, die nach einem eingehenden Wert vom Typ bool verzweigt:

 public class IfBool : LogicComponent { public INPUT_POINT<bool> ValueToBeChecked = new INPUT_POINT<bool>(); public OUTPUT_POINT True = new OUTPUT_POINT(); public OUTPUT_POINT False = new OUTPUT_POINT(); public override void Constructor() { ValueToBeChecked.Handler = ValueToBeCheckedHandler; } private void ValueToBeCheckedHandler(bool value) { if(value) { True.Execute(); }else { False.Execute(); } } } 

Wie Sie dem Code entnehmen können, haben wir den Eingabepunkt der Komponente erstellt, der einen Wert vom Typ bool und zwei Ausgabepunkte annimmt, die je nach dem erhaltenen Wert aufgerufen werden.

Vielleicht haben Sie jetzt eine Frage, was für ein Konstruktor ist das? Ich erkläre. Standardmäßig unterstützt ScriptableObject keine Methoden wie Start , Update usw., aber auch die Methoden Awake , OnEnable , OnDisable und OnDestroy . Hier ist also Awake (wie OnEnable ), falls ScriptableObject über die CreateInstance- Methode erstellt wird, wird es immer aufgerufen, und dies ist tatsächlich das Problem. Aufgrund der Tatsache, dass das Objekt im Editor für die Serialisierung im Editor-Modus erstellt wurde, musste der Komponentencode zu diesem Zeitpunkt von der Arbeit ausgeschlossen werden. Daher wurde das Awake- Analogon als Konstruktormethode hinzugefügt. Dies gilt auch für die Methoden OnDisable und OnDestroy , wenn ein Objekt im Editor gelöscht wird. Wenn Sie das Entfernen einer Komponente korrekt verarbeiten müssen (z. B. beim Entladen einer Szene), müssen Sie die IDisposable- Schnittstelle verwenden.

Wie Sie sehen, ist das Erstellen von Komponenten im Allgemeinen nicht schwierig. Dies ist eine reguläre Klasse, in der es beliebigen Code geben kann. In dem speziellen Fall enthalten die Komponenten möglicherweise überhaupt keine Eingabe- und Ausgabepunkte, sondern kommunizieren über globale Nachrichten. Übrigens gibt es in uViLEd eine GlobalEvent- Klasse - es handelt sich um ein Nachrichtensystem, das auf Datentypen basiert (mehr dazu in meinem Artikel).

Das Letzte, was ich erwähnen möchte, ist die Möglichkeit, die Eingabe- und Ausgabepunkte der Komponente in Abhängigkeit von den Parametern der Komponente zu konfigurieren.

Bild

Zu diesem Zweck reicht es aus, im Komponentencode eine oder beide der Schnittstellen IInputPointParse und IOutputPointParse zu implementieren . Im Folgenden finden Sie ein Beispiel für einen abstrakten generischen Klassencode für Switch- Verzweigungskomponenten. Hier werden abhängig vom Parameter SwitchValues automatisch Ausgabepunkte erstellt.

SwitchAbstract-Klassencode
 public abstract class SwitchAbstract<T> : LogicComponent, IOutputPointParse { [Tooltip("input point for transmitting value, which should be checked")] public INPUT_POINT<T> ValueToBeChecked = new INPUT_POINT<T>(); [Tooltip("set of values for branching")] public List<T> SwitchValues = new List<T>(); protected Dictionary<string, object> outputPoints = new Dictionary<string, object>(); public override void Constructor() { ValueToBeChecked.Handler = ValueToBeCheckedHandler; } protected virtual bool CompareEqual(T first, T second) { return first.Equals(second); } protected virtual string GetValueString(T value) { var outputPontName = value.ToString(); #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlaying) { if (outputPoints.ContainsKey(outputPontName)) { outputPontName += " ({0})".Fmt(outputPoints.Count); } } #endif return outputPontName; } private void ValueToBeCheckedHandler(T checkedValue) { foreach (var value in SwitchValues) { if (CompareEqual(checkedValue, value)) { ((OUTPUT_POINT)outputPoints[GetValueString(value)]).Execute(); return; } } } public IDictionary<string, object> GetOutputPoints() { #if UNITY_EDITOR if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode) { outputPoints.Clear(); } #endif if (outputPoints.Count == 0) { foreach (var value in SwitchValues) { outputPoints.Add(GetValueString(value), new OUTPUT_POINT()); } } return outputPoints; } } 


Logik-Debugging


UViLEd bietet verschiedene Mechanismen zum Debuggen von Logik:

  1. Die Möglichkeit, interne Variablen und ihre Werte im Logikeditor im Szenenstartmodus anzuzeigen. Verwenden Sie dazu das ViewInDebugMode- Attribut
  2. Möglichkeit, Werte von Logikvariablen im Szenenstartmodus anzuzeigen
  3. Möglichkeit des schrittweisen Debuggens von Aufrufen zwischen Komponenten und Anzeigen von Daten, die zwischen ihnen übertragen werden

UViLEd verfügt über einen speziellen Modus für das letzte Element, der beim Starten der Szene aktiviert wird.

Bild

Dieser Modus weist leider bestimmte Einschränkungen auf, die mit dem Übergang zwischen Szenen verbunden sind. In diesem Fall gehen die Debugging-Daten aus der vorherigen Szene und Logik verloren, und in der neuen Szene werden sie erst ab dem Moment angezeigt, in dem die Logik im Editor aktiviert wird.

Fazit


In diesem Artikel habe ich versucht, Ihnen kurz den Entwicklungsansatz vorzustellen, den ich in meinen aktuellen Projekten verwende. Trotz der anfänglichen Skepsis (einschließlich meiner) zeigt die Praxis deutlich die Bequemlichkeit ihrer Verwendung, insbesondere beim Prototyping. Unter anderem wurde die Arbeit der Spieleentwickler stark vereinfacht, sie gehen nicht in die Szene, stoßen keine Objekte an, um den Spielprozess zu konfigurieren, es wird eine separate Logik für sie mit einer Reihe von Daten von Variablen und Komponenten erstellt, in denen sie einfach alles konfigurieren können. Ein großer Vorteil ist auch die Tatsache, dass in meinen Projekten der Inhalt oft von außen heruntergeladen wird. Mit dem visuellen Logik-Editor kann ich das Gleichgewicht des Spielprozesses aktualisieren, ohne die Hauptanwendung zu aktualisieren. In einigen Fällen kann die Logik selbst geändert werden.

Für mich selbst habe ich entschieden, dass ein solcher Entwicklungsansatz durchaus der richtige Ort ist. Natürlich ist er nicht auf große Projekte anwendbar, aber er kann dort für einige Gameplay-Skripte verwendet werden, um die Welt, das Level-Design usw. wiederzubeleben Laufende Projekte (Kindersegment), bisher zeigt er großartige Ergebnisse.

Was kommt als nächstes?

Dies war der erste Teil einer Reihe von Artikeln über den visuellen Editor von Logik uViLEd, dann wird es Teile geben über:

  1. Der Kern des Systems : wie die Logik geladen wird, warum das ScriptableObject ausgewählt wird, wie die API angeordnet ist, was Sie tun können usw., welche Schwierigkeiten aufgetreten sind und wie alles gelöst wurde.
  2. Redaktion : Wie es entwickelt wurde, wie es gebaut wurde, welche Probleme und welche Lösungen usw. Dinge, die ich jetzt neu gestalten würde.

Schreiben Sie in die Kommentare, wenn Sie spezielle Fragen haben, die ich in den folgenden Artikeln behandeln soll.

PS : Ich habe versucht, über die wichtigsten Punkte von uViLEd zu sprechen. Wenn Sie möchten , können Sie sich mit dem Plugin aus dem Asset Store vertraut machen. Es gibt eine vollständige Dokumentation (allerdings in englischer Sprache): ein Benutzerhandbuch, eine Anleitung für Programmierer und APIs.

Visual Logic Editor Teil 2

UViLEd Visual Logic Editor
Global Messaging Artikel

Source: https://habr.com/ru/post/de448190/


All Articles