Портирование игры на Unreal Engine 4

Портирование игры на Unreal Engine 4

В этой статье расскажу про опыт переноса игры, созданной с использованием Marmalade SDK, на Unreal Engine 4.

Привет всем!

Меня зовут Андрей. Я — независимый разработчик.

Сейчас занимаюсь созданием ассетов для Unreal Engine 4 и разработкой собственных игровых проектов на UE4.

В геймдев пришел в 2005 году, начав в компании Haggard games. Там проработал около 8 лет над серией игр Смерть Шпионам (Death to Spies) и Alekhine’s Gun. В круг моих задач входил менеджмент арт команды и левел-дизайн. Почти все уровни, с точки зрения арта, наполнения и сеттинга в этих играх были созданы мной вместе с командой замечательных 3d художников.

Потом успел поработать PMом в одной из местных компании и поучаствовать в некоторых сторонних проектах в качестве разработчика.

После, полностью ушёл в независимую разработку, выпустил два проекта для iOS/Android и один из них — на PlayStation 4.

На данный момент новый проект находится на early pre-production стадии и о нём пока рано что-либо рассказывать.

Поехали!

Кратко об игре

Портирование игры на Unreal Engine 4

Это стилизованная лоупольная головоломка в Sci-fi сеттинге.

В игре 50 уровней. В основном — комбинаторные головоломки.

Игрок управляет космическим дроном, которым взаимодействует с космонавтами. Цель каждого уровня — эвакуировать всех с космической платформы.

Космонавты обладают различными свойствами: некоторых можно цеплять и перетаскивать, другие могут толкать соседнего космонавта. Есть хрупкий космонавт, которого нельзя сбрасывать с высоты больше своего роста и т.д.

Отдельно хотелось бы отметить: в игре содержится почти час специально написанной композитором Helge Borgarts музыки в стиле space ambient. Если вам нравится музыка в таком стиле, уверен — треки из игры вам зайдут.

Портирование игры на Unreal Engine 4

Что было на входе

Портирование игры на Unreal Engine 4

Изначально игра была написана с использованием Marmalade SDK под платформы iOS и Android. Это не игровой движок, а скорее кросс-платформенное API. Т.е. В нём нет специфических сущностей вроде Actor, Camera, уровень и т.д. Из языков в нём были C++ и Lua, из платформ — iOS, Android, PC и Tizen.

Было три фактора, которые спровоцировали наш отказ от мобильных версий.

  • Вскоре после релиза игры компания Marmalade закрылась, а моя лицензия — истекла.
  • Слабая монетизация проекта. Хотя отзывы у проекта были положительные и оценка выше 4.5 баллов, отдача совсем не вселяла оптимизм, а чемоданов денег на трафик у нас не было.
  • Мы испробовали разные способы управления, копались в настройках - но достичь нужной отзывчивости управления на тачпаде не удалось.

По итогу убрал все мобильные версии и прекратил их поддержку. Но бросать проект не хотелось: всё же большинство отзывов были положительными. Поэтому решил перенести игру с канувшего в лету Marmalade SDK на Unreal Engine 4.

Что у меня было:

  • Код (C++) написанный под Marmalade SDK.
  • Управление для Touch Screen.
  • Ассеты в исходниках
  • Уровни в XML формате
  • Самописный редактор уровней, который на выходе выдавал XML файл, описывающий структуру уровня со всеми необходимыми данными.
  • Шейдеры на GLSL
  • Локализация на 4 языка
  • Отсутствие возможности скомпилировать рабочий билд

За дело!

Портирование игры на Unreal Engine 4

Формально работы по переносу игры можно разбить на три этапа:

То что пришлось удалить полностью и сделать заново

Save\Load система, управление, Pawns, Камера, Система частиц, загрузка ассетов, материалы, конвертор уровней из XML в UE4, реимпорт всех 3д моделей и ассетов в UE4 и т.д.

Существенно править

