introduction
Chaque jeu contient des données avec lesquelles les concepteurs de jeux travaillent. En RPG, il s'agit d'une base de données d'objets, en match-3 - le coût en cristaux d'outils du magasin, dans les jeux d'action - la quantité de HP que la trousse de premiers soins guérit.
Il existe de nombreuses façons de stocker ces données - quelqu'un les stocke dans des tables, dans des fichiers xml ou json, qu'ils éditent avec leurs propres outils. Unity propose sa propre méthode: les objets scriptables (SO), que j'aime parce que vous n'avez pas besoin d'écrire votre propre éditeur pour leur représentation visuelle, il est facile de lier les actifs du jeu et les uns aux autres, et avec l'avènement d'Adressables, ces données peuvent être facilement et commodément stockées à l'extérieur jeux et mettre à jour séparément.
Dans cet article, je voudrais parler de ma bibliothèque SODatabase, avec laquelle vous pouvez facilement créer, éditer et utiliser dans le jeu (éditer et sérialiser) des objets scriptables.
Création et édition de SO
Je crée et modifie les SO dans une fenêtre séparée, qui est un peu similaire aux fenêtres de projet avec un inspecteur - à gauche il y a une arborescence de dossiers (le dossier dans lequel tous les SO se trouvent - un groupe dans adressables), et à droite se trouve l'inspecteur du SO sélectionné.
Pour dessiner un tel WindowEditor, j'utilise la bibliothèque Odin Inspector . De plus, j'utilise la sérialisation pour SO de cette bibliothèque - elle étend considérablement la sérialisation unitium standard en permettant le stockage des classes polymorphes, de l'imbrication profonde et des références de classe.
Les nouveaux SO sont créés en cliquant sur un bouton dans cette fenêtre - là, vous devez sélectionner le type de bipied souhaité, et il est créé dans le dossier. Pour que le type SO apparaisse dans cette fenêtre en tant qu'option, SO doit hériter de DataNode, qui n'a qu'un seul champ supplémentaire à 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.
La bibliothèque est accessible au public sur github . Écrit en utilisant Nullable à partir de c # 8, nécessite donc Unity 2020.1.4 comme version minimale.