Einheit: Skriptfähige Objekte kennenlernen

Bild

In diesem Tutorial erfahren Sie, wie Sie skriptfähige Objekte in Unity erstellen und verwenden. Mit skriptfähigen Objekten können Sie Ihren Workflow verbessern, den Speicherbedarf verringern und sogar die Codearchitektur aufteilen.

Gemäß der Unity- Dokumentation ist ScriptableObject ein Klassencode, mit dem Sie skriptfähige Objekte im Spiel erstellen können, um große Mengen gemeinsam genutzter Daten zu speichern, die unabhängig von Skriptinstanzen sind.

Es gibt viele Gründe für die Verwendung von skriptfähigen Objekten in Unity. Sie können den Speicherbedarf für jedes weitere Fertighaus reduzieren, da das skriptfähige Objekt im Wesentlichen dem Entwurfsmuster Flyweight folgt.

Ein weiterer Vorteil von Scriptable Objects, der das Hauptthema dieses Tutorials sein wird, ist ihre Verwendung für die bequeme Datenübertragung. Wir betrachten diese Eigenschaft als Beispiel für die Einrichtung eines Schwerthandelsgeschäfts, in dem die Parameter, Preise und Beschreibungen verschiedener Schwerter angezeigt werden.

Hinweis: In diesem Lernprogramm wird davon ausgegangen, dass Sie mit dem Unity-Editor vertraut sind. Sie müssen verstehen, wie Code in einem Code-Editor bearbeitet wird, und über grundlegende C # -Kenntnisse verfügen. Wenn Sie Ihre Unity-Fähigkeiten verbessern müssen, lesen Sie andere Unity-Tutorials .

An die Arbeit gehen


Beginnen wir mit dem Herunterladen der benötigten Materialien .

Entpacken Sie die heruntergeladene Datei an einen für Sie geeigneten Ort und öffnen Sie das Scriptable Object Tutorial-Starter- Projekt in Unity.

Der folgende Ordner sollte im Rahmen der Projektbeschaffung erstellt werden:


  • _Setup : Für das Tutorial wird dieser Ordner nicht benötigt.
  • Szenen : Enthält eine Sword Merchant- Szene, die wir im gesamten Tutorial behandeln werden. Öffne diese Szene.
  • Skripte : Bisher gibt es nur ein Skript, aber während des Tutorials werden wir neue erstellen.
  • Schwertsymbole : Enthält Standbilder einzelner Schwerter.
  • Sword Prefabs : Enthält die Prefabs aller Schwerter in der Sword Merchant-Szene.

Erstellen eines skriptfähigen Objekts


Um loszulegen, gehen Sie zur Sword Merchant- Szene. Es sollte so aussehen:


Skriptfähiges Objekt vorbereiten


Es ist Zeit, das erste skriptfähige Objekt zu erstellen!

Erstellen Sie im Ordner " Skripte " ein neues Skript mit dem Namen " SwordData" . Diese Klasse wird als Container für alle Schwertdaten verwendet, die im Geschäft des Schwerthändlers angezeigt werden.

Beginnen Sie in dieser Klasse damit, von ScriptableObject anstelle von MonoBehaviour :

 public class SwordData : ScriptableObject { } 

Diese Aktion teilt Unity mit, dass wir die Unity-Funktionen und -Methoden wie bei normalem MonoBehaviour weiterhin verwenden möchten, dieses Skript jedoch nicht mehr an GameObject anhängen müssen. Stattdessen wird es wie jedes normale Asset verarbeitet, das auf die gleiche Weise wie ein Fertighaus, eine Szene oder ein Material erstellt werden kann.

Füllen Sie das Skript mit serialisierten Feldern, die alle Daten enthalten, die den in der Benutzeroberfläche von Sword Merchant angezeigten Informationen entsprechen.

 public class SwordData : ScriptableObject { [SerializeField] private string swordName; [SerializeField] private string description; [SerializeField] private Sprite icon; [SerializeField] private int goldCost; [SerializeField] private int attackDamage; } 

  • Schwertname : string , in der der Name des Schwertes gespeichert wird.
  • description : string , in der die Beschreibung des Schwertes gespeichert wird.
  • Symbol : Das Sprite, das das Schwertsymbol enthält.
  • goldCost : int , um den Wert des Schwertes in Gold zu speichern.
  • attackDamage : int , um Schaden zu speichern, wenn mit einem Schwert angegriffen wird.

Hinweis: SerializeField

In Unity können Sie mit dem SerializeField-Attribut private Skriptvariablen im Inspector verfügbar machen. Damit können Sie Werte im Editor festlegen, ohne von anderen Skripten aus auf die Variable zugreifen zu können.