Пришлось приводить исходный С++ код к типам UE4 (FVector, FTransfrom, UOBJECT и т.д.) и и убирать все хвосты, оставшиеся от Marmalade SDK.

Так же потребовалось добавление BluerpinrImplemantableEvent для того, чтобы С++ код мог отправлять сообщение Blueprint наследнику. Это используется, например, когда все космонавты эвакуированы с уровня и С++ вызывает event LevelComplete.

Добавление BlueprintCallable для того, чтобы Blueprint мог вызывать и использовать С++ код. Например, для расчёта рейтинга игрока. Сам метод расчёта написан на С++, к нему обращается Blueprint и получает результат расчёта.

Создание структуры уровней в виде sublevels и полностью новой логики камеры.

Минимальные правки

Меньше всего изменений было у 3д моделей. В основном — фиксы по мелочи.

После выполнения предварительных работы с кодом и ассетами приступил к переносу уровней.

В версии на Marmalade SDK уровень представлял собой два XML файла. Первый описывал игровую структуру уровня и объекты - трансформ, свойства, тип и т.д.

Второй XML файл описывал декоративные элементы - расположение мигающих ламп, вентиляторов, антенн. Декоративные элементы не оказывают влияние на геймплей, но придают визуальной живости уровням.

Портирование игры на Unreal Engine 4

Был создан базовый актёр - BP_AstroBase, содержащий необходимую структуру данных из версии на Marmalade и от него унаследованы все 4 класса космонавтов и другие динамические объекты - кнопки, конвееры, телепортаторы, лифты.

Мне не потребовалось придумывать структуру заново и переделывать всю игровую логику. Разве что убрал все несущественные, в основном косметические, переменные и данные, которые были необходимы для работы Marmalade версии.

Потом создал актёра для декора. Он содержит все типы декора на уровнях, отрисовывает необходимую в данный момент модель и осуществляет с ней действия.

Конвертер читал два XML файла, парсил их и спавнил актёров в Unreal Engine 4. Всё что мне оставалось - это добавить StaticMesh c геометрией уровня.

После финализации конвертера перенос всех 50 уровней занял 1.5-2 часа.

Архитектура игры

Портирование игры на Unreal Engine 4

В игре есть 3 вида Pawns:

  • MainMenu Pawn. Используется в главном меню и обрабатывает нажатия на кнопки Start Game, Options, Help и т.д. Полностью на Blueprint.
  • Levels Pawn. Обрабатывает скорллинг между планетами и выбор уровней. Полностью на Blueprint.
  • PlayerPawn. Базовый класс написан на С++ и в нём содержится вся геймплейная логика игры, перенесённая из версии на Marmalade SDK. От базового класса унаследован Blueprint, который обрабатывает все input event, restart и подобное.

GameInstance - содержит весь системный функционал игры: загрузку/выгрузку уровней, сохранение и загрузку состояния игры, подсчёт рейтинга, переменные игры, которые необходимо передавать между уровнями, например общий игровой таймер. Написан на С++ и имеет Blueprint наследника.

Уровни сделаны по схеме sub levels, т.е. это level streaming. Такой подход имеет два существенных плюса:

  • Не нужно делать отдельный поток для беспрерывного проигрывания музыки.
  • Экономия размера билда. Все общие элементы, используемые в большинстве уровней, находятся в persistent (постоянном уровне) и не требуют их дупликацию в каждый уровень. К таким элементам относится: MusicPlayer, задник с текстурой, космические корабли, которые летают на заднем фоне, PostProcess Volume, эффект звёзд.

Цикл работы логики игры на UE4 можно описать так:

  • Ожидание события от игрока в Pawn (выбор уровня, нажатие опции и т.д.)
  • Выгрузка текущего уровня (всегда загружен какой-либо уровень)
  • Сохранение текущих данных (номер уровня, таймер и т.д.)
  • Загрузка нового уровня
  • Передача контроля Pawn’у

Синхронизация Actor’s Tick()

Портирование игры на Unreal Engine 4

