![](https://habrastorage.org/getpro/habr/upload_files/edc/c26/1af/edcc261af3be5cb48b05cab2caf9a469.jpeg)
Весь цикл статей
Всем привет.
В этой части настроим анимацию движения во все стороны для персонажа.
Начнем с того что создадим Animation Blueprint для нашего персонажа.
Перейдем в папку Blueprints->Player и нажмем ПКМ. В появившемся меню выбираем Animation Blueprint:
![](https://habrastorage.org/getpro/habr/upload_files/305/4b6/69b/3054b669bc8e789037cf09ca1de9895c.png)
Дальше выбираем наш скелет и жмем OK:
![](https://habrastorage.org/getpro/habr/upload_files/048/397/d2c/048397d2c12134914582c53bd739171c.png)
Назовем созданный блюпринт ABP_Player:
![](https://habrastorage.org/getpro/habr/upload_files/b43/5c2/4a7/b435c24a7e24120958982d258aa843fd.png)
Отроем его и перейдем в AnimGraph:
![](https://habrastorage.org/getpro/habr/upload_files/5be/d96/188/5bed961888e8db70287c1d3c22ff7ecd.png)
Щелкнем ПКМ во Viewport и создадим новую State Machine:
![](https://habrastorage.org/getpro/habr/upload_files/4f2/dcb/9b8/4f2dcb9b879901703f8b9284e0c22d7c.png)
Назовем ее Locomotion. Здесь будут наша анимация передвижения.
![](https://habrastorage.org/getpro/habr/upload_files/60d/d73/ade/60dd73ade734f5c95f4aca3cec72377f.png)
Вернемся в папку Blueprints->Player и создадим там Blend Space:
![](https://habrastorage.org/getpro/habr/upload_files/033/adc/ba2/033adcba2f9ee2494892082ba58892e7.png)
Назовем его BS_Locomotion:
![](https://habrastorage.org/getpro/habr/upload_files/595/c9e/0a2/595c9e0a2e72439b3a6bd1a8d68449cf.png)
Откроем его и в Axis settings увидим что есть две оси - Horizontal и Vertical:
![](https://habrastorage.org/getpro/habr/upload_files/f9c/2b3/23b/f9c2b323be70b14a7fb5b7051870f321.png)
Развернем Horizontal и дадим ей имя Velocity, так как она будет отвечать за скорость. Maximum Axis Value установим на 600(стандартная скорость в Character Movement Component):
![](https://habrastorage.org/getpro/habr/upload_files/e73/269/a7d/e73269a7dbd721a0af805f22354cbe7e.png)
Теперь развернем Vertical и назовем ее Direction, она будет отвечать за угол между вектором скорости и Forward вектором актора. Т.е. будет показывать в какую сторону движется персонаж и проигрывать соответствующую анимацию. Минимальное значение будет -180, а максимально 180.
Number of Grid Divisions изменяем на 8:
![](https://habrastorage.org/getpro/habr/upload_files/733/503/dc2/733503dc2d8e4fa267f93d00f29f00db.png)
Теперь сетка выглядит следующим образом:
![](https://habrastorage.org/getpro/habr/upload_files/37a/6a3/42f/37a6a342fa5e4c5976eebe8862772467.png)
В Asset Browser находим анимацию Pistol_Idle:
![](https://habrastorage.org/getpro/habr/upload_files/4dd/31d/dd6/4dd31ddd6bd327f8f426df2062415fd1.png)
Переносим ее в то положение, когда Velocity и Direction равны 0:
![](https://habrastorage.org/getpro/habr/upload_files/076/500/740/076500740a369fe15c56471ef5f44185.png)
Теперь находим анимацию Pistol_WalkFwdLoop:
![](https://habrastorage.org/getpro/habr/upload_files/6ae/b23/074/6aeb23074d39fa522f62344731162a9c.png)
Переносим ее в то положение, когда Velocity = 150, а Direction = 0:
![](https://habrastorage.org/getpro/habr/upload_files/937/489/943/93748994346807aa4a6c60e9072e5382.png)
Дальше нам нужны анимации для движения персонажа влево под определенными углами:
![](https://habrastorage.org/getpro/habr/upload_files/691/665/d51/691665d516c5d1998716c011ada86e65.png)
Выставляем их когда Direction становится отрицательным(значит персонаж движется влево). Число в названии указывает на какое значение Direction нужно поставить эту анимацию.
Pistol_StrafeLeft45Loop - -45
Pistol_StrafeLeftLoop - -90
Pistol_StrafeLeft135Loop - -135
![](https://habrastorage.org/getpro/habr/upload_files/fe1/f3e/fa2/fe1f3efa2f9090c2497afac8c85ab71d.png)
Тоже самое проделываем с анимациям когда персонаж движется вправо:
![](https://habrastorage.org/getpro/habr/upload_files/506/962/52a/50696252adc3aedd2392a2df10acf04b.png)
Дальше находим анимацию Pistol_WalkBwdLoop и ставим ее когда Velocity = 150, а Direction = 180 и -180
В итоге получается что-то в таком виде:
![](https://habrastorage.org/getpro/habr/upload_files/54d/8e4/ae0/54d8e4ae03648685c0dcd8f6a448f705.png)
Тоже самое нужно проделать для анимации бега:
![](https://habrastorage.org/getpro/habr/upload_files/761/3ce/ffd/7613ceffd9d1ed51e7093439615e0600.png)
Все делается аналогично, только теперь устанавливаем на значение Velocity = 600.
Это будет что-то вроде самостоятельной работы).
Получается следующая картина:
![](https://habrastorage.org/getpro/habr/upload_files/638/f6a/892/638f6a8924b4b5b782f5de4cb863ab85.png)
Вернемся в ABP_Player. Дальше в Locomotion и перетаскиваем BS_Lomotion во Viewport:
![](https://habrastorage.org/getpro/habr/upload_files/15a/e1a/af2/15ae1aaf2015e392ce9525690fb95d54.png)
Соединяем его с Entry:
![](https://habrastorage.org/getpro/habr/upload_files/8e6/e4b/208/8e6e4b208e454fea55c2e8e392284af0.png)
Теперь заходим внутрь BS_Locomotion. Щелкаем ПКМ по Velocity и создаем из нее переменную(Promote to Variable):
![](https://habrastorage.org/getpro/habr/upload_files/672/839/65d/67283965d762b26bf80ac5bf4861d1a2.png)
Тоже самое проделываем с Direction:
![](https://habrastorage.org/getpro/habr/upload_files/d52/7ae/573/d527ae5733de0ef47be1b6b58367b4fe.png)
Вернемся в AnimGraph и соединим Locomotion с OutputPose:
![](https://habrastorage.org/getpro/habr/upload_files/81a/1b8/774/81a1b877494320731e1e1ca3e170b63c.png)
Перейдем в BP_SHCharacter и выделим компонент Skeletal Mesh:
![](https://habrastorage.org/getpro/habr/upload_files/2a1/394/6a2/2a13946a2812c91b2d4794a050c8f124.png)
В Details нужно установить наш анимационный блюпринт в Anim Class:
![](https://habrastorage.org/getpro/habr/upload_files/1cd/40b/05c/1cd40b05ce8c6003c2d8f5b99fbdeea2.png)
Теперь если запустить игру будет проигрывать анимация Idle, но анимации Walk и Run нет.
Чтобы они работали необходимо обновлять переменные Velocity(скорость) и Direction(направление).
Начнем с Velocity и сделаем это с помощью блюпринтов.
Перейдем в ABP_Player. Дальше в EventGraph:
![](https://habrastorage.org/getpro/habr/upload_files/b66/aad/7df/b66aad7dff39ac3136e9e378e9b9c36a.png)
Слева можно увидеть наши переменные Velocity и Direction:
![](https://habrastorage.org/getpro/habr/upload_files/19d/920/cd0/19d920cd0468ecbd3f63224aae22405d.png)
Перетащим Velocity во Viewport и выберем Set Velocity:
![](https://habrastorage.org/getpro/habr/upload_files/05f/6b0/ace/05f6b0ace643dca2ff699c22d9ac2884.png)
Функция Try Get Pawn Owner возвращает ссылку на владельца пешки, на нашего персонажа. У которого есть функция Get Velocity, находим ее:
![](https://habrastorage.org/getpro/habr/upload_files/390/ca9/a8d/390ca9a8ddfcb159673a9efa4bcbfa47.png)
Get Velocity возвращает Vector. Чтобы узнать значение скорости нам нужно узнать длину этого вектора с помощью функции Vector Length:
![](https://habrastorage.org/getpro/habr/upload_files/e10/526/84c/e1052684ccea47f6ec7b1685dfe9534f.png)
И теперь длину этого вектора соединяем с переменной Velocity:
![](https://habrastorage.org/getpro/habr/upload_files/bfd/486/5b5/bfd4865b50a3f49e3ce8f2044c54bbb9.png)
Если сейчас запустить игру, то начнут проигрываться анимации Walk и Run, но анимации при движении в бок нет.
Перейдем в редактор кода, а именно в заголовочный файл персонажа SHCharacter.h, чтобы это исправить.
В секции protected создадим новую функцию MoveDirection, она будет возвращать тип float(направление движения, если точнее угол между foward вектором и вектором скорости).
Также воспользуемся макросом UFUNCTION со спецификатором BlueprintCallable, чтобы мы воспользоваться этой функцией в блюпринтах.
![](https://habrastorage.org/getpro/habr/upload_files/417/1bf/aba/4171bfabad049eafddb50a6e539f34ad.png)
Теперь перейдем в SHCharacter.cpp и создадим тело функции MoveDirection:
![](https://habrastorage.org/getpro/habr/upload_files/1a2/311/5a7/1a23115a7192dfe430bb3698ee97273b.png)
Как я говорил выше - это функция будет возвращать угол между foward вектором и вектором скорости
Делать это нужно с нормализованными векторами, т.е. равными 1. Forward вектор по умолчанию нормализован, а вот вектор скорости необходимо нормализовать с помощью функции GetSafeNormal у GetVelocity:
![](https://habrastorage.org/getpro/habr/upload_files/03d/e9e/068/03de9e068beecc866b06f2da3091ebc2.png)
Теперь можно найти угол между нашими векторами c помощью скалярного произведения. Для этого у Vector есть функция, которая называется DotProduct.
DotProduct возвращается косинус угла между векторами, чтобы получить значение угла необходимо воспользоваться функцией арккосинуса(Acos), которая находится в библиотеке FMath.
![](https://habrastorage.org/getpro/habr/upload_files/1a9/015/f6f/1a9015f6f879d6a6173e36c5621242ac.png)
Сейчас угол между векторами всегда будет положительный, независимо от стороны движения. Нам нужно чтобы когда персонаж двигался влево угол был отрицательным, а при движении вправо, он был положительным.
Чтобы найти знак угла воспользуемся векторным произведение(CrossProduct):
![](https://habrastorage.org/getpro/habr/upload_files/e07/5fc/34a/e075fc34ac2e62db3f0ff95d0a6684d5.png)
Так как Acos возвращает угол в радианах, нам нужно преобразовать его в градусы с помощью функции RadiansToDegrees и сразу умножим градусы на знак векторного произведения(SignAngle) по оси Z:
![](https://habrastorage.org/getpro/habr/upload_files/75f/496/3e3/75f4963e3e86fb8ceb88de3a442380b8.png)
Осталось DegreesAngle передать в возвращаемое значение функции.
![](https://habrastorage.org/getpro/habr/upload_files/ae1/681/0c6/ae16810c64f13c93992ebfe188b5b62f.png)
Теперь вернемся в анимационный блюпринт ABP_Player и вызовем Event Blueprint Initialize Animation:
![](https://habrastorage.org/getpro/habr/upload_files/d16/d3b/17b/d16d3b17b3e1eda8fc4f044f9356eba9.png)
Дальше вызовем функцию Try Get Pawn Owner:
![](https://habrastorage.org/getpro/habr/upload_files/f43/99b/9e9/f4399b9e9815dbac68bbb3bce518eedc.png)
Чтобы с помощью Cast получить ссылка на нашего персонажа:
![](https://habrastorage.org/getpro/habr/upload_files/7aa/01e/f02/7aa01ef0254838dcc91a2a77d60d35a8.png)
Создадим переменную из возвращаемого значения Cast. Для этого необходимо щелкнуть ПКМ по As SHCharacter и потом по Promote to Variable:
![](https://habrastorage.org/getpro/habr/upload_files/644/13b/35e/64413b35ea52746ce1d8a84fe025633b.png)
Назовем переменную Player:
![](https://habrastorage.org/getpro/habr/upload_files/3a2/6fd/64b/3a26fd64b625e3153258b2b3bb0b257e.png)
После Velocity вызовем Set Direction(переменная, которую создали ранее):
![](https://habrastorage.org/getpro/habr/upload_files/64c/86c/df6/64c86cdf6a01e939786a73c97f585869.png)
Потом возьмем переменную Player и вызовем функцию MoveDirection, которую создавали в С++ классе, а возвращаемое значение соединим с Direction:
![](https://habrastorage.org/getpro/habr/upload_files/7da/5a5/d89/7da5a5d89f283cdd14fdbbeb621c9fa1.png)
И последнее что мы сделаем - это проверим с помощью функции IsValid, что Try Get Pawn Owner возвращает не пустой указатель на персонажа:
![](https://habrastorage.org/getpro/habr/upload_files/045/a8d/e4a/045a8de4a44ce4393dcecc721593e8e8.png)
Теперь если запустить игру и побегать персонажем в разные стороны, будут проигрываться соответствующие анимации.
Тоже самое только в видео:
Подпишись:
Discord - discord.gg/CqZTXY4zwG
VK - vk.com/vlakugames
Youtube - vk.cc/cchfQD
Rutube - https://rutube.ru/channel/23334940/