Jedes Schwert erfordert eine eigene Implementierung der Scriptable Object SwordData . Bevor wir diese Implementierungen erstellen können, müssen wir dem Asset-Menü ein skriptfähiges Objekt hinzufügen.

Fügen Sie unser skriptfähiges Objekt zum Asset-Menü hinzu, indem Sie der SwordData- Klasse das folgende Attribut hinzufügen :

 [CreateAssetMenu(fileName = "New SwordData", menuName = "Sword Data", order = 51)] public class SwordData : ScriptableObject 

  • Dateiname : Standardname beim Erstellen eines Assets.
  • menuName : Asset- Name, der im Asset-Menü angezeigt wird.
  • Reihenfolge : Asset-Platzierung im Asset-Menü. Unity unterteilt Assets in Untergruppen mit einem Faktor von 50. Das heißt, ein Wert von 51 platziert das neue Asset in der zweiten Gruppe des Asset-Menüs.

Wenn alles richtig gemacht wurde, können Sie unter Assets >> Create das neue Sword Data Asset im Menü anzeigen. Es sollte sich in der zweiten Gruppe unter dem Ordner-Asset befinden:


Sie können auch mit der rechten Maustaste in das Projektfenster klicken und das neue Schwertdaten-Asset anzeigen:


Daten hinzufügen


Wir organisieren das Projekt, indem wir einen Ordner namens Scriptable Objects im Ordner Scripts und in diesem Ordner einen weiteren Ordner namens Sword Data erstellen.

Erstellen Sie im neu erstellten Ordner "Schwertdaten" unser erstes Schwertdaten-Asset.

Das neue Sword Data-Asset sollte weiterhin den zuvor angegebenen Standardnamen fileName haben . Wählen Sie ein Asset aus und duplizieren Sie es sechsmal ( Strg / Befehlstaste + D ), um sieben Schwertdaten-Assets zu erstellen, eines für jedes der Schwerter. Benennen Sie nun jedes Asset gemäß den Fertighäusern um:


Klicken Sie im Ordner "Schwertdaten" auf das erste Schwertdaten- Asset und sehen Sie sich das Inspektorfenster an :


Hier sehen wir einen Vermögenswert, in dem Informationen über ein bestimmtes Schwert gespeichert werden. Geben Sie die Informationen für jedes Schwert ein. Versuchen Sie, ihnen während eines Angriffs eine eindeutige Beschreibung, einen Wert in Gold und Schaden zu geben. Verwenden Sie im Feld Icon Sprite die entsprechenden Sprites im Ordner Sword Icons :


Glückwunsch! Sie haben ein Skriptobjekt erstellt und mehrere Assets mit diesem Skriptobjekt konfiguriert.

Verwenden eines skriptfähigen Objekts


Jetzt werden wir Daten von diesen skriptfähigen Objekten abrufen.

Zuerst müssen wir einige öffentliche Getter-Methoden hinzufügen, damit andere Skripte auf private Felder innerhalb des Skriptobjekts zugreifen können. Öffnen Sie SwordData.cs und fügen Sie unter den zuvor hinzugefügten Feldern Folgendes hinzu:

  public string SwordName { get { return swordName; } } public string Description { get { return description; } } public Sprite Icon { get { return icon; } } public int GoldCost { get { return goldCost; } } public int AttackDamage { get { return attackDamage; } } 

Öffnen Sie Sword.cs und fügen Sie den folgenden Code hinzu:

  [SerializeField] private SwordData swordData; // 1 private void OnMouseDown() // 2 { Debug.Log(swordData.name); // 3 Debug.Log(swordData.Description); // 3 Debug.Log(swordData.Icon.name); // 3 Debug.Log(swordData.GoldCost); // 3 Debug.Log(swordData.AttackDamage); // 3 } 

Folgendes haben wir mit diesem Code hinzugefügt:

  1. Der Datencontainer für die Daten für dieses Schwert.
  2. OnMouseDown ist eine integrierte MonoBehaviour-Funktion, die aufgerufen wird, wenn der Benutzer die linke Maustaste drückt.
  3. Beispiele zum Abrufen von Daten aus unserem Skriptobjekt-Asset

Gehen Sie zurück zu Unity und gehen Sie zum Hierarchiefenster . Wählen Sie das 1_Longsword-Spielobjekt im Schwert-Fertighaus aus. Fügen Sie der Sword Data-Variablen des Sword.cs-Skripts im Inspector-Fenster das entsprechende 1_Longsword Data-Asset hinzu:


Klicken Sie im Unity-Editor auf Wiedergabe ( Strg / Befehlstaste + P ) und dann auf das Schwert ganz links:


Die Konsole sollte Informationen anzeigen, die Daten ähneln, die vom Schwertdaten-Asset übertragen wurden.

