Создание настоящего вида от первого лица в Unreal Engine 4

С анимированным телом персонажа.

Технический художник Фабрик Пике (Fabrice Piquet) из компании Allegorithmic в блоге на сайте Gamasutra рассказал, как в Unreal Engine 4 создать «настоящий» вид от первого лица, при котором камера двигается в соответствии с движением головы персонажа. Мы выбрали главное из материала.

Создание настоящего вида от первого лица в Unreal Engine 4

«Настоящий вид от первого лица» предполагает, что камера «закреплена» на анимированном теле персонажа, в отличие от простой «летающей» камеры. Такой подход использовался, например, в The Chronicles of Riddick, Syndicate и Mirror’s Edge.

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

Создание настоящего вида от первого лица в Unreal Engine 4

Порой, меши тела видны только игрокам, а полная версия туловища используется для того, чтобы отрисовывать тени (она видна также другим игрокам в мультиплеере, как в последних Call of Duty). Это помогает оптимизации, однако вредит погружению.

Меш полного тела (Full-body Mesh) предполагает, что весь персонаж будет состоять всего из одного меша. При этом камера присоединена к его голове. Её позиция или вращение диктуется движениями тела, их не нужно настраивать вручную. Иерархия класса выглядит так.

Создание настоящего вида от первого лица в Unreal Engine 4

PlayerContorller всегда находится выше Character (или Pawn) в Unreal, поэтому тут ничего нового. У персонажа есть меш тела, у которого имеется AnimBlueprint для управления анимациями. Наконец, камера, которая присоединена к мешу в конструкторе. Однако это не всё.

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

Создание настоящего вида от первого лица в Unreal Engine 4

Я использовал 10 анимаций, но вы можете сделать и больше, если вам, например, хочется, чтобы персонаж смотрел назад. В моём случае вместе с поворотом головы, поворачивается и тело (как в Mirror’s Edge). Это потребовало создание дополнительных анимаций.

Как только анимации импортированы в Unreal, нужно настроить несколько вещей. Убедитесь, что базовая поза для анимаций названа правильно, чтобы быстро найти её, когда потребуется. Я назвал её «anim_idle_additive_base».

Затем, я открыл другие позы и изменил несколько свойств во вкладке «Additive Settings». Параметр «Additive Anim Type» я установил на «Mesh space», а «Base Pose Type» — на «Selected Animation». Наконец, я загрузил мою анимацию базовой позы в слот ассетов. Все эти действия надо повторить для каждой позы.

Создание настоящего вида от первого лица в Unreal Engine 4

Теперь, когда анимации готовы, нужно создать Aim Offset — ассет, который хранит связи между несколькими анимациями и позволяет переключаться между ними в зависимости от введенных параметров. Полученное добавляется поверх существующей анимации (вроде бега, ходьбы и так далее).

Мой Aim Offset учитывает два параметра ввода: Pitch и Yaw. Эти значения управляются обновлениями игрового кода.

Создание настоящего вида от первого лица в Unreal Engine 4
Создание настоящего вида от первого лица в Unreal Engine 4

Обновление анимации

Чтобы анимация обновлялась, вам надо перевести данные, которые вводит игрок, в значения, понятные для Aim Offset. Это делается в три шага:

  • конвертация ввода в значение вращения в классе PlayerController;
  • конвертация вращения, основанного на мире, в локальное значение в классе Character;
  • обновление AnimBlueprint на основе значения локального вращения.

Шаг первый: ввод PlayerController

Когда игрок двигает мышку или стики на геймпаде, я учитываю ввод в классе PlayerController и обновляю вращение контроллера, переписывая функцию UpdateRotation().

Создание настоящего вида от первого лица в Unreal Engine 4

Шаг 2: локальное вращение камеры

У моего класса Character есть функция, которая называется «PreUpdateCamera()». Она делает следующее.

Создание настоящего вида от первого лица в Unreal Engine 4

Функции CameraProcessYaw() и CameraProcessPitch() конвертируют вращение контроллера в значения локального вращения. Функции выглядят следующим образом.

Создание настоящего вида от первого лица в Unreal Engine 4

Шаг третий: обновление AnimBlueprint

Последний шаг самый простой. Я получаю переменную локального вращения и передаю её AnimBlueprint, имеющей Aim Offset.

Создание настоящего вида от первого лица в Unreal Engine 4
Создание настоящего вида от первого лица в Unreal Engine 4

Как избежать лага

Если вы следуете этому гайду и не знакомы с тем, как работает функция Tick() в Unreal Engine, то вы рискуете столкнуться с особенной проблемой — задержкой на один кадр. Это создаёт определённый дискомфорт во время игры.

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

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

Создание настоящего вида от первого лица в Unreal Engine 4

Можно заметить, что класс Character обновляется после AnimInstance (это AnimBlueprint). Это значит, что локальное вращение камеры будет обсчитываться только на следующем тике, поэтому AnimBlueprint использует старые значения. Чтобы решить эту проблему, я расположил функцию «PreUpdateCamera()» в конце тика PlayerController. Таким образом, система получает свежие данные о вращении до обновления меша и его анимации.

Воспроизведение анимаций

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

В моём случае, я хотел проиграть анимацию подъема через некоторое время после падения.

Этот код относительно прост.

Создание настоящего вида от первого лица в Unreal Engine 4

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

Не совсем то, что хотел. Слот анимации находится до узла Aim Offset в AnimBlueprint. Поэтому, если вы смотрите вниз, перед тем, как проигрывается анимация, значение вращения удваивается из-за чего персонаж становится в странную позу и смотрит себе между ног.

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

Создание настоящего вида от первого лица в Unreal Engine 4

Эти строки обсчитываются в начале функции, до расчёта локального вращения камеры из PlayerControll. Они просто сбрасывают pitch на 0 с помощью функции «RInterpConstantTo()». Результат выглядит так.

7373
31 комментарий

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

27

Классовая иерархияУсыпите своего внутреннего Маркса, это всего лишь иерархия класса.

36

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

15

Оно просто вот так копируется, да и в целом, здешний редактор для кода не предназначен.

3

Нам тут еще уроков по Юнити не хватало!

(шучу, у меня просто личная неприязнь к юнити)

6

Если б не Unity, то многих отличных игр могло бы потенциально и не быть.

2

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

1