MOVE and UNPACK: История разработки 2D игры на Unreal Engine 4
Это лучшая версия статьи из всех имеющихся экземпляров в разных местах. Всё благодаря Gyt-у и редактору постов на сайте. СЛАВА ГИТУ!
>> Видеоверсия в другом посте <<
Аннотация
Поучаствовал в конкурсе по разработке игр и при этом начал изучать новый движок — Unreal Engine 4. Поделюсь своим опытом в этой статье. Думаю, это может быть интересно тем, кто посматривает на этот движок, или наоборот уже специалист и готов мне рассказать, как надо правильно. Внутри статьи очень много материала.
Введение
Очень кратко расскажу о своём бэкграунде: у меня около 10 лет опыта в GameMaker, до этого я почти написал свой движок на Си++ c DirectX и OpenGL. Сделал пару игр на Unity. Выпустил две коммерческие игры на GameMaker. В последнее время я пробую для себя новые движки: Godot, RenPy. Давно приглядывался к Unreal. Время пришло.
О игре, словно Gamin не знает о этой игре, ну да ну да.
Моя игра Move and Unpack или же Двигай и Разгружай* это 2D top-down игра о распаковке и расстановке мебели в квартире. Игра выполнена в стиле чертежей c pixel art графикой, шуршащими самодельными звуками и нейросетевой музыкой. Тема конкурса — «Не по размеру» — раскрывается через вместительность коробок для предметов, лимитах пространства для расстановки, рисунки на внутриигровых постерах, а так же как герой лихо управляется с любыми габаритными предметами. Надеюсь, я верно передал ощущения расстановки предметов в квартире, весёлые и раздражающие моменты.
Вдохновением для меня послужила практически реальная ситуация о размещении в первую очередь мебели в квартире. Сначала смеёшься, а потом рыдаешь. И так поставишь и сяк, а всё неудобно выходит, и приходится придумывать иную позицию. А ведь это ещё без учёта других вещей! Так что, можно сказать, основано на реальной истории!
* перевод скорее «Переезд и распаковка»
Концепция
Поиск идеи
Как уже понятно, выбрал движок Unreal Engine 4. Да, для 2D игры! Началось это как безобидная шутка «на следующий Гаминатор». Затем я подумал «А почему бы и нет?» и серьёзно решил сделать 2D пиксельную игру на движке, который не особо для этого предназначен! Звучит как 3D в GameMaker 2D, а я таким часто баловался.
Хотел смотреть материалы по движку ещё с анонса конкурса, но решил отложить это дело до непосредственных работ, а то кто знает какая тематика будет и какая идея меня посетит! Это, конечно, ставило меня в сложное положение, ведь знаний по Unreal у меня нуль — открывал лишь пару раз, ничего там не сделал.
И вот, когда тема показалась всем, то стало ясно, что я «проиграл». Всё дело в том, что хотел использовать подобное (тематику разных размеров) для продолжения Бумажного подземелья. Удачный пинок, чтобы участвовать в этом конкурсе именно с продолжением Бумажного. Но нет! Ведь та шутка про Unreal уже превратилась в серьезное обещание и себе, и другим! К тому же я давно хотел попробовать этот движок, а это был хороший повод.
Конкурс стартовал 15 марта, а уже 16 числа я нарисовал первый концепт и общие идеи. По своей традиции всю игру хотел описать одним листом А5. Был запасной вариант, если ничего не получится — сделать Понг! Зарисовал небольшие идеи не-по-размерности. Например, как шутка-мем про большие, несоразмерные к персонажам мечи в японских играх. В этот раз написал-нарисовал много концептов А5. Где-то до 19 марта очень долго и много описывал концепт в ТХТ файле, потом это аукнулось.
Зарисовки несоразмерных персонажей превратились потом во внутриигровые постеры. Очень схематично сделал концепты, а сами спрайты постеров рисовал уже под самый конец сроков конкурса как не самый важный аспект игры. Постеры изобилуют отсылками, но об этом позже.
РАЗРАБОТКА
Принимаюсь за дело
В отличие от прошлых участий в конкурсах, в этот раз начал вести исторический лог и записывать какие-то моменты из разработки, поэтому восстановить некоторые вещи проще, вплоть до конкретных дат. Например, 21 марта я уже скачал Unreal и пытался что-то реализовывать, хотя ТХТ файл концепта был не дописан.
Скачать PDF (он же TXT) концепт можно на странице игры сайта Itch.io. Там же можно скачать и саму игру.
Пошёл против своих же идей и начал детально описывать идею. А чем же мне аукнулись горы концептов А5 и километр текста в ТХТ? А тем, что устал на этапе концепта, от чего чуть не сдался. Придумка шла не так гладко, и постоянно было непонятно, как это превратить в игру. Много писать — не игру делать. Если нет четкого видения игры, то и получится каша.
Дошло до странного: до последнего момента не мог определиться с управлением. Базовыми вещами! Не мог определиться. Не мог и всё. Определиться не мог! То ли это игра управляется курсором, а персонаж под управлением ИИ будет проверять предметы, то ли игрок управляет персонажем и расставляет предметы, а потом и проверяет их. Естественным отбором победил второй вариант как самый простой в реализации.
Первые проблемы
Гнев игробогов за то, что я оставил GameMaker, не заставил себя долго ждать. Они портили мне опыт с Unreal Engine. Я стал одним из тех счастливчиков, у которых с определенного времени пропадало контекстное меню! Да, вот так! Берёт и пропадает. Связано это было с Nvidia драйвером или чем-то таким. Проблеме уже года 3.
Проблема с контекстным меню и её временное решение в виде перезапуска движка мешали войти в ритм, поток разработки. Это едва не стало одной из причин почему мог бросить разработку в начале. Решение, конечно, нашлось позже: отредактировать реестр заменить лишь какое-то одно значение. После этого критичных проблем с Unreal не заметил и разработка продолжилась в более-менее стабильном темпе, но всё равно пару раз были проблемы.
Подготовка ресурсов
Столкнулся с организационными вопросами. Дело в том, что с опытом GameMaker я принял их конвенцию имён, так сказать, даже в файлах. В итоге у меня спрайт в формате png мог называться, например, s_hero.png, где s — это sprite. Термины Unreal и его работа с ресурсами иные. Пайплайн добавления спрайта с анимацией такой: добавить текстуру, извлечь из неё спрайты (регионы на текстуре), а потом добавить последовательность спрайтов в flipbook.
В итоге, чтобы соответствовать рекомендациям Unreal, файл пришлось называть не s_hero.png, а T_Hero.png*, из которого образуется T_Hero текстура, S_Hero_Walk_0, S_Hero_Walk_1, …, S_Hero_Walk_n спрайты, а потом FB_Hero_Walk анимация флипбук.
* на самом деле не так важно как называется исходный файл
Unreal оперирует текстурами и текстурными атласами (их ещё называют Sprite Sheet, набор спрайтов в одной текстуре), пришлось придумывать, как компоновать спрайты. Могу ошибаться, но кажется Unreal, в отличие от GameMaker, не собирает атласы самостоятельно.
Сначала попробовал программу Texture Packer, взял пробный период, т.к. она платная. Использовал графический редактор Aseprite и понял, что удобнее рисовать сразу атлас со всеми объектами, поэтому не было смысла компоновать отдельно. В этой программе есть инструмент Slice — нарезка областей и … он не подходит для экспорта в Unreal. Бегло поискал — нет готового решения. Тогда я быстро с использованием аналога chatGPT накидал скрипт конвертации — снова выручили нейросети. Теперь я могу экспортировать нарезанный SpriteSheet из Aseprite в Unreal.
Работа с движком
Март, 27 число. Разработка идет крайне туго, рисую на бумаге логические и архитектурные схемы интерактивности, как выстроить классы и прочее. Много времени уделяется изучению движка, например, тому, что есть Actor и какие компоненты у него. Раньше видел, но всё равно очень непривычно программировать через Blueprints. Впрочем, описание архитектуры на бумаге очень помогло и действительно лучше так делать, чем бежать «писать код», ОСОБЕННО в Unreal. Если в GameMaker простительно писать, извиняюсь, говнокод, то в Unreal это потом аукнется.
Мне показалось, что переделывать визуальный спагетти-код куда сложнее, чем обычный текстовый код. К тому же, Unreal Blueprints очень странно работает с Git. Через систему контроля версий не посмотреть изменение в коде Блюпринтов, что становится крайне неудобно (потом я узнал, что можно смотреть разницу внутри самого Unreal, но удобства это не добавило).
Неочевидно работает то, что если меняешь родительский Блюпринт, то меняются и дочерние, словно в них внесли изменения.
Незапланированный перерыв
Разработка начала буксовать, и чтобы хоть что-то делать, я решил страшное — устроить небольшой рефакторинг спагетти-Блюпринтов. Стало чуть лучше, но всё равно не идеально. А затем и вовсе на дня 3 отложилась разработка. Смешно, что этот перерыв выпал и на 1 апреля.
Уже 2 апреля решил порисовать и обновить спрайты и … по моим записям хронологии у меня пропал спрайт! Какой, где и как — непонятно. Но разве я буду обманывать сам себя?! Есть также пометка, что UNREAL ВИНОВАТ, что, конечно, возможно, ведь именно в этот момент я узнал, что он как-то странно работает с переименованием и перемещением ассетов, и нужно нажимать специальный пункт меню, который называется «Fix Up Redirectors in Folder».
Внезапная смена курса
А вот 3 числа отвлёкся на другой проект! И тоже на Unreal! В этот раз правда от первого лица и с нулём механик. За один день сделал простую штуку про самолёт по мотивам сна. Но здесь не об этом, хотя если захотите и попросите — напишу и о разработке G27 Airplane.
Создание Меню
После отдыха решил сменить область разработки самой игры — засел за создание меню. Рисовал графику — затянул меня процесс воплощения спрайта грузовика, сидел над каждым пикселем. Впрочем, думаю иногда очень полезно в рамках конкурса переключиться на иную область, чтобы отдохнуть от кода\музыки\графики и сделать код\музыку\графику, особенно если ты соло-разработчик.
С готовым спрайтом грузовика и пришла идея сделать анимацию меню. Сразу же понял, что хочу сделать «прогерскую анимацию»
Программная анимация планировалась очень простая: колёса крутятся, кабина с корпусом сжимается-разжимается. И как же я удивился, что не было простого способа сделать анимацию в Акторе, как это было в Godot, например. В Unreal же есть некие Cinematics для уровня, где мне таки удалось сделать анимацию грузовика. Сначала я сделал бесконечный скролл заднего фона через материал, а уже потом нашёл эти Кинематики.
Мне пришлось полностью скопировать кинематик для аналогичной сцены в конце игры, потому что я не разобрался, как создать анимацию в Акторе. Непонятки с Акторами продолжились — каким образом сделать составной Актор из нескольких с редактируемыми наследниками? Пришлось пере-придумать пару моментов и выдумать, как их реализовать, но это относится не к Меню, а к базовому классу расставляемых предметов.
Продление конкурса и Плакаты
Изначально я хотел успеть к дедлайну 7 числа, даже был близок к этому. Продление на неделю, до 14 апреля, было кстати — микропроблемы и дела постоянно возникали во время разработки.
Почувствовав облегчение от сдвига сроков сдачи или, может быть, так и не отдохнув от спагетти-Блюпринтов, решил зарыться в пиксели снова. В этот раз пошли в дело плакаты-постеры, вот несколько забавных фактов:
Один из плакатов на тематику большого трона и короны. Смотрю заявки на сайте конкурса и увидел, что TheDreik делает игру про корону. Мне показалось интересным сделать прямую отсылку к его игре — спросил разрешение, спрайты попросил и быстро накидал постер. От меня здесь рисованное название и композиция, а другая графика от Дрейка;
Второй плакат именуется «кошкодевочка». Очевидно, что должно быть изображено, но играет мета-шутка надо мной — у меня не получается рисовать конкретных животных. Например, когда я рисую кота, про него говорят: «Это пёс»! В этот раз смысл рисунка был в больших ушах, я предполагал кошачьи уши, но вышло совсем всё не то! Если хотите, то получился фурри-персонаж (как я понимаю, они достаточно сильно отличаются от понятий «кошкодевочка»)! Под конец рисования вдруг понял, что это ведь похоже на одного зверька — фенек. И долго не думая, беру и называю персонажа на постере DJ Vulpes zerda, что есть научное название этих самых животных;
Третий момент в том, что у меня были слишком абстрактные зарисовки и от этого придумалось несколько версий одного постера — сначала я решительно выбрал один, но потом дал слабину и зарисовал все три варианта с мечом, вот они, слева направо: Отсылка на Final Fantasy 7, Devil May Cry 3 и неслучившийся сиквел моей игры с КОД про инопланетного повара.
Начинается звуко-музыкальная прямая
Апрель, 10 число. Начинается финальный этап работ над игрой. Для меня всегда последний этап это звуки и музыка. В этот раз ничего нового: я пошуршал в микрофон и покопался в своих старых записях.
Звуки коробок это буквально звуки коробок, хотя ладно — это звуки шуршания картона от коробки. А картонка эта при транспортировке защищала две книжки, которые я приобрёл относительно недавно — одна по геймдизайну, другая по музыке.
По-честному раскрывал картонку, записывал, обрабатывал. Нравится мне это дело, возиться с обработкой аудио, есть в нём что-то от творца. Однако, забегая вперёд, скажу, что после творческого этапа по наводке TheDreik приобрёл себе пак звуков, так что кто знает — может быть, это последняя моя конкурсная игра с моими собственными звуками.
В Unreal звуки можно воспроизводить через ресурс типа Cue. Это по сути своей тоже блюпринт, но для исполнения логики звука. Например, именно через такой Cue (на самом деле я все звуки продублировал в Cue) собран звук завершения этапа: можно добавить в один «звук» несколько «проигрывателей» и задать им задержку, либо ещё какие-то параметры воспроизведения. Очень интересная штука эти Cue.
Самым монструозным звуковым блюпринтом является «шаг». На всём этапе разработки я не мог выбрать, какой же мне комплексный звук оставить: тот, что записал специально, или же с моих старых проектов малозаметные шуршания ног. В один момент меня озарило, что я могу смешать звуки в один! Из нескольких новых берётся звук, потом смешивается с одним из двух старых. При правильных параметрах звучит всё достаточно интересно.
Музыка
Конечно, я стараюсь делать музыкальное сопровождение сам, но мои умения слишком малы, да ещё и время поджимало. Тогда подумал взять где-то уже готовую бесплатную музыку для инди игр, даже послушал пару треков, но всё было не то. Сколько времени уйдёт на поиск нужного трека? Не эффективнее ли научиться писать что сам захочешь? Не знаю.
На этот конкурс много разработчиков использовали нейросетевую музыку — Suno.com. Что ж, я решил попробовать, достаточно удачный момент — времени мало, никаких толком идей в голове, кроме пары описывающих слов.
Всё что я придумал к музыке: в меню должна быть весёлая, но не назойливая, в игровом процессе лёгкая фоновая, в конце торжественно забавная. И, как мне кажется, нейросеть удачно справилась со своей задачей!
Какая-то весёлая мелодия, джазовый эмбиент и чуть ли не олимпийские поп-фанфары. По сути, со второй попытки вышли подходящие треки, и я залил их прямиком в движок. Это оказалось достаточно эффективно.
Причесать игру
Решил устроить рефакторинг миссий — до этого одни данные были в Акторе, другие в таблице, третьи в триггере-зоне. Затем, после переосмысления, стало достаточно удобно — все данные миссии хранятся в одной DataTable.
Физика
Оставалась одна большая проблема в игре — физика. Ну, помимо странного геймдизайна, конечно. Боролся разными способами, но ничего не помогало. Вышло даже так, что в попытках сделать «как лучше» вышло «как всегда» — я сломал игру полностью. Думал, что знаю коллизии Unreal и каналы для trace, но как оказалось — ничего я не знаю. Наделал для столкновений каналы-пресеты: расположенный предмет, предмет в руках, стены, пол, плакат. Кое-как решил проблемы, но одного врага мне не удалось победить совершенно никаким образом — Стол-Г. Помимо своей формы буква отсылает и к тому как этот стол можно назвать при использовании в игре. Он буквально рассыпается на части, ведь там два коллайдера, а почему рассыпается? Не могу понять.
Последний день разработки
13 число. Суббота, не пятница. По сути игра готова, началась полировка того, что имеется. Финальные штрихи. Одним из таких штрихов стали иконки для выбора уровня. Сначала я хотел поступить очень просто, как я уже делал в КОД 19: BIBONICLELE — сделать скриншот из редактора уровня и уменьшить картинку.
Но всё оказалось не так просто: в Unreal нельзя из Top вида включить Gameview* и с Unlit освещением. Вернее как. Нельзя именно в том порядке, который я описал! Что?! А вот что. Оказывается, можно в Top view включить Game view с Unlit светом: для этого надо ещё в Perspective включить игровой вид, освещение, а уже потом включить Top. Почему? Почему? Почему?! Не знаю. Крайне странно.
* Gameview — метод отображения в редакторе уровней, который максимально схож с тем, что увидит игрок в игре.
Вспомнил об одной функции в Photoshop, результат удивил! Но не подходил. Не имеет смысла делать такой даунскейл.
Иконки уровней
В своём любимом Aseprite, лучшей программе для пиксель арта, подготовил холст, закидывал туда уменьшенные замыленные картинки уровней, а потом обрисовывал контур квартир, добавил несколько штрихов и вот иконки уровней готовы!
Убрать в коробку
Совсем внезапно придумал добавить новую фишку — убрать предмет из рук в коробку. Понимая, что вероятно это даст 1001 проблему (так и получилось), я внес этот функционал как бонус за прохождение игры. Быстро добавить это в игру позволило то, что так уже работали плакаты — их можно убрать в коробку.
Кстати, случайно сделал одну визуальную ошибку в последнем уровне, когда ставил тайлы. Думал убрать, но потом решил, что было бы забавно оставить и подчеркнуть это — эдакая пасхалка.
Ключевой арт, финал
Абсолютно финальным действием было рисование заглавного арта. В последний момент решил нарисовать так называемый «маркетинг арт». В планах не было, но что-то загорелся мыслью и совсем не понял, как это произошло — смотрю, а арт уже готов! Хотел использовать композицию из главного меню, а в итоге она потерялась где-то на заднем фоне. Центральный элемент — это, конечно же, персонаж с коробкой в руках. Забавно, что коробки-то герой не таскает в этой игре.
Выпуск игры
Игра готова. Можно выдыхать. Марафон по тасканию виртуального дивана подошёл к концу, теперь разве что дополнить его подушками.
Пошли отзывы. Первый был от E1e5en, где были аспекты, которые я пытался исправить в багодневной версии, но не совсем удачно. Второй отзыв был от Kot211 на его стриме. Помимо всплывших багов, выяснилась интересная вещь: для игроков неочевидно, что список дел нужно делать по порядку. Это сбивало их с толку, возможно, негативно влияло на оценку игры.
Во время разработки, конечно, и я сам запутался в этом, т.к. логика подсказала, что выполнять можно в любом порядке, но я же почему-то закодировал выполнение строго последовательно? Странно, но ладно. Такова геймдизайнерская мысль!
К сожалению, выяснилось, что есть бага, которая создаёт ложное впечатление, что предметы тоже нужно ставить в определенном порядке.
Локальный лор и отсылки
Не знаю, куда отнести эти факты, но очень хочется поделиться:
- Иконка кнопки привязки к сетке (snap) — из моего локально мем-долгострой проекта TheСтенки! Прямиком оттуда скопировал.
- Отсылки в постерах уже озвучены, но ещё раз: Final Fantasy 7, Devil May Cry 3, игра Дрейка на этот же конкурс, моя игра на КОД 14 «Рецепт» Великий Готовить Приключение, зверёк фенёк.
- Звук штанги, беговой дорожки и велотренажера это звуки из моей игры на КОД 20 «Движение — жизнь», которая называется «Спотрмен» (именно так, НЕ Спортсмен).
- Из Спотрмена ещё звуки компьютера и телевизора.
- Звук стола плотника был в игре Gaminator 24 Infinity и в игре Про Робота с Gaminator 22.
- Мелодии при взаимодействии с синтезатором тоже с КОД 21 «Судя по звуку», где я сделал игру про угадывание мелодии.
- Из мелодичной игры так же звук восторга при завершении этапа.
- Персонажу игрока снится, опять же, моя игра на КОД 18: «Свободное падение», которая называет Супер Матвей Галаксеевич.
ВЫВОДЫ
Время итогов
Считаю свою цель полностью выполненной: 2d pixel art игра на Unreal Engine. Это даже похоже на игру в каком-то смысле. Соответствует ли игра тематике конкурса? Считаю что да, а если не согласны — пишите в комментариях почему.
Большим аспектом всей разработки было изучение движка. На самом деле это не тот проект, через который я хотел изучить Unreal Engine. Да, у меня были планы на определенную игровую задумку — хотел сделать игру про Соника, а освещать процесс в своей группе ВК.
И моя хотелка приступить к освоению движка продолжалось достаточно долго, поэтому я решил — если не брать и не сделать сейчас, то, вероятно, и не сделаешь, вот и решил взять и сделать. Не игру по Сонику, а исследовать Unreal Engine. Глядишь — и будущий фан-проект выйдет куда лучше.
Возможно, интереснее было бы изучать движок с готовыми ресурсами, кодом, моделями, текстурами и прочим. В своё время GameMaker изучал по примерам игр и крохотным прототипам, пытался понять, как и что там работает.
С Unreal Engine решил пойти путём, который я провернул с Godot — есть задача, нужно гуглить и смотреть видео, чтобы было наглядно видно решение. Тем самым поработал и с ресурсами, и делал вещи с нуля, набрался опыта. Есть, конечно, то, что не смог освоить — физика и неправильно отображаемые цвета, что для пиксель арта очень критично.
Про контроль версий
Блюпринты и Git (системы контроля версий), откровенно говоря, это какая-то дичь — думаю попробовать потом использовать C++ в Unreal для сравнения. Дебаг этих спагетти тоже не самое приятное дело. Вообще, этот способ визуального программирования, его поддержка и дебаг отнимают очень много, так сказать, визуальных сил. Нужно не читать текст, а вглядываться в картинку и связи, что с одной стороны проще, а с другой более утомительно.
Конец
Что же можно ещё сказать, движок мне понравился, хотя, как я и предполагал, он во всех аспектах тяжелее. На нём, как мне показалось, проблемно быстро сделать прототип с нестандартным геймплеем, зато если нужен простой шутер от первого лица, то всё работает чуть ли не из коробки.
Доволен ли я своей игрой? Сложный вопрос. С одной стороны, мне нравится, что вновь с нулевыми знаниями разобрался в движке, но с другой, игра именно как ИГРА опять показала себя плохо. Я решил, что это последняя моя игра на конкурсы. На неопределенный срок. Только причина и следствие тут не те, о которых вы подумали. Остановить своё участие в конкурсах я подумал ещё в начале разработки этой игры, чтобы отдохнуть от дедлайнов.
Исходники этой игры на моём Бусти! А саму игру можно скачать через itch.io: https://darkdes.itch.io/move-and-unpack
Выражаю благодарность всем: сыгравшим, прочитавшим, оставившим отзывы. Особо хочу поблагодарить Dieberry(Умрика) за помощь в редактировании данной статьи! И конечно же благодарности сайту Гамин! И организатору конкурса Гаминатор 27 — Luca_Nia!
Всем спасибо за внимание!
Ссылки по Unreal Engine:
- Создание 2д платформера на Unreal Engine, 3.5 часа (Youtube)
- Настройка Pixel Perfect через материал (Youtube)
- Создание главного меню (Youtube, Docs)
- Физика. Тащить объект мышкой. (Youtube, Youtube,Youtube)
- Физика. Тащить объект. (Youtube,Youtube,Youtube)
- Физика. Толкать объект. (Youtube)
- Строительство, расстановка. (Youtube)
- Тайловые карты (Youtube)
- Персонаж из спрайтов (Youtube)
- Программный интерфейс интератива (Youtube)
- Камера как в Метроиде (Youtube)
- Изменение активной камеры (Youtube)
- Установка своего курсора (Форум, Youtube, Youtube)
- Задания, квесты, таблицы (Youtube, Youtube)
- Добавление шрифтов (Youtube)
- Сохранение и загрузка данных (Youtube, Статья)
- Анимация UI (Youtube)
- Конвенция имён в Unreal (Docs)
- Rich Text (Youtube)
Эту статью писал наверно неделю, не меньше.
- 04 мая 2024, 17:01
- 029
10 комментариев