Der folgende Blog-Beitrag wurde, sofern nicht anders angegeben, von einem Mitglied der Gamasutra-Community verfasst.
Die Gedanken und Meinungen, die hier geäußert werden, sind die des Verfassers und nicht die von Gamasutra oder dessen Muttergesellschaft.
Ziel
Das Hauptziel dieses Blog-Beitrags ist es, einen Überblick über ScriptableObject in Unity zu geben.
Was ist Scriptable Object?
Was ist der Unterschied zwischen ScriptableObject und Monobehaviour Klasse?
Was sind die Vor- und Nachteile von Scriptableobject?
Wie benutzt man ScriptableObject?
Lassen Sie uns all diese Fragen verstehen, indem wir eine Runde durch diesen Blog über ScriptableObject drehen
Nach der Unity API Dokumentation,
„ScriptableObject ist eine Klasse, von der Sie ableiten können, wenn Sie Objekte erstellen wollen, die nicht an Spielobjekte angehängt werden müssen.“
Verwirrt?
Keine Sorge, wenn Sie es nicht verstanden haben. Hier werde ich erklären, was es bedeutet.
Wie wir wissen, ist in Unity alles ein Objekt.
Monobehaviours sind eines der Objekte.
Spielobjekte: In deiner Szene kannst du dich mit transform bewegen.
ScriptableObject ist eine Art Objekt, aber es kann nur Daten enthalten.
So, sie werden nicht in das eigentliche Spiel involviert.
Ich hoffe, du hast die Definition von ScriptableObject verstanden.
Lassen Sie uns die Vor- und Nachteile von ScriptableObject diskutieren.
Vorteile von ScriptableObject:
- Eingebaut in Unity
- Sie werden von Unity sehr gut gepflegt.
- Sie können mit ihnen sehr einfach im Unity-Inspektor interagieren.
- Sie können als Assets gespeichert werden
- Sie können sie als Mini-Datei in Ihrem Projekt erstellen.
- Sie können diese Datei aktualisieren und je nach den Anforderungen Ihres Spiels speichern.
- Kann während der Laufzeit gespeichert werden
- Wenn Sie etwas während der Laufzeit ändern, wird es sich daran erinnern.
- Interne Lösung
- Wenn du versuchst, die Daten während der Laufzeit des Spiels zu erhalten, brauchst du dir keine Gedanken über das Parsen externer Dateien zu machen, die mehr ins Spiel kommen werden.
- Große Datenmengen
- Du kannst Millionen von ganzen Zahlen innerhalb eines ScriptableObjects speichern.
- So gibt es eine Menge Platz (keine Größenbegrenzungsfunktion).
- Ergänzen Sie die Struktur nach und nach
- Wenn Sie ein skriptfähiges Objekt erstellen und ein paar Instanzen davon erzeugen und feststellen, ohh ich brauche eine neue Einstellung für ‚moveSpeed‘ oder was auch immer für eine zusätzliche Variable Sie brauchen, können Sie sie hinzufügen, es wird Ihre Variable nicht stören.
- Löschen von Variablen kann ein wenig negative Auswirkungen haben.
Nachteile von ScriptableObject:
- Erfordert einen Editor für Skripte
- Wenn man Assets aus Skripten erstellen möchte, muss man sich ein wenig damit auskennen.
- Kann nicht außerhalb von Unity bearbeitet werden
- Wenn man ausschließlich mit Unity arbeitet, ist das kein großes Problem.
- Aber wenn du eine Teamlösung hast, bei der du Dateien an jemanden schicken willst, der sie dann bearbeiten soll, dann wird es nicht funktionieren.
- Kann nicht speichern, wenn es einmal bereitgestellt wurde
- Kann nicht während der Laufzeit speichern, sobald du das Spiel gebaut hast, was bedeutet, dass dies keine Lösung ist, um die Daten eines Spielers zu speichern, sondern nur, um die Daten der Spielentwicklung zu speichern.
Lassen Sie uns ein Beispiel nehmen, um zu verstehen, wie man ScriptableObject im Spiel verwendet.
Lassen Sie mich Ihnen zuerst eine Aufgabe geben.
Angenommen, wir haben ein Spiel mit 10 Levels und in jedem Level ändert sich das Verhalten des Feindes.
Irgendwelche Ideen, wie du das machen willst?
Ahh, du könntest denken, dass du 10 Prefab von 10 verschiedenen Feinden machst und sie jedem Level zuweist. Richtig?
Sind Sie sicher, dass es wirklich eine gute Übung ist?
Die Antwort ist eigentlich Nein.
„Weil ein Feindobjekt 4 Variablen und Update()-Funktion haben kann, und nehmen wir an, dass es 4 Mb Speicher benötigt, so können 10 Level Feind 40 Mb Speicher benötigen.“
So, hier ist die Lösung. Verwenden Sie ScriptableObject, um die Daten des Feindobjekts zu speichern.
Lassen Sie uns unser Minispiel mit ScriptableObject entwickeln.
Zunächst werde ich ein einfaches Skript erstellen, ohne ein ScriptableObject zu verwenden. (Wie bei unserem ersten Gedanken, für jeden Feind eine andere Vorabversion zu erstellen und sie jedem Level zuzuordnen 😉 )
Schritt 1
- Erstelle ein leeres GameObject und nenne es Enemy.
Schritt 2
- Erstelle ein C# Script und nenne es EnemyMove
Schreibe folgenden Code in EnemyMove.cs
public class EnemyMove : MonoBehaviour {#region PUBLIC_VARIABLESpublic string name;public int moveSpeed;public Color color;public string colorName; public SpriteRenderer spriterendere;#endregion#region PRIVATE_VARIABLESprivate float speed;Vector3 newPosition;#endregion#region UNITY_CALLBACKSvoid Update () {ChangeSpeed();gameObject.name = name;spriterendere.color = color;newPosition=transform.position;newPosition.y = Mathf.Sin (Time.time) * speed;transform.position = newPosition;}#endregion#region PROVATE_METHODSprivate void ChangeSpeed(){speed = Mathf.MoveTowards (speed,moveSpeed,Time.deltaTime);}#endregion}
Schritt 3
- Zuweisen an leeres GameObject(Enemy).
- Das Skript „EnemyMove“ hat drei öffentliche Variablen.
- Wenn das Spiel so viele feindliche GameObjects mit dem Skript „EnemyMove“ hat, dann verbraucht es viel Speicher.
- Dafür können wir, wie bei unserer Lösung „ScriptableObject“, ein Skript „EnemyData“ erstellen, anstatt diese Variablen im Skript „EnemyMove“ zu speichern.
Schritt 4
- Erstelle ein C#-Skript mit dem Namen EnemyData.
- das ScriptableObject anstelle von Monobehaviour erbt.
Schreibe den folgenden Code in EnemyData.cs.
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Schritt 5
- Ändern Sie den Code in „EnemyMove“, der zuvor erstellt wurde.
- Erstellen Sie eine öffentliche Variable „data“, die die Referenz von „EnemyData“ ist.
- Entfernen Sie die öffentliche Variable, die sich bereits in „EnemyData“ befindet.
Ändern Sie den Code wie folgt.
public class EnemyMove : MonoBehaviour {#region PUBLIC_VARIABLESpublic EnemyData data;public SpriteRenderer spriterendere;#endregion#region PRIVATE_VARIABLESprivate float speed;Vector3 newPosition;#endregion#region UNITY_CALLBACKSvoid Update () {ChangeSpeed();gameObject.name = name;spriterendere.color = data.color;newPosition=transform.position;newPosition.y = Mathf.Sin (Time.time) * speed;transform.position = newPosition;}#endregion#region PROVATE_METHODSprivate void ChangeSpeed(){speed=Mathf.MoveTowards (speed,data.moveSpeed,Time.deltaTime);}#endregion}
Jetzt können Sie sehen, dass im Inspektor für das feindliche Spielobjekt die Variable ‚Data‘ erscheint,
Ideen Sie, was Sie hier zuweisen könnten?
Folgt mir…
Schritt 1
- Hinzufügen einer Zeile in EnemyData.cs wie folgt
public class EnemyData : ScriptableObject {#region PUBLIC_VERIABLEpublic string name;public int moveSpeed;public Color color;public string colorName; #endregion}
Schritt 2
- Erstelle einen Ordner Game data und mache folgendes
Schritt 3
- Benenne ihn wie du willst.
- Nun kannst du alle Variablen innerhalb der EnemyData im Inspektorfenster sehen, du kannst die Werte der Variablen hier ändern.
Schritt 4
- Zuweisung in das Skript ‚EnemyMove‘
Ich bin sicher, du hast jetzt alle Antworten.
Fazit
- ScriptableObject sind wirklich gut für die Tatsache, dass sie deine Daten in größere Stücke aufteilen können.
- So dass du nicht eine Menge Speicher verbrauchst.
- ScriptableObject ist nur für Entwicklungszwecke.