В версии на Marmalade SDK все расчёты логики, update, render и т.д. выполнялись внутри MainLoop, т.е. с однозначно заданной последовательностью.

В UE4, каждый актёр выполняет Tick() асинхронно. Основная логика находится в PlayerPawn, из-за чего возникала ситуация, когда часть актёров могла выполнить свой Tick до того как он выполнится у PlayerPawn, а другая часть уже после. Чтобы решить эту небольшую задачу удобно использовать метод AddTickPrerequisiteActor(). Так мы напрямую указываем последовательность тиков в разных актёрах.

Задав всем актёрам (кроме PlayerPawn) такое условие, мы помещаем PlayerPawn наверх списка и он всегда будет тикать первым.

Скажу честно — я тестировал с AddTickPrerequisiteActor и без него и существенной разницы не заметил. Поэтому в финальной версии это решение отсутствует.

Teleport FX

Портирование игры на Unreal Engine 4

В игре есть телепорты и созданный специально для них эффект телепортирования. В версии на Marmalade SDK он был реализован с помощью самописной системы частиц и представлял собой пролетающие из start в target по траектории близкой к параболе частицы. Одновременно может выполняться сколько угодно телепортирований.

В UE4 наиболее быстрым решением оказалось использование InstancedStaticMeshComponent. Во-первых, логика расчёта траектории у меня уже была. Во-вторых, ISMC отрисовывается за 2-4 (зависит от материала) draw calls.

Потребовалось лишь адаптировать логику для апдейта трансформов ISMC. В UE4 так же существует HierarchicalInstancedStaticMeshesComponent, который поддерживает LODs, но в моём случае поддержка lods не требовалась.

Улучшено для PlayStation 4

Портирование игры на Unreal Engine 4

Для PlayStation 4 мне хотелось выпустить более качественную версию.

К существенным улучшениям можно отнести:

  • Добавление скелетной анимации для космонавтов
  • Два новых саундтрека
  • Динамический Ambient Occlusion
  • Эффект при эвакуации космонавта
  • Дополнительные 8 языков локализации
  • Deferred UE4 renderer

Сроки

Портирование игры на Unreal Engine 4

У меня ушло ровно 30 дней по 12-14 часов в сутки от текстовых исходников до полностью рабочей игры на UE4.

Скажу честно, после такого кранча я пару дней просто отсыпался и не реагировал на внешние сигналы.

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

Трейлер

Портирование игры на Unreal Engine 4

Пару слов о создании стори трейлера я решил добавить в эту статью потому, что он создавался под UE4 версию. Версия на Marmalade SDK имела только геймплейный трейлер.

Полагаю, он, положительно сказывается на восприятии игроком информации об игре на первоначальном этапе. Трейлер рассказывает небольшую историю и плавно подводит к действиям в игре и способствует сопереживанию судьбе маленьких героев.

Созданием трейлера занимался другой человек, за что ему большая благодарность. Несмотря на то, что он не обладал большим опытом в UE4, ему удалось быстро разобраться во всех необходимых инструментах и собрать трейлер в Unreal Engine 4 с помощью sequencer и других инструментов.

Портирование игры на Unreal Engine 4

Первоначально был только story board, нарисованный мной от руки - фактически, ключевые кадры трейлера. Далее мы обсудили сценарий, что нужно было получить на выходе и какой продолжительности.

Через пару недель был готов драфтовый синематик без эффектов, текстур, звука, света и прочих красивостей. Он содержал в себе финальные тайминги, ракурсы и анимацию.

После пары мелких правок он отправился к композитору, который под видеоряд написал саундтрек. Одновременно с этим синематик был перенесён в UE4 и стартовала работа по финализации - свет, эффекты, материалы и т.д.

Еще через 12 дней я получил финальный проект в UE4.

Мне оставалось подправить гамму, т.к. она была слишком тёплая и, по моему мнению, слабо ассоциировалась с космосом, а также пофиксить косяки с DOF.

