Einführung
Jedes Spiel enthält Daten, mit denen Spieleentwickler arbeiten. In RPG ist dies eine Datenbank mit Gegenständen, in Match-3 - die Kosten in Kristallen von Werkzeugen aus dem Laden, in Actionspielen - die Menge an HP, die das Erste-Hilfe-Set heilt.
Es gibt viele Möglichkeiten, solche Daten zu speichern - jemand speichert sie in Tabellen, in XML- oder JSON-Dateien, die er mit seinen eigenen Tools bearbeitet. Unity bietet seinen eigenen Weg - Scriptable Objects (SO), die mir gefallen, weil Sie für ihre visuelle Darstellung keinen eigenen Editor schreiben müssen, es einfach ist, Links zu Spiel-Assets und untereinander zu erstellen, und mit dem Aufkommen von Addressables können diese Daten einfach und bequem im Freien gespeichert werden Spiele und Update separat.
In diesem Artikel möchte ich über meine SODatabase-Bibliothek sprechen, mit der Sie bequem skriptfähige Objekte im Spiel erstellen, bearbeiten und verwenden können (bearbeiten und serialisieren).
SO erstellen und bearbeiten
Ich erstelle und bearbeite SOs in einem separaten Fenster, das den Projektfenstern mit einem Inspektor etwas ähnelt. Links befindet sich ein Ordnerbaum (der Ordner, in dem sich alle SOs befinden - eine Gruppe in adressierbaren Dateien) und rechts der Inspektor des ausgewählten SO.

Um einen solchen WindowEditor zu zeichnen, verwende ich die Odin Inspector- Bibliothek . Außerdem verwende ich die Serialisierung für SO aus dieser Bibliothek - sie erweitert die Standard-Unitium-Serialisierung erheblich und ermöglicht das Speichern von polymorphen Klassen, tiefen Verschachtelungen und Klassenreferenzen.

Neue SOs werden durch Klicken auf eine Schaltfläche in diesem Fenster erstellt. Dort müssen Sie den Typ des gewünschten Zweibeines auswählen. Dieser wird im Ordner erstellt. Damit der SO-Typ als Option in diesem Fenster angezeigt wird, muss SO von DataNode erben, der nur ein zusätzliches Feld für ScriptableObject enthält
public string FullPath { get; }
SO, .
SO
- , , SO - , — , , SO.
static SODatabase , , .
public static T GetModel<T>(string path) where T : DataNode
public static List<T> GetModels<T>(string path, bool includeSubFolders = false) where T : DataNode
, SODatabase , Addressables.
ScriptableObject , . ScriptableObject . , SO .
— , , - , . , SO . , unity, xml .
, ScriptableObject JSON.
DataNode — SO, SODatabase,
[JsonObject(MemberSerialization.OptIn, IsReference = true)]
JsonProperty save.txt . SODatabase addressables JsonConvert.PopulateObject SODatabase, .
, , SO ( , JsonProperty) -, SO . — . , , , .
-
async void Awake()
{
await SODatabase.InitAsync(null, null);
await SODatabase.LoadAsync();
}
private void OnApplicationPause(bool pauseStatus)
{
if (pauseStatus)
SODatabase.Save();
}
private void OnApplicationQuit()
{
SODatabase.Save();
}
PlayerSO, — , , . - , SODatabase, .
public class PlayerSO : DataNode
{
public static string Path => "PlayerInfo/Player";
[JsonProperty]
public string Title = string.Empty;
[JsonProperty]
public int Experience;
}
PlayerInventorySO, ( SO SODatabase).
public class PlayerInventorySO : DataNode
{
public static string Path => "PlayerInfo/PlayerInventory";
[JsonProperty]
public List<ItemSO> Items = new List<ItemSO>();
}
, — , . , , QuestSO (, , ..) . - .
public class QuestNode : BaseNode
{
public static string Path = "QuestNodes";
//Editor
public virtual string Title { get; } = string.Empty;
public virtual string Description { get; } = string.Empty;
public int TargetCount;
//Runtime
[JsonProperty]
private bool finished;
public bool Finished
{
get => finished;
set => finished = value;
}
}
, JsonProperty , SO .
var playerSO = SODatabase.GetModel<PlayerSO>(PlayerSO.Path);
var playerInventorySO = SODatabase.GetModel<PlayerInventorySO>(PlayerInventorySO.Path);
var questNodes = SODatabase.GetModels<QuestNode>(QuestNode.Path, true);
— - / , , SO, json. - , ( ..) . SO , SODatabase , Addressables.
Die Bibliothek ist auf Github öffentlich zugänglich . Für die Verwendung von Nullable ab c # 8 ist daher Unity 2020.1.4 als Mindestversion erforderlich.