Skriptfähige Objekte erleichtern das Ersetzen dieser Daten. Versuchen Sie, verschiedene skriptfähige Objekte mit Schwertdaten in das Feld Schwertdaten des Schwertes einzufügen.

Eventable Scriptable Objects


Also haben wir ein skriptfähiges Objekt erstellt und Sie haben gesehen, wie Sie im Spiel auf seine Daten zugreifen können. Wir müssen jedoch noch Schwertdaten in die Benutzeroberfläche integrieren!

Sie können hierfür das schnelle und schmutzige Singleton- Muster verwenden. Jetzt haben wir jedoch andere Möglichkeiten ...

... nämlich skriptfähige Objekte! Wir werden sie verwenden, um sauberen und sauber unterteilten Code zu erstellen.

In diesem Abschnitt erfahren Sie, wie Sie mithilfe der UnityEvent- Klasse Spielereignisse erstellen.

Spielereignisse und Hörer


Erstellen Sie im Ordner "Skripte" zwei Skripte: GameEvent.cs und GameEventListener.cs . Sie hängen voneinander ab. Um Fehler zu beseitigen, müssen Sie beide erstellen.

 using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "New Game Event", menuName = "Game Event", order = 52)] // 1 public class GameEvent : ScriptableObject // 2 { private List<GameEventListener> listeners = new List<GameEventListener>(); // 3 public void Raise() // 4 { for (int i = listeners.Count - 1; i >= 0; i--) // 5 { listeners[i].OnEventRaised(); // 6 } } public void RegisterListener(GameEventListener listener) // 7 { listeners.Add(listener); } public void UnregisterListener(GameEventListener listener) // 8 { listeners.Remove(listener); } } 

Der obige Code bewirkt Folgendes:

  1. Fügt dem Asset-Menü ein GameEvent als Asset hinzu.
  2. GameEvent ist ein skriptfähiges Objekt, daher sollte es von ScriptableObject erben.
  3. Liste der GameEventListener, die GameEvent abonnieren sollen.
  4. Methode zum Aufrufen aller GameEvent-Abonnenten.
  5. Der zuletzt signierte GameEventListener wird als erster aufgerufen (last come, first come out).
  6. Rufen Sie jeden UnityEvent GameEventListener auf.
  7. Eine Methode, mit der GameEventListeners dieses GameEvent abonnieren können.
  8. Eine Methode, mit der GameEventListener dieses GameEvent abbestellen können.


 using UnityEngine; using UnityEngine.Events; // 1 public class GameEventListener : MonoBehaviour { [SerializeField] private GameEvent gameEvent; // 2 [SerializeField] private UnityEvent response; // 3 private void OnEnable() // 4 { gameEvent.RegisterListener(this); } private void OnDisable() // 5 { gameEvent.UnregisterListener(this); } public void OnEventRaised() // 6 { response.Invoke(); } } 

In dem oben gezeigten Code wird das Projekt weiterentwickelt:

  1. Voraussetzung für die Verwendung der UnityEvent-Klasse.
  2. Das GameEvent, das dieser GameEventListener abonniert.
  3. Die UnityEvent-Antwort, die ausgelöst wird, wenn das GameEvent-Ereignis diesen GameEventListener auslöst.
  4. Binden eines GameEvent an einen GameEventListener, wenn dieses GameObject aktiviert ist.
  5. Binden eines GameEvent aus einem GameEventListener, wenn dieses GameObject deaktiviert ist.
  6. Wird aufgerufen, wenn ein GameEvent generiert wird, das den GameEventListener veranlasst, das UnityEvent-Ereignis aufzurufen.

Ist es schwierig Nichts, du wirst es mit der Zeit herausfinden!

Redaktionstraining


Kehren Sie zum Unity-Editor zurück und erstellen Sie einen neuen Ordner für Spielereignisse unter Skripte >> ScriptableObjects. Erstellen Sie dann sieben Spielereignisse aus dem Asset-Menü, wie wir es für jedes Schwertdaten-Asset getan haben. Legen Sie sie in den neuen Ordner "Spielereignisse".


Ersetzen Sie den Code im Skript Sword.cs durch die folgenden Zeilen:

  [SerializeField] private GameEvent OnSwordSelected; // 1 private void OnMouseDown() { OnSwordSelected.Raise(); // 2 } 

Dieser Code fügt dem Geschäft des Schwerthändlers zwei Möglichkeiten hinzu:

  1. Generierung eines Spielereignisses bei der Auswahl eines Schwertes.
  2. Ereignisgenerierung, wenn Sie auf das Schwert klicken.

Speichern Sie das Skript. Verbinden Sie nun in jedem Hierarchie-GameObject des Schwertes das entsprechende OnSwordSelected-Ereignis.