Еще через пару дней приехал саундтрек от композитора и я собрал финальную версию трейлера.

На все работы от создания сториборда до финального трейлера ушло 23 дня.

Выводы

Портирование игры на Unreal Engine 4

С момента релиза на PlayStation 4 прошло уже более 3 месяцев и я могу взглянуть на игру несколько отвлеченным взглядом и сделать определённые выводы:

Сократить продолжительность трейлера

Даже путём изменения story board. Примерно на 15-20% он урезается без потери идеи и motion design.

Устаревший способ подачи обучающих уровней (tutorials).

Обучающие уровни это первые 10 уровней. Они не содержат головоломок, лишь демонстрируют игровые возможности. Это очень очень устаревший подход. В идеале, надо было переделать на подсказки для уровней, где появляется какая-либо новая механика.

Отсутствие глаз у космонавтов

Несмотря на то, что космонавты анимированные и уже не воспринимаются мумиями в космосе, нужно было добавить глаза для передачи эмоций — для большей асоциации с живыми героями.

UX

После прохождения уровня появляется надпись Level Complete. К сожалению, это происходит тривиальным образом - просто появляется надпись и всё. Ощущение достижения у играющего не возникает. Нужно было добавить анимацию и major звуковой эффект, чтобы подчеркнуть важность достижения.

Последовательность уровней

Первые уровни крайне простые и плейтестеры говорили, что играть скучно. Интересно играть становится только примерно после 22-23 уровня. Можно было переставить уровни местами, дав вызов уже на 13 или 14 уровне в виде достаточно сложной головоломки. К сожалению, это потребовало бы много дополнительной работы.

Заключение

Это был интересный во всех отношениях опыт и мне хотелось бы поблагодарить всех людей, которые так или иначе принимали участие в создании игры!

Отдельная большая благодарность компании Sony Interactive Entertainment за возможность выпустить игру на PlayStation 4, дав возможность любителям головоломок поиграть в неё.

Специальное спасибо Яну Корвину за редактуру текста статьи!

Благодарю за уделённое статье время, всем хороших игр!

Для связи со мной, можете написать мне в Facebook

Портирование игры на Unreal Engine 4
4141
15 комментариев

Спс, интересная статья.

А до переноса этой игры, сколько времени занимались UE4? Какой опыт?

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

2

UE4 активно занимаюсь более 2х лет.  В целом у меня был опыт с разными технологиями - Marmalade, Cry Engine, custom driven решения в виде движка для Смерть Шпионам и т.д., поэтому адаптация к UE достаточно быстро прошла )

Изучаю UE4, насколько я знаю, в движке очень много классов приспособленных под свои задачи, например, для меню UMG, UI классы, для игровой логики GameMode насколько помню и понимаю. У вас везде используется Pawn, класс который в UE4 создан для реализации механики персонажей, NPC на уровне.  Это связано с тем, что игра создана не с нуля на UE4, а путем портирования? Или мобильные игры на UE4 так создаются? Просто я заметил изучение UE4 на моем примере, да и в общем чаще всего проходит с уклонам на большие открытые миры, когда в редакторе создаешь landscape, раставляешь StaticMesh и потом начинаешь писать логику, игровые механики и т.д. 

GameMode используется в мультиплеерных играх. Т.к. у меня single player мне он не понадобился. Pawn используется для удобства, т.к. имеет всю необходимую коммуникацию, которая мне требовалась для реализации, к тому же это и есть представление игрока на уровне и тут не имеет никакого значения, как он визуально представлен.

Т.к. вся game play логика это достаточно массированный объем кода, не было смысла это разносить по классам, в противном случае это означало по сути создание игры с нуля. Такой задачи я перед собой не ставил. 

1

Андрей, а с вами можно пообщаться ВКонтакте? Можете мне там написать (мой ВК в профиле есть в "Информации")?

Ок. Написал вам в ВК. Добавлю в статью контакт свой.

1

Комментарий недоступен