pengantar
Setiap game memiliki data yang digunakan desainer game. Dalam RPG, ini adalah database item, dalam pertandingan-3 - biaya peralatan kristal dari toko, dalam permainan aksi - jumlah HP yang disembuhkan oleh kotak P3K.
Ada banyak cara untuk menyimpan data semacam itu - seseorang menyimpannya dalam tabel, dalam file xml atau json, yang mereka edit dengan alat mereka sendiri. Unity menyediakan caranya sendiri - Scriptable Objects (SO), yang saya suka karena Anda tidak perlu menulis editor Anda sendiri untuk presentasi visual mereka, mudah untuk menautkan ke aset game dan satu sama lain, dan dengan munculnya Addressables, data ini dapat dengan mudah dan nyaman disimpan di luar game dan perbarui secara terpisah.
Pada artikel ini, saya ingin berbicara tentang pustaka SODatabase saya, yang dengannya Anda dapat dengan mudah membuat, mengedit, dan menggunakan objek yang dapat ditulis dalam game (edit dan serialisasi).
Membuat dan mengedit SO
Saya membuat dan mengedit SO di jendela terpisah, yang agak mirip dengan jendela proyek dengan inspektur - di sebelah kiri ada pohon folder (folder di mana semua SO berada - grup di addressables), dan di sebelah kanan adalah inspektur dari SO yang dipilih.

Untuk menggambar WindowEditor seperti itu, saya menggunakan library Odin Inspector . Juga, saya menggunakan serialisasi untuk SO dari perpustakaan ini - ini sangat memperluas serialisasi unitium standar dengan memungkinkan kelas polimorfik, bersarang dalam, dan referensi kelas untuk disimpan.

SO baru dibuat dengan mengklik tombol di jendela ini - di sana Anda perlu memilih jenis bipod yang diinginkan, dan dibuat di folder. Agar tipe SO muncul di jendela ini sebagai opsi, SO harus mewarisi dari DataNode, yang hanya memiliki satu bidang tambahan untuk ScriptableObject
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.
Perpustakaan tersedia untuk umum di github . Ditulis menggunakan Nullable dari c # 8, oleh karena itu membutuhkan Unity 2020.1.4 sebagai versi minimum.