Создание проекта на Unreal Engine 4

Часть 1

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

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

Решил начать с перемещения и анимации состояний. Unreal Engine 4 предоставляет при создании проекта шаблоны разных жанров, выбрал шаблон жанра игры от третьего лица. В шаблоне есть базовое перемещение игрока, что облегчает работу. Изменил некоторые настройки для персонажа. И получил следующий результат:

​Стандартное перемещение с незначительными изменениями Somied Nagrom

Основные изменения заключаются в скорости разгона, в силе притяжения и скорости бега. Для прототипа, данных изменений будет достаточно. После этого изменил структуру папок в проекте и расположения окон, это было сделано для собственного удобства. Создал новую карту специально для тестирования прототипов. При помощи плагина Prefabricator перенёс стандартный свет, визуальные эффекты, туман и т.п. Создал простенькую карту из стандартных мешей, накинул на них стандартные материалы и добавил свет. И получил результат:

​Простенькая карта для прототипа Somied Nagrom
​Простенькая карта для прототипа Somied Nagrom

Поставил стартовую точку для появления персонажа, там где нужно мне, а не там где находится камера. Решил, что начальная подготовка окончена.

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

Написал пробный вариант для решения задачи и создал простенькие тестовые анимации для наглядного результата. Сейчас некоторую часть разработки разберу здесь. Логику решил писать в Anim Blueprint’е игрока. Возникали сомнения по поводу этого решения, но потратив некоторое время согласился с собой, что это можно сейчас упустить. Для начала создал булевую переменную, которая отвечает за то бездействует ли игрок или же напротив. Это позволит нам заставить персонажа перейти к случайным анимация бездействия или же напротив, вернуться к обычному стандартному состоянию покая\бездействия. Далее, создал переменную с плавающей точкой, которая работает как таймер, в котором после окончания заданного времени мы понимаем что игрок бездействует. Следующая переменная является целочисленной и ей случайным образом присваивается число, которое означает номер проигроваемой анимации.

Теперь к разбору screenshot’ов.

​Переход к событию которое вызывается каждый кадр Somied Nagrom
​Переход к событию которое вызывается каждый кадр Somied Nagrom

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

<p>В зависимости от результата булевой переменной будет развиваться исход действий</p> Somied Nagrom

В зависимости от результата булевой переменной будет развиваться исход действий

Somied Nagrom

Если персонаж не двигается, то единожды вызывается таймер. После окончания заданого времени вызывается пользовательское событие.

​Пользовательское событие бездействия персонажа Somied Nagrom
​Пользовательское событие бездействия персонажа Somied Nagrom

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

<p>Пользовательское событие для сообщения того что персонаж не стоит на месте</p> Somied Nagrom

Пользовательское событие для сообщения того что персонаж не стоит на месте

Somied Nagrom

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

Еле-еле отказался от того чтобы сесть и привести этот визуальный код в читаемый, приятный глазу вид. Там можно и нужно его оптимизировать — это хорошая привычка. Решив, что ещё смогу позже уделить этому время, перешёл к AnimGraph’у и начал настраивать переходы и условия для анимаций.

AnimGraph для персонажа Somied Nagrom
AnimGraph для персонажа Somied Nagrom

Было решено, чтобы перейти к случайной анимации нужны были два условия. Первое, чтобы булевая переменная отвечающая за то бездействует ли игрок или нет, была правдой. Второе, чтобы совпали значения с переменной в которой лежит случайное число от 0 до 2 с номером анимации. После того, как эти условия соблюдены анимации будут циклические в одной последовательности проигрываться. И как только игрок двигается мы переходим в состояние смешанной анимации. Следующим образом выглядят условия перехода к случайным анимациям.

​Условие перехода к случайным анимациям Somied Nagrom
​Условие перехода к случайным анимациям Somied Nagrom

А таким образом выглядит условия возвращение к смешанной анимации.

<p>Условие возвращения к стандартной анимации покоя\бездействия</p> Somied Nagrom

Условие возвращения к стандартной анимации покоя\бездействия

Somied Nagrom

Переходы между случайными анимации происходят автоматически благодаря Unreal Engine 4 и активированной булевой переменной.

​Активация автоматического перехода между анимациями Somied Nagrom
​Активация автоматического перехода между анимациями Somied Nagrom

Получились следующие результаты проделанной работы:

​Первые результаты Somied Nagrom

Выглядит это пугающе, но махнул рукой на моё неумение создавать качественные анимации. Маленький прототип готов. Следующим шагом является импорт анимаций с Mixamo без использования Root Motion и присвоение их манекену.

Закончив импорт с Mixamo начал заменять в AnimGraph’е анимации и появилась идея, чтобы между этими случайными анимациями была промежуточная. Первая же идея была сделать напрямую, например, есть какая-то анимация, позавершению её перейти в анимацию отдыха, далее, следующая анимация и опять отдых и т.д. Но мне хотелось меньше таких поступков делать и я решил, что будет всего одна анимация отдыха между остальными случайными. Чтобы зайти в анимацию отдыха используем автоматический переход, а вот для выхода из анимации отдыха в случайную анимацию, было создано специальный Enum. Как мне показалось, это хороший вариант для того чтобы в будущем было легче расширять этот функционал. Теперь AnimGraph имел следующий вид:

​Обновленный AnimGraph Somied Nagrom
​Обновленный AnimGraph Somied Nagrom

Условия перехода также изменились:

​Условия для перехода в анимацию грустного бездействия Somied Nagrom
​Условия для перехода в анимацию грустного бездействия Somied Nagrom

Добавил в Animation Blueprint функцию в которой берётся случайное число из диапазона и в зависимости от результата присваиваю собственному Enum’у нужную анимацию.

​Функция установки случайной анимации Somied Nagrom
​Функция установки случайной анимации Somied Nagrom

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

Полученный результат
11
Начать дискуссию