Unity предлагает отличные инструменты для создания небольших игр с малым количеством переменных. Когда проект разрастается, становится крайне неудобно изменять в стандартном Inspector данные, особенно если все данные хранятся в одном месте (что крайне удобно при редактировании).
Как сделать удобную для редактирования и понятную для геймдизайнеров базу данных?
Об этом ниже.
Для начала создадим класс DataBase который будет отвечать за общение с базой данных или хранение данных для небольших проектов.
Стоит поговорить с гемдизайнором и определится какой список типов данных потребуется. Для примера это будет 4 типа данных.
Записываем их в enum (потом будет понятно зачем)
public enum DataType
{
Item=0,
Ship=1,
Spell=2,
Recipe=3,
}
Тут-же создаем интерфейс для общения с нашими типами данных. В нем обязательными полями должны быть Id, Name и одна функция DrawGui() которая в дальнейшем и будет отвечать за отрисовку нашего интерфейса.
public interface IData
{
int Id { get; set; }
string Name { get; set; }
#if UNITY_EDITOR
void DrawGui();
#endif
}
Функция DrawGui() нам не нужна в скомпилированном проекте так что ее настоятельно рекомендую обнести директивой компиляции.
В самом классе DataBase добавляем функции для доступа к данным:
List GetDatas(DataType type) — для получения всего списка данных указанного типа
IData GetData(DataType type, int id) — для получения данных по id
void AddData(DataType type) — добавления нового значения
void UpdateData(DataType type, IData data) — обновление указанного значения
void Remove(DataType type, int id) — удаления указанного значения
В этих функциях будет описано взаимодействие с базой данных например с PostgreSQL.
Получилось вот так
Теперь надо создать класс для отрисовки окна в редакторе Unity. Создаем папку Editor и в ней скрипт DataBaseEditor. Наследуем его от EditorWindow.
Нужно реализовать переключение между созданными ранее типами данных.
Объявим статичную переменную DataType CurrentDataType и сделаем выбор типа данных в стандартной функции OnGUI()
Тут есть 2 варианта:
- воспользоваться стандартным EditorGUILayout.EnumPopup()
- для каждого элементы enum создать свою кнопку
Лично я предпочитаю второй вариант так получается удобнее. Вот такого кода вполне достаточно
var types = Enum.GetValues(typeof (DataType));
GUILayout.BeginHorizontal();
foreach (var type in types)
{
if (GUILayout.Button(type.ToString()))
{
CurrentDataType = (DataType) type;
}
}
GUILayout.EndHorizontal();
Можно немного поиграть и сделать выделение выбранного типа цветом.
Теперь добавим одну кнопку для добавления данных в нашу базу данных
if (GUILayout.Button("Add"))
{
DataBase.AddData(CurrentDataType);
}
И осталось вызвать наше окно из меню Unity для этого:
- создаем новый элемент меню
[MenuItem("DataBase/EditDataBase")]
- по клику на элемент меню создаем наше окно
static void Init()
{
var window = (DataBaseEditor)GetWindow(typeof(DataBaseEditor));
window.Show();
}
В результате должно получится что-то такое
Теперь нам нужно окошко в котором будет отображаться сама форма для изменения данных.
Создаем новый класс DataWindowEditor и как и ранее наследуем его от EditorWindow.
В этом классе нам нужно отследить 2 события (открытие и закрытие окна).
При открытии будем передавать этому окну данные для отображения и сохранять ранее открытые данные чтоб геймдизайнер случайно не потерял свою работу.
При закрытии сохранять изменения в нашу базу данных.
public void OnOpen(IData data,DataType type)
{
if (_data != null)
{
DataBaseEditor.DataBase.UpdateData(_dataType, _data);
}
_data = data;
_dataType = type;
}
void OnDestroy()
{
DataBaseEditor.DataBase.UpdateData(_dataType, _data);
}
И осталось нарисовать саму форму в OnGUI
public void OnGUI()
{
if (_data==null)
{
Close();
return;
}
_data.DrawGui();
}
Теперь нам надо получить список наших данных. Воспользуемся ранее созданной функцией GetDatas.
И отрисовываем наши данные средствами GUILayout, при клике на элемент открыть его представление.
var datas = DataBase.GetDatas(CurrentDataType);
foreach (var data in datas)
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("Id: " + data.Id + " Name: " + data.Name))
{
var window = (DataWindowEditor)GetWindow(typeof(DataWindowEditor));
window.OnOpen(data,CurrentDataType);
window.Show();
}
if (GUILayout.Button("-"))
{
DataBase.Remove(CurrentDataType,data.Id);
}
GUILayout.EndHorizontal();
}
Вторая кнопка отвечает за удаление указанного элемента.
Теперь перейдем непосредственно к нашим данным.
Создадим новый класс Item.
Добавляем поля, нужные геймдизайнеру.
В моем случае пока это будет цена предмета.
Наследуем класс от ранее созданного интерфейса IData.
Функцию DrawGui() как и в интерфейсе стоит пометить директивой условной компиляции и в теле функции описать само отображение элемента:
#if UNITY_EDITOR
public void DrawGui()
{
GUILayout.Label("Id: "+Id);
Name = EditorGUILayout.TextField("Name: " , Name);
Price = EditorGUILayout.IntField("Price: " , Price);
}
#endif
На этом все. Переходим в редактор и получаем вот такую картинку:
Для остальных типов данных так-же создаем отдельные классы и делаем все тоже само что и для класса Item.
Автор: Blackelf2