Skip to content
This repository was archived by the owner on Aug 15, 2024. It is now read-only.

Commit 54af894

Browse files
committed
doc: added russian doc
1 parent 167e7d7 commit 54af894

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

Packages/com.nuclearband.sodatabase/Documentation.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
### Введение
2+
3+
В каждой игре есть данные, с которыми работают гейм-дизайнеры. В рпг - это база данных айтемов, в матч-3 - стоимость в кристаллах инструментов из магазина, в экшенах - количество хп, на которое лечит аптечка.
4+
5+
Для хранения таких данных существует много способов - кто-то хранит их в таблицах, в xml или json файлах, которые редактируют собственными инструментами. Unity предоставляет свой способ - Scriptable Objects (SO), которые мне нравится тем, что для их визуального представления не нужно писать свой редактор, легко делать ссылки на ассеты игры и друг на друга, а с появлением Addressables эти данные можно легко и удобно хранить вне игры и обновлять отдельно.
6+
7+
В этой статье я хотел бы рассказать о своей библиотеке SODatabase, с помощью которой можно удобно создавать, редактировать и использовать в игре (редактировать и сериализовать) scriptable objects.
8+
9+
### Создание и редактирование SO
10+
11+
Создание и редактирование SOшек я веду в отдельном окне, которое чем-то похоже на окно проекта с инспектором - слева находится дерево папок (папка, в которой находятся все SOшки - группа в addressables), а справа - инспектор выделенной SOшки.
12+
13+
![Интерфейс](https://habrastorage.org/webt/g-/at/3_/g-at3_ewbaje3clfmpwy2fdv9fw.png)
14+
15+
Для отрисовки такого WindowEditor’а я использую библиотеку Odin Inspector. Кроме того, я использую сериализацию для SO из этой библиотеки - она значительно расширяет стандартную юнитиевскую сериализацию, позволяя хранить полиморфные классы, глубокую вложенность, ссылки на классы.
16+
17+
![Создание SO](https://habrastorage.org/webt/kw/8z/6k/kw8z6kpamvb8eq2k5mkissvo4m8.png)
18+
19+
Создание новых SO происходит через нажатие кнопки в этом окне - там нужно выбрать тип нужной сошки, и она создаётся в папке. Для того, чтобы тип SO появился в этом окне в качестве варианта, SO должен наследоваться от DataNode, который имеет лишь одно дополнительное поле к ScriptableObject
20+
```csharp
21+
public string FullPath { get; }
22+
```
23+
Это путь к данной SO, с помощью которого к ней можно будет обратиться в рантайме.
24+
25+
### Доступ к SO в игре
26+
27+
В игре обычно нужно либо получить какую-то конкретную модель, например, SO со списком настроек какого-либо окна, либо набор моделей из папки - например, список айтемов, где модель каждого айтема представляет собой отдельный SO.
28+
Для этого в static классе SODatabase есть два основных метода, которые возвращают либо весь список моделей из нужной папки, либо конкретную модель из папки с определённым именем.
29+
30+
```csharp
31+
public static T GetModel<T>(string path) where T : DataNode
32+
33+
public static List<T> GetModels<T>(string path, bool includeSubFolders = false) where T : DataNode
34+
```
35+
36+
37+
Уточню, что один раз в начале игры перед запросом моделей SODatabase нужно проинициализировать, чтобы обновились данные из Addressables.
38+
39+
### Загрузка и сохранение
40+
41+
Один из недостатков ScriptableObject по сравнению с хранением данных с сериализацией в собственном формате является то, что в них нельзя записывать данные из игры в рантайме. То есть по сути ScriptableObject предназначены для хранения статичных данных. Но любой игре нужна загрузка и сохранение, и я реализую это через те же самые SO из базы данных.
42+
43+
Возможно это не идиоматичный способ - совмещать базу статичных моделей игры с загрузкой и сохранением динамических данных, но в моём опыте ещё ни разу не было случая, когда это создало бы какие-то неудобства, но при этом есть ряд ощутимых плюсов. Например, с помощью тех же инспекторов SOшек можно смотреть игровые данные в эдиторе и менять их. Можно удобно загружать сейвы игроков, смотреть их содержимое и редактировать в unity, не используя никаких внешних утилит и собственных редакторов для визуализации xml или других форматов.
44+
45+
Я достигаю этого, сериализуя динамические поля в ScriptableObject с помощью JSON.
46+
47+
Класс DataNode - родительский класс всех SO, хранящихся в SODatabase, помечен как
48+
```csharp
49+
[JsonObject(MemberSerialization.OptIn, IsReference = true)]
50+
```
51+
и все его *JsonProperty* сериализуются в файл save.txt при сохранении игры. Соответственно при инициализации SODatabase кроме запроса данных об изменении addressables происходит *JsonConvert.PopulateObject* для каждой динамической модели из SODatabase, используя данные из этого файла.
52+
53+
Для того, чтобы это работало гладко, я сериализую ссылки на SO (которые могут являтся динамическими полями, помеченными как JSONProperty) в строку-путь, и потом десериализую обратно в ссылки на SO при загрузке. Есть ограничение - данные на игровые ассеты динамическими быть не могут. Но это не фундаментальное ограничение, просто у меня ещё не было случая, когда такие динамические данные потребовались бы, поэтому я не реализовывал специальную сериализацию для таких данных.
54+
55+
### Примеры
56+
В рпг для хранения информации об игроке я прямо создаю *PlayerSO*, в котором одни только динамические поля - имя, количество экспы игрока, кристаллов и так далее. Точно также для инвентаря игрока я создаю *PlayerInventorySO*, где храню список ссылок на айтемы игрока (каждый айтем представляет собой ссылку на статичный SO из SODatabase).
57+
58+
Бывают наполовину статические, наполовину динамические данные - например, квесты. Возможно, это не лучший подход, но я прямо в моделях *QuestSO *со статической информацией о квестах (название, описание, цели и т.д.) храню динамическую информацию по прогрессу в этом квесте. Таким образом гейм-дизайнер в одном инспекторе видит всю инфу о текущем состоянии квеста и его описание.
59+
60+
61+
62+
63+
64+
65+
66+
67+
68+
69+
70+
71+
72+
73+
74+

Packages/com.nuclearband.sodatabase/Documentation/Documentation.ru.md.meta

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@ You can install via git url by adding this entry in your **manifest.json**
1010
"com.nuclearband.sodatabase": "https://github.com/Tr0sT/UnityScriptableObjectDatabase.git#upm"
1111
```
1212
The library depends on [Odin Inspector](https://odininspector.com/)
13+
14+
## Documentation
15+
- [Документация](https://github.com/NuclearBand/UnityWindowsManager/blob/master/Assets/com.nuclearband.windowsmanager/Documentation/Documentation.ru.md)

0 commit comments

Comments
 (0)