Jedes Schwert hat jetzt einen Link zu dem Ereignis, das ausgelöst wird, wenn auf das Schwert geklickt wird.

UI-Integration


Jetzt müssen Sie die Benutzeroberfläche zum Laufen bringen. Unser Ziel ist es, die entsprechenden Schwertdaten anzuzeigen, wenn Sie auf jedes Schwert klicken.

UI-Links


Vor dem Aktualisieren der Benutzeroberfläche müssen Sie einen Link zu jedem Element der Benutzeroberfläche erhalten. Beginnen wir mit der Erstellung eines neuen Skripts mit dem Namen SwordMerchant.cs und dem Hinzufügen des folgenden Codes zu diesem neuen Skript:

 using UnityEngine; using UnityEngine.UI; public class SwordMerchant : MonoBehaviour { [SerializeField] private Text swordName; // 1 [SerializeField] private Text description; // 2 [SerializeField] private Image icon; // 3 [SerializeField] private Text goldCost; // 4 [SerializeField] private Text attackDamage; // 5 } 

Mit diesem Code haben wir Folgendes hinzugefügt:

  1. Ein Verweis auf die Textkomponente des NameText -Spielobjekts.
  2. Link zur Textkomponente des DescriptionText -Spielobjekts.
  3. Link zur Image-Komponente des Sword_Icon -Spielobjekts.
  4. Link zur Textkomponente des GoldText -Spielobjekts.
  5. Ein Link zur Textkomponente des AttackText -Spielobjekts.

Die oben genannten Spielobjekte befinden sich im SwordMerchantCanvas >> SwordMerchantPanel des Hierarchiefensters. Fügen Sie das Skript zu GameObject SwordMerchantCanvas hinzu und konfigurieren Sie dann alle Links:


Listener und UI-Antworten


Alle Schwerter haben ein Ereignis, das die Benutzeroberfläche mithilfe des GameEventListener- Skripts abonnieren kann. Fügen Sie GameObject SwordMerchantCanvas einen GameEventListener für jedes OnSwordSelected-Ereignis hinzu :


Wie Sie sehen können, verfügt unser Game Event Listener über zwei Felder: das Game Event-Ereignis, das er abhört, und die Antwort, die beim Generieren des Game Event ausgelöst wird.

In unserem Fall wird die Antwort von der Benutzeroberfläche aktualisiert. Fügen Sie dem Skript SwordMerchant.cs die folgende Methode hinzu :

  public void UpdateDisplayUI(SwordData swordData) { swordName.text = swordData.SwordName; description.text = swordData.Description; icon.sprite = swordData.Icon; goldCost.text = swordData.GoldCost.ToString(); attackDamage.text = swordData.AttackDamage.ToString(); } 

Diese Methode empfängt ein Schwertdaten-Asset und aktualisiert dann jedes UI-Feld mit dem Wert des entsprechenden Schwertdatenfelds. Beachten Sie, dass GoldCost und AttackDamage ein int , sodass Sie es in eine Zeichenfolge für Text konvertieren müssen.

Mit unserer neuen Methode können wir jedem GameEventListener eine Antwort hinzufügen .

Für jede Antwort, die Sie hinzufügen, benötigen Sie einen Link zu unserem SwordMerchantCanvas -Spielobjekt als Wert des Felds Keine (Objekt) . Wählen Sie danach SwordMerchant.UpdateDisplayUI aus dem Dropdown-Menü rechts neben der Dropdown-Liste Nur Laufzeit .

Seien Sie vorsichtig und verwenden Sie für jedes OnSwordSelected- Ereignis das richtige Schwertdaten- Asset.


Jetzt können wir das Spiel starten, auf das Schwert klicken und sehen, dass die Benutzeroberfläche entsprechend aktualisiert wird!


Da wir Game Events verwenden, können Sie einfach SwordMerchantCanvas verwenden , und alles funktioniert weiterhin, nur ohne Benutzeroberfläche. Dies bedeutet, dass die Schwert- Fertighäuser von den SwordMerchantCanvas getrennt sind .

Wohin als nächstes?


Wenn Sie während der Geschichte etwas verpasst haben, können Sie das fertige Projekt herunterladen , das sich in den Materialien des Tutorials befindet.

Wenn Sie weitermachen möchten, versuchen Sie, jedes Schwert seinen eigenen Klang wiedergeben zu lassen. Versuchen Sie, Scriptable Object Sword Data zu erweitern und auf OnSwordSelected Ereignisse zu OnSwordSelected .

Möchten Sie mehr über Unity erfahren? Schauen Sie sich unsere Unity- Videoserien an oder lesen Sie die Unity-Tutorials .

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


All Articles