Обновление #16 - Профессиональные инструменты

Как герой, который настолько хорош, насколько хорошо его оружие (правило #15), так и разработчик настолько хорош, насколько хороши его инструменты. Поэтому, когда мы перешли на Unreal, нашей основной заботой стало то, сможем ли мы разобраться с "блюпринтами" (визуальной системы создания скриптов Unreal). Мы начали с Unreal 4.14 и нескольких плагинов, чтобы сделать первый шаг и немного освоиться с движком:

  • стандартная библиотека LE Extended (блюпринты, добавляющие общую функциональность и улучшения)
  • Unreal.js (даёт Javascript с поддержкой V8 в Unreal Engine 4)
  • Victory плагин Рамы (библиотека функций блюпринтов С++)
  • диалоговый плагин (редактор на основе узлов)

 

Плагин Javascript нужен нам для связывания скриптов с диалогами: выполнение проверок типа "aod.str > 7" или выполнение таких действий, как "dlgAddItem(35, 5);", но интеграция целого языка программирования и запуск отдельного экземпляра интерпретатора движка для такой базовой задачи - это перебор (это как фоновый запуск Google Chrome в качестве части игры). Кроме того, большие и сложные подсистемы, как правило, со временем вызывают большие и сложные проблемы, которые нам не нужны, поэтому мы продолжали экспериментировать, и это наш отчёт о проделанной работе (технически это отчёт Ника, поэтому я размещаю его электронное письмо и закругляюсь):

#1 - Редактор диалогов

Нам удалось объединить граф блюпринта Unreal (визуальное создание скриптов) с древовидной структурой диалогового плагина в новый ресурс и сделать подходящий редактор:




Это означает, что как структура диалога (текст, части, ответы, ссылки), так и диалоговые скрипты (вызов персонажей, переключение миссий, добавление предметов, разблокировка дверей и т.д.) содержатся в одном ресурсе, а не разбросаны по всей сборке. В то время, как в AoD мы могли только добавлять что-то из заранее определённого списка скриптов, чтобы получить список команд вроде "сделать это, затем это, затем это...", теперь мы можем закодировать сложное действие с проверками, циклами и всем, что только позволяют блюпринты UE, а позволяют они почти всё.

Мы также можем вызывать функции из библиотек блюпринтов, если нам нужно хранить и повторно использовать некоторые общие сценарии (примеры из AoD: scheduleEnding, setMapLighting и т.д.). Нам также удалось подключиться к контекстным меню и категориям ресурсов Unreal, поэтому диалоги (и всё остальное) создаются удобным способом:

 

Его очень легко использовать, и есть только два простых правила:

- чтобы считаться диалоговой проверкой и отображаться в выпадающем списке в свойствах диалоговых узлов, функция должна принимать 0 параметров и возвращать 1 булево значение. Фактически, это значение является результатом вашей проверки и сообщает системе диалога, должен ли появиться этот текст НИП/ответ ИП;

- чтобы считаться диалоговым событием (действием, скриптом, называйте его как вам угодно), ваша функция должна иметь 0 входных параметров и 0 выходных. Она просто делает внутри то, что вы хотите, ничего не принимает и не возвращает.

#2 - Редактор предметов

В AoD мы использовали редакторы ItemGen и CharGen, которые сохраняли списки предметов и персонажей в своих собственных бинарных базах данных. Они нам нравились, и мы к ним привыкли, но Unreal предлагает свой собственный способ хранения, редактирования и поиска данных, во многом значительно лучший, поэтому мы решили отказаться от нашего велосипеда с квадратным колесом и сделать так, как делают крутые ребята. Вот наш новый интерфейс редактирования предметов:

 

Он делает всё, что делал наш старый ItemGen и даже больше:

1) Один класс предметов теперь не будет содержать поля данных из других классов, то есть у оружия ближнего боя не будет поля "ёмкость магазина", у брони не будет "диапазона" и "поддерживаемых атаках". Теперь каждый класс предметов содержит только связанные данные благодаря иерархии наследования. Например: InvItemInfo (свойства всех предметов, таких как название, вес и т.д.) -> InvEquipableItemInfo (добавляет свойства, определяющие 3D-визуальные эффекты) -> InvWeaponInfo (добавляет свойства, общие для всего оружия, такие как тип урона, его диапазон, стоимость ОД, атаки) -> InvRangedWeaponInfo (ёмкость магазина, тип боеприпасов и т.д.).

2) Печатные поля Unreal: моно вводить / выбирать только связанные данные, которые отображаются наиболее удобным способом. Взгляните на свойство "Статический меш" для оружия на изображении выше. Больше это не общее текстовое поле, где приходилось набирать строку и надеяться, что меш/анимация будет где-то в наших файлах, и игра, с благословениями богов, её подключит. Теперь появилось правильное меню с полным списком подходящих ресурсов для выбора, эскизами, полями поиска, параметрами просмотра и полной информации о выбранном ресурсе:



 

3) Могут быть не только свойства, но и функциональность, привязанная к каждому конкретному предмету в виде настраиваемого графа блюпринта. Хотите, чтобы этот предмет искрился при перезарядке или сверкал при броске? Хотите, чтобы эта граната бабахнула при попадании или вместо этого создала эффект искажения? Хотите нанести определённые последствия попаданием этой дубинки, но только этой, а не другими? Что ж, больше никакого дерьмокода и особых проверок для "если это кислота, сделать это, иначе, если это сеть, сделать это, иначе, если это напалм..." В этом предмете все специфические функции полностью автономны - просто поместите, перетащите и соедините некоторые узлы блюпринта, чтобы магия заработала. Мы также можем (и, безусловно, будем) наследовать некоторую функциональность от родительских классов - например, каждый предмет, полученный из оружия дальнего боя, сможет порождать дульную вспышку, каждый предмет каждого класса будет порождать объект карты, если его уронить, потому что основной класс (InvItemInfo) будет знать, как это делается, и т.д.

Мы уже создали основную иерархию предметов, но мы можем в любое время улучшить и расширить её, от добавления новых свойств до создания новых классов предметов. Проверьте Gameplay\Items\BaseTypes\. Для создания нового оружие ближнего боя щёлкните правой кнопкой мыши InvMeleeWeaponInfo и выберите "Создать дочерний класс блюпринта". Вот и всё! Назовите его, отредактируйте его свойства и переместите в соответствующую папку (например, Gameplay\Items\Weapon\, но позже мы определим конкретную структуру папок). Можно легко найти любой предмет из сотен, которые у нас будет, набрав пару символов из его названия в строке поиска обозревателя содержимого. Кроме того, ваш новый предмет теперь будет отображаться во всех меню выбора, где вам нужно выбрать предмет - например, в слоте оружия персонажа в редакторе персонажей. Кстати говоря...

#3 - Редактор персонажей

Он похож на редактор предметов - простой конструктор LEGO для всех ваших потребностей в редактировании персонажа, включая обзорное окно с бумажной куклой, которая будет мгновенно отображать всё выбранное вами снаряжение, настройку внешнего вида (позже) и обновление производных параметров в реальном времени по мере изменения шмоток:


Некоторые замечания:

1) Проверьте Gameplay\Characters\Database\BaseTypes\ - это то, где мы будем хранить типы "существ". Каждое существо будет иметь уникальные слоты снаряжения, код блюпринта для запуска анимации, набор мешей и правил, которые отображают/скрывают их, и другие функциональные возможности блюпринта данного существа - какому ущербу оно подвержено, какие последствия на него влияют и т.д. Например, растение в пустошах - это существо, у которого нет слотов одежды, есть один меш тела и один (возможно, невидимый) предмет оружия. Робот - это существо, у которого есть броня, слоты оружия и инвентарь, но нет шляп или противогазов и т.д. Таким образом, у каждого типа существ есть свои свойства, и больше никакого кода-спагетти, например, "если существо - человек и пронзён, то показать копьё; если это демон - то нет, в этом случае показать 200 кусков тела, если он мёртв и сломан; если это механоид, то показать только меш под названием "тело"; если это - растение, то показать trunk_01 и 02..."

2) Чтобы создать нового персонажа, щёлкните правой кнопкой мыши HumanCharacterInfo, выберите "Создать дочерний блюпринт класс", назовите его и переместите на одну папку вверх из BaseTypes. Теперь можно выбрать вашего вновь созданного персонажа в раскрывающемся списке CharMarker. Если вы когда-нибудь переименуете персонажа, то Unreal автоматически пройдёт по всем его ссылкам во всех CharMarkers и везде обновит его имя, поэтому невозможно испортить dbID.

Короче говоря, основная система уже существует - мы можем начать добавлять диалоги, предметы и персонажей прямо сейчас, что позволяет нам придерживаться рабочего графика (пока что).