MVC (Model-View-Controller) — это схема, предполагающая разделение данных приложения, пользовательского интерфейса и управляющей логики на три отдельных компонента, чтобы каждый из них можно было независимо модифицировать. Разработчик Cem Ugur Karacam поделился своим опытом программирования в Unity и коротко рассказал о Scriptable Objects. Мы представляем перевод его статьи, опубликованной на сайте dev.to.
Добро пожаловать в первую часть моего рассказа о реализации MVC в Unity с помощью Scriptable Objects. В этой статье я написал только про основы работы со Scriptable Objects, и в целом текст будет простым и понятным.
Для начала узнаем, что о Scriptable Objects говорят разработчики Unity:
Теперь логично спросить: почему именно Scriptable Objects?
Scriptable Objects — это часть функционала движка Unity, поэтому такие объекты имеют много встроенных возможностей для работы с редактором.
Мне нравится подход, используемый при разработке проектов на Unity. Вы можете создавать собственные инструменты и легко настраивать те, которые установлены по умолчанию. Scriptable Objects заметно расширяют ваши возможности, поскольку позволяют делать пользовательские контейнеры для данных и хранить их как ассеты в проекте.
Изображение выше — это пример использования Scriptable Object в Unity. Один файл .asset, созданный в проекте, может содержать информацию, необходимую для работы нескольких систем, и обеспечивать сохранение их настроек. Если хотите узнать больше, на YouTube есть отличное видео с презентацией про SO (Scriptable Object) под названием «Свержение тирании MonoBehaviour в выдающейся революции Scriptable Object» (Overthrowing the MonoBehaviour Tyranny in a Glorious Scriptable Object Revolution).
Еще один отличный пример показан выше. Здесь игровые объекты ссылаются на объект инвентаря (Inventory), а система сохранения (Save System) управляет ими всеми. Это изображение из другой прекрасной лекции «Архитектура игры со Scriptable Objects» (Game Architecture with Scriptable Objects), очень рекомендую с ней ознакомиться.
Другая замечательная особенность в том, что когда вы разберетесь со Scriptable Objects, то, скорее всего, не захотите больше использовать другие форматы сохранения данных, такие как JSON или XML, поскольку SO — это самый удобный формат для хранения данных в Unity.
Что ж, давайте посмотрим на Scriptable Objects в деле.
Мы написали класс с именем
Атрибут
Создадим папку с названием
Теперь напишем другой скрипт под названием
Добавим в него метод, который будет выводить информацию в консоль. Также запустим проверку, чтобы не выходить за пределы массива, а обходить массив по кругу.
Я назначу вызов нашего метода на клавишу «Пробел». В Unity это сделать очень легко. Благодаря классу
Пришло время переключиться обратно на редактор Unity. Мы наполним наш массив
Теперь давайте запустим проект и протестируем его.
Работает! А сейчас я хочу показать вам, что Scriptable Object может хранить не только данные, но и методы для работы с ними. Например, давайте добавим метод для вычисления цены в класс
Затем используем наш новый метод в классе
Теперь воспроизведем все и посмотрим на результат.
Примеры из этого урока есть на GitHub!
Первая часть рассказа подошла к концу. В следующей статье мы поговорим об использовании MVC в Unity. Но, поскольку мы уже знакомы со Scriptable Objects, добавим несколько новых фишек, чтобы сделать все круче и сложнее, как поступают настоящие гуру Unity.
Добро пожаловать в первую часть моего рассказа о реализации MVC в Unity с помощью Scriptable Objects. В этой статье я написал только про основы работы со Scriptable Objects, и в целом текст будет простым и понятным.
Для начала узнаем, что о Scriptable Objects говорят разработчики Unity:
- Это класс, от которого можно отнаследоваться, чтобы создать объект, который не должен быть прикреплен к другому объекту в сцене.
- Наибольшая польза от такого созданного объекта будет, если применять его только для сохранения данных.
Теперь логично спросить: почему именно Scriptable Objects?
Scriptable Objects — это часть функционала движка Unity, поэтому такие объекты имеют много встроенных возможностей для работы с редактором.
Мне нравится подход, используемый при разработке проектов на Unity. Вы можете создавать собственные инструменты и легко настраивать те, которые установлены по умолчанию. Scriptable Objects заметно расширяют ваши возможности, поскольку позволяют делать пользовательские контейнеры для данных и хранить их как ассеты в проекте.
Изображение выше — это пример использования Scriptable Object в Unity. Один файл .asset, созданный в проекте, может содержать информацию, необходимую для работы нескольких систем, и обеспечивать сохранение их настроек. Если хотите узнать больше, на YouTube есть отличное видео с презентацией про SO (Scriptable Object) под названием «Свержение тирании MonoBehaviour в выдающейся революции Scriptable Object» (Overthrowing the MonoBehaviour Tyranny in a Glorious Scriptable Object Revolution).
Еще один отличный пример показан выше. Здесь игровые объекты ссылаются на объект инвентаря (Inventory), а система сохранения (Save System) управляет ими всеми. Это изображение из другой прекрасной лекции «Архитектура игры со Scriptable Objects» (Game Architecture with Scriptable Objects), очень рекомендую с ней ознакомиться.
Другая замечательная особенность в том, что когда вы разберетесь со Scriptable Objects, то, скорее всего, не захотите больше использовать другие форматы сохранения данных, такие как JSON или XML, поскольку SO — это самый удобный формат для хранения данных в Unity.
Что ж, давайте посмотрим на Scriptable Objects в деле.
using UnityEngine;
public class ItemData : ScriptableObject
{
public string itemName;
public ItemType type;
public float attack;
}
public enum ItemType
{
Dagger,
Axe,
Sword,
Staff
}
Мы написали класс с именем
ItemData
и несколько свойств, типичных для RPG-игр. Далее создадим несколько таких предметов в проекте, получим к ним доступ из скрипта и выведем значения в консоль. Но сначала стоит добавить одну важную строчку в наш код.using UnityEngine;
[CreateAssetMenu]
public class ItemData : ScriptableObject
{
public string itemName;
public ItemType type;
public float attack;
}
public enum ItemType
{
Dagger,
Axe,
Sword,
Staff
}
Атрибут
CreateAssetMenu
, который мы добавили перед классом ItemData
, указывает Unity, что мы хотим создавать файлы .asset, в которых будет храниться наш класс, через меню. Иначе мы не сможем делать это с помощью правой кнопки мыши или кнопки Create в проектной папке.Создадим папку с названием
Items
и попробуем создать объект ItemData
в этой папке.Теперь напишем другой скрипт под названием
Inventory
, чтобы работать с файлом данных.using UnityEngine;
public class Inventory : MonoBehaviour
{
public ItemData[] inventory;
}
Добавим в него метод, который будет выводить информацию в консоль. Также запустим проверку, чтобы не выходить за пределы массива, а обходить массив по кругу.
using UnityEngine;
public class Inventory : MonoBehaviour
{
public ItemData[] inventory;
int index = 0;
public void NextItemInfo()
{
if (index > inventory.Length)
{
index = 0;
}
Debug.Log("Item name: " + inventory[index].name);
Debug.Log ("Attack power: " + inventory[index].attack);
switch(inventory[index].type)
{
case ItemType.Axe:
Debug.Log("Item type: Axe");
break;
case ItemType.Dagger:
Debug.Log("Item type: Dagger");
break;
case ItemType.Staff:
Debug.Log("Item type: Staff");
break;
case ItemType.Sword:
Debug.Log("Item type: Sword");
break;
}
index ++;
}
}
Я назначу вызов нашего метода на клавишу «Пробел». В Unity это сделать очень легко. Благодаря классу
Input
мы можем проверить в методе Update
, была ли нажата требуемая клавиша.using UnityEngine;
public class Inventory : MonoBehaviour
{
public ItemData[] inventory;
int index = 0;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
NextItemInfo();
}
}
public void NextItemInfo()
{
if (index > inventory.Length)
{
index = 0;
}
Debug.Log("Item name: " + inventory[index].name);
Debug.Log ("Attack power: " + inventory[index].attack);
switch(inventory[index].type)
{
case ItemType.Axe:
Debug.Log("Item type: Axe");
break;
case ItemType.Dagger:
Debug.Log("Item type: Dagger");
break;
case ItemType.Staff:
Debug.Log("Item type: Staff");
break;
case ItemType.Sword:
Debug.Log("Item type: Sword");
break;
}
index ++;
}
}
Пришло время переключиться обратно на редактор Unity. Мы наполним наш массив
inventory
ранее созданными файлами ItemData
из папки Items
. Но сперва создадим пустой объект в сцене и добавим на него наш скрипт Inventory
.Теперь давайте запустим проект и протестируем его.
Работает! А сейчас я хочу показать вам, что Scriptable Object может хранить не только данные, но и методы для работы с ними. Например, давайте добавим метод для вычисления цены в класс
ItemData
. Чтобы узнать более подробную информацию об этом, загляните в документы здесь и здесь.using UnityEngine;
[CreateAssetMenu]
public class ItemData : ScriptableObject
{
public string itemName;
public ItemType type;
public float attack;
public float GetPrice()
{
return attack * 40;
}
}
Затем используем наш новый метод в классе
Inventory
.using UnityEngine;
public class Inventory : MonoBehaviour
{
public ItemData[] inventory;
int index = 0;
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
NextItemInfo();
}
}
public void NextItemInfo()
{
if (index == inventory.Length)
{
index = 0;
}
Debug.Log("Item name: " + inventory[index].name);
Debug.Log ("Attack power: " + inventory[index].attack);
switch(inventory[index].type)
{
case ItemType.Axe:
Debug.Log("Item type: Axe");
break;
case ItemType.Dagger:
Debug.Log("Item type: Dagger");
break;
case ItemType.Staff:
Debug.Log("Item type: Staff");
break;
case ItemType.Sword:
Debug.Log("Item type: Sword");
break;
}
Debug.Log("Item price: " + inventory[index].GetPrice());
index ++;
}
}
Теперь воспроизведем все и посмотрим на результат.
Примеры из этого урока есть на GitHub!
Первая часть рассказа подошла к концу. В следующей статье мы поговорим об использовании MVC в Unity. Но, поскольку мы уже знакомы со Scriptable Objects, добавим несколько новых фишек, чтобы сделать все круче и сложнее, как поступают настоящие гуру Unity.