Первый опыт и впечатления от Unreal Engine 4
Evening, lads! Под конец года я хочу вам вкратце рассказать о своём начальном опыте познания троп Unreal Engine 4, его инструментария, и о том, чему можно самостоятельно и спокойно научиться делать в нём за три месяца.
Начну сразу с демонстрации:
Для контекста
Сразу уточню – я всё делал на Blueprints и к написанию кода на Си не прикасался. У меня уже есть опыт как в разработке игр (участвовал в трёх проектах на Unity), так и двух лет программирования на С++, но в этом учебном проекте решил сосредоточиться на изучении частично или полностью нового – в создании игровых механик (ранее в играх в основном занимался ИИ), в инструментарии (движок и аспекты игры); и иной вид программирования (графический BP, вместо классического кодинга).
Также, до начала работы у меня уже было видение и концепции игры (роуглайк FPS с упором на динамичные бои, передвижение и скиллы), которая может из этого прототипа вырасти, и механик, которые я хотел создать – их было на полноценные полторы-две игры, так что пришлось выбирать и сосредоточиться лишь на главных (так, например, совершенно не заморачивался с перезарядкой стволов).
Какие темы в итоге затронул:
- Использование проекта-шаблона (FPS шутер) и его настройки, а также готовых ассетов (материалы, модели, анимации);
- Inputs (клавиши управления и действий);
- Базовый ИИ – его настройка, навигация и поведение;
- Программирование актёров, их компонентов и их динамичное изменение;
- Создание актёров-снарядов (Projectile) и их взаимодействие;
- Программирование уровня и “game mode”;
- Функционал взаимодействия игрока и интерактивных объектов;
- Создание и программирование HUD и виджетов;
- Создание материалов, использование их экземпляров и работа с координатами;
- Использование многослойных (Layered) материалов;
- Система частиц (Cascade);
- Создание статичных мешей с помощью Geometry brush;
- Основы работы с освещением;
- Настройки импорта в UE изображений (текстур);
- Особенности ООП в Blueprints UE4;
- Рабата со структурами, таблицами и перечислениями;
- Изменение параметров материалов и систем частиц с помощью кода.
Теперь уже перейду к тому, что конкретно сделал.
По контроллеру игрока, шаблону и что не трогал
Для базы своего проекта я использовать шаблон ‘FPS Shooter’ входящий в UE4 и должен сказать, что был приятно удивлён качеством контроллера персонажа игрока и глубиной его настройки. Например, ещё до начала работы я знал, что хочу сделать функционал двойного и более прыжков – и хотя в итоге мною было это реализовано, но это оказалось ненужным, так как в шаблоне уже был параметр с количеством этих самых прыжков, а также возможность настройки перемещения в воздухе и его силы, скорости торможения, силы эффекта гравитации (не путать с весом актёра) и так далее.
Но что добавил в передвижение игрока, так это рывки – о них напишу отдельно.Кроме этого, добавил в проект готовые базовые ассеты (материалы, меши) и шаблон ‘3dr Person Shooter’ (нужен был готовый актёр-манекен для врагов).
Geometry brush и его карты
Довольно любопытный инструмент для создания простой геометрии, отличный вариант для построения временного игрового уровня. Я опробовал все основные функции, сделал несколько статичных мешей, в том числе для ”сундука”. Однако, для создания чего-то более серьёзного, вроде мешей оружия, он уже не так хорошо подходит, например, в нём не хватает возможности глубокой настройки UV карты (только позиция, масштабирование и “перспективная стыковка”, которая делает то, что вы хотите только при создании элемента уровня). Так пробовал создать полый цилиндр – с геометрией никаких проблем не было, а вот нормально настроить эту самую карту (да, только одну) возможности нет.
Система частиц
Теперь перехожу уже к более интересным и объёмным темам. Система частиц, материалы и “data staff” – это то, что я активно использовал во многих частях проекта. Например, частицы у меня используются в:
- Эффектах у закрытых сундуков;
- Эффектах при использовании скиллов (в частности – взрывов);
Как уже писал, я использовал старую (но ещё актуальную) встроенную систему Cascade, к которой у меня почти не было претензий или желания большего. Она достаточно понятная и функциональная, особенно благодаря многослойности (разные эффекты в одной системе), взаимодействию с материалами через специальные входные данные, возможности изменения параметров через код или кривые.
Материалы и текстуры
Самое большое количество времени в этом проекте мною было потрачено на визуальный кодинг, второе – материалы. Впервые занимаюсь ими и был очень приятно удивлён функционалу, понятности (большинства) и тому, что ты можешь сделать с их помощью – от простого наложения текстуры с настройкой цвета или контрастности до полноценного изменения геометрии и симуляции жидкостей (эти два я, правда, не пробовал, но когда-нибудь!), при этом ещё и с возможностью делать это разными слоями (имею в виду систему Layered Matereals, про неё будет дальше).
Конечно, не все материалы, что мною были сделаны, основаны на генерации - я создал некоторые текстуры и иконки (созданные в PS изображения с разными настройками импорта):
А также несколько “кистей” для UI виджетов (brushes; большинство, правда, в итоге так и не использовал):
Отдельно хочу отметить систему многослойных материалов, так как работа с ними отличается от обычных, например, вместо одного ассета-материала, используются:
- Layered Material – материал конкретного слоя или фона (Background);
- Material Layer Blend – отвечает за формат наложения/слияния слоя, где он выбран с предыдущим слоем или фоном;
- Материал-база, в котором присутствует компонент для использования этой системы и включает в себя базовые настройки.
Кроме этого отличается и синтаксис для динамичного изменения параметров этих материалов, документации и примеров чего я почти не нашёл, так что пришлось разбираться самостоятельно.
В итоге с помощью материалов сделал:
- Простой материал с настройкой основных атрибутов;
- Динамичную (прокрутка по X и/или Y текстурной коор.) текстуру для снарядов (с возможностью настройки цвета, скорости прокрутки и эффектом Fresnel);
- Текстуры для систем частиц (их необходимо делать через материалы из-за того, что их цвет идёт как input значение);
- Динамичную текстуру для отображения 3D эффекта при использовании рывка игроком;
- Многослойный материал с отображение 2D иконки как один слой и добавочным визуальным эффектом (использовал почти тот же самый, что и для эффекта рывка) как второй на меше-плоскости в 3D пространстве;
- Материал для эффекта “обводки” объекта в постобработке (выбор врагов при использовании направленных умений);
- Материал для “наклеек” (Decals, на которые действуют эффекты FadeIn и FadeOut) с параметрами 2D текстуры и наложения цвета.
Записи, информация или data-staff
Тут речь пойдёт об одной из самых скучных частей разработки (не такой как тестирование и исправление багов, но всё же) – организации данных, а конкретно о структурах и их использовании в информационных таблицах и проекте. Кто не в курсе: структура данных – это пользовательский набор данных (которые могут быть различного формата, например, в одной структуре использовать такие данные как число, строка, ссылка на актёра и 2d текстуру), который можно использовать в качестве переменной или в таблице для записи данных.
Но зачем это всё нужно в моём небольшом проекте? Как уже писал, даже если в итоге он не разрастется в полноценную игру, то я хотя бы получу дополнительный опыт для работы с оными и больше пойму возможности масштабирования.
Итак, мною были созданы структуры с информацией о:
Оружии (с таблицей) – название, ссылка на класс, иконка, изначальная скорострельность (задержка между выстрелами), количество амуниции (выстрелов);
Способностях (с таблицей) – название, ссылка на класс, описание, иконка, изначальное время перезарядки, количество зарядов;
- Виде статус эффектах – название, описание, иконка;
- Статус эффектах (с таблицей) – вид статуса эффекта (исп. предыдущая структура), продолжительность тика (одного заряда), количество тиков;
Цветах (с таблицей, для использования как единой цветовой палитры) – название (типа enumeration – выбор одного из созданного перечисления) и линейный цвет, вот так просто.
Кроме этого я создал несколько объектов-интерфейсов для большего удобства работы с переменными записями и наборами (например, геймплейных тегов).
NPC-враги
Как уже писал, у меня уже есть опыт работы с созданием модели поведения NPC и системы их взаимодействия, однако ранее это делал на чистом коде (за исключением системы навигации – что тогда, что сейчас я использую предоставляемую движком), на этот же раз - использовал готовые инструменты и системы, что предоставляет Unreal: Behaviour Tree, Blackboard, AI Controller и AI Perception, а также встроенную навигационную систему.
Работать и объединять работу (через Blueprint классы) со всеми этими компонентами было удобно, быстро и довольно понятно, по крайне мере на том уровне, который был мною выбран.
За основу персонажей врагов взял готовый “манекен” для контроллера игрока от третьего лица (готовая модель с анимациями) и класс актёра “Character controller” со своими компонентами (капсулой для коллизии, компонент навигации персонажа с настройками проходимости, скорости движения и прочим). Для полноценного функционирования и для возможности будущего масштабирования пришлось также использовать дополнительный компоненты и классы:
Behavior Tree (далее BT) – “дерево поведения” или “дерево выбора”, компонент для удобной работы с поведением врага в виде последовательных графов (имеют иную структуру и вид, нежели кодинг на Blueprints);
Blackboard – связанный напрямую с BT компонент, в котором хранятся переменные для использования в нём;
AI Controller – базовый компонент для настройки и прописывания логики относящихся к “чувствам” (в данном случае задействовано только зрение для поиска игрока), а также присвоения значения Blackboard переменным;
- Несколько BT Task – небольшие задачи со своей логикой, которые можно использовать в BT;
Interface – для обозначения (лишь обозначения, сама логика описывается в каждом конкретном классе отдельно) типовых для врагов функций (вроде получения урона, призыва атаковать, проверки готовности для деспавна), к которым будет простой доступ из других классов;
- и наконец, отдельный класс снаряда (Projectile, о них будет идти речь позже) для возможности атаки по игроку.
Итак, вот какую логику и действия я прописал врагу:
“Патрулирование” – нахождение случайной допустимой для подхода точки в небольшом от актёра-врага радиусе, доход до неё, небольшое ожидание и повторение;
“Визуальное обнаружение и преследование игрока” – обнаружение игрока в поле зрения (настраиваемое виртуальное “чувство” в AI Controller) или после получения урона от него, и его преследование, пока тот не выйдет за пределы зрения, после чего возврат к патрулированию;
“Атака игрока” – суть думаю ясна, враги стреляют в игрока с заданным промежутком, когда преследуют его. Так же сделал для этого действия специальный визуальный эффект;
У врагов есть здоровье и при попадании игроком по нему (снарядами или способностями, что наносят урон) оно уменьшается, опустится до нуля - он перестаёт двигаться или атаковать, включается ragdoll и через пару секунд он уничтожается;
В видео этого не было, но я для тестов сделал функционал респавна - когда враг умирает или падает за пределы уровня, то он вновь появляется в своей начальной позиции (реализовано в коде уровня).
Оружие и снаряды
Итак, раз шутер, то игрок должен из чего-то и чем-то стрелять, и вот как я поступил с этой задачей.
Сначала создал базовый класс снаряда, который представляет из себя:
- Сфера коллизии снаряда;
- Основную модуль/меш для снаряда;
- Модель/меш для трассы (след полёта снаряда)
Систему частиц для той же трассы (может использоваться как и с мешем, так и отдельно);
Компонент Projectile Movement, который является ключевым при работе со снарядами в Unreal и в котором и происходит настройка его поведения;
Также в этом классе есть ссылка на систему частиц, что проигрывается при попадании в объект.
Логики же снаряда, как таковой, особой и нет, прописал только разное визуальное изменение, когда он попадает по врагу, а когда по элементам игрового уровня. Также был сделан схожий класс (но не наследственный) для вражеских снарядов.
После этого создал несколько дочерних классов, которые разнятся лишь визуальными составляющими и скоростью снаряда – их то я и использовал при стрельбе оружия. Само же оружие вышло ещё проще по количеству компонентов (лишь модель оружия и пустой компонент для места создания снарядов), но вся суть была в создании логики, а именно:
Переменные-параметры с указанием класса снаряда, записи в таблице с данными об оружии, разброса стрельбы и прочие;
- Функция основной стрельбы (работает как для одного, так и нескольких снарядов, а также может быть изменена для каждого отдельного оружия) – появление определенного количества снарядов в направлении стрельбы со случайным разбросом в заданных пределах;
- Функции для работы (обмена) с данными и отображению на интерфейсе.
· Переменные-параметры с указанием класса снаряда, записи в таблице с данными об оружии, разброса стрельбы и прочие;
· Функция основной стрельбы (работает как для одного, так и нескольких снарядов, а также может быть изменена для каждого отдельного оружия) – появление определенного количества снарядов в направлении стрельбы со случайным разбросом в заданных пределах;
· Функции для работы (обмена) с данными и отображению на интерфейсе.
Остальная же логика, связанная с оружием прописана уже в классе актёра игрока.
Система скиллов
Пожалуй, та часть проекта, над которой работал больше всего, и не удивительно, учитывая ту вариативность, что я хотел достичь. Так, мною было реализовано несколько видов (именно видов, а не отдельных экземпляров) способностей:
Снаряды – схожи по своей структуре со снарядами оружия, но имеют более сложную логику столкновения (нанесение урона и/или накладывание эффектов на врагов в радиусе), которая прописывается для каждой способности отдельно (пример - граната);
Направленные – для их применения необходимо выбрать цель, на которую будет наложен эффект этой способности. Выбор цели я реализовал так – сначала нажимается кнопка способности, после чего игрок наводит прицел на нужного врага (он “подсвечивается” на уровне пост-процесса) и нажимает повторно кнопку активации способности, либо нажимает ПКМ для отмены выбора;
Усиление (Бафф) – просто накладывает положительный статус эффект на персонажа игрока.
Немного подробней расскажу про статус-эффекты – у персонажа игрока и каждого врага есть массив переменных, этих самых статус эффектов. Каждый из них имеет значение продолжительности одного тика, количество этих тиков и что за эффект применяется за него. Например, эффект оглушения имеет один тик и при его окончании враг может вновь выполнять действия, а отравления – несколько и по истечении каждого наносится урон.
Игрок может иметь в своём распоряжении несколько способностей, каждая из которых может иметь один или несколько зарядов с определённой длительностью перезарядки.
Интерфейс
Реализовал только самое необходимое:
- Статичный прицел;
Отображение оставшегося HP в числах в углу экрана и в виде полоски около прицела;
- Тоже самое для оставшейся амуниции текущего оружия;
Отображение иконок оружия, которое есть у игрока и выделение того, что сейчас у него в руках;
Отображение оставшихся рывков под прицелом (масштабируется в зависимости от их количества);
Сегмент с отображением способностей игрока (они изменяют свой вид, когда те уходят на перезарядку и подсвечиваются во время выбора цели целенаправленными);
Всплывающее окно для выбора новой способности или оружия из сундуков;
- Выноска с информацией об оружие или способности, которая появляется при выборе.
Сундуки и дропы
Новое оружие и способности игрока должны откуда-то у него появляться, так что было решено использовать обычную систему сундуков – игрок подходит к ним, взаимодействует и ему на выбор предоставляются случайные три способности или два ствола. Если у игрока есть свободный слот, то он может просто добавить выбранное в сундуке в него, если нет – нажимает правую или левую кнопку мыши для замены того, что уже есть.
Кроме того, сделал систему дропов: из врагов после смерти выпадают “пирамидки”, к котором игрок может подойти и что-то себе восстановить, в зависимости от вида – либо здоровье, либо амуницию (для текущего оружия). Вид зависит от того, каким способом был нанесён смертельный удар врагу : HP (зелёная) - если просто оружием, патроны (фиолетовая) - если способностью. Визуально же они отличаются как цветом, так и плавающей иконкой над ними. Кстати, для визуальной части отображения иконки над дропом я тоже использовал многослойный материал (один слой – визуальные эффекты, второй – изображение).
Рывок
Суть проста - нажимая Shift персонаж игрока совершает дэш в ту сторону, что он двигается, а если же игрок никуда не двигается, то работает как прыжок. При этом сбрасывается ускорение игрока (в каком бы направлении оно ни было) и во время действия рывка на него не действует гравитация.
Куда больше времени было потрачено на визуальную реализацию, чем на сам функционал – я решил сделать схожий с классическими “action lines”, которые часто используют в играх при ускорении или тех же рывках, но чтоб они были по направлению движения (во всех, кроме вниз). В итоге пришлось повозиться с материалом и UV картами цилиндра, но получилось неплохо.
Итог
Хоть суммарно мною было потрачено не очень много времени, считаю, что реализовал неплохую базу как для будущего развития в полноценный проект, так и личных навыков работы с теперь не столь новым для себя игровым движком. Работать в Unreal Мне понравилось(в отличии от написания этой статьи) и думаю вот почему:
Интерфейс лаконичный (особенно по сравнению с Unity) и понятный;
Функционал мощный (за исключением некоторых инструментов, вроде Geometry brush), но в то же время гибкий;
Работа с графами в Blueprints и материалах очень приятная и визуально понятная, куда интересней чем работа с голым кодом;
Хотя у меня не самое типовое железо, но технических проблем почти не было (только несколько крашей из-за бага, что в новых версиях уже исправили);
Количество и простота использования визуального инструментария (не удивительно, Unreal же): обычные и многослойные материалы, пост-процесс обработка, создание простой геометрии, виджеты интерфейса и прочие;
Удобство и структурирование работы между различными составляющими отдельно взятого актёра и между несколькими, взаимодействия с виджетами интерфейса, программной логикой уровня или всей игры;
Множество “quality of life” фишек в основных сферах использования.
Но осталось ещё много совершенно не затронутых мною тем и инструментов – сеть и мультиплеер, работа с освещением, анимации, катсцены и несколько камер, пост-процесс (затронул всего для одного эффекта), система визуальных эффектов Niagara, а про изучение UE5 и вовсе молчу. В этой статье прошёлся по всему кратко, некоторые узкие моменты и вовсе не затронул, так что, если есть вопросы по реализации чего-либо или просто какие-то по делу – задавайте!
Спасибо за внимание и с наступающим!
P.S. Ищу работу
Комментарий недоступен
Один движок по факту. Проблемма в том что если нет как минимум 20хх серии видеокарт, все отличие уе5 от уе4 будет по сути в "тёмной/теме"
Тоже понимаю, что звучит так себе 😅
Но на то есть серьёзные причины: материалов, уроков и форумных тем по нему огромное количество; в отечественном сегменте не так много компаний и с четвёркой то работают, с пятой - и вовсе единицы (всё-таки изучаю его в том числе и для трудоустройства, да и не когда-то через года два, а сейчас). К тому же, на сколько я видел, они основным инструментарием не так сильном отличаются, а вот копаться и разбираться во всяких тонкостях - я бы просто тратил время зря.
Комментарий недоступен
По материалам и техарту - мне очень нравятся видео этого чела:
https://www.youtube.com/c/TechArtAid
Там на примере создания конкретного материала или эффекта довольно глубокие нюансы и приёмчики рассматриваются.
На этот канал не натыкался, но выглядит интересно, спасибо что поделился!
Пожалуй, также стоит отметить, что это моя первая публикация на DTF (как и первое написание статьи в принципе) и, должен признать, был приятно удивлён удобством работы с сайтом при её создании 👀