Third person Smooth Camera

Реализация плавной Third person камеры для Unreal Engine 4.

Всем привет! Начав работу над своим новым проектом, достаточно быстро обнаружилась потребность в улучшении работы стандартной Third Person камеры. К основным минусам которой можно отнести:

Резкая смена ракурса с ближнего на дальний в отсутствии коллизии у камеры

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

Отсутствие механизма для контроля Spring Arm положения

Камера всегда стремится в начальную координату Spring Arm при сокращении дистанции. В общем случае это приводит к влетанию камеры внутрь геометрии персонажа. В современных играх, например God of War, Uncharted 4 и т.д. при критическом расстоянии и отсутствии места для размещения камеры между стеной и персонажем, камера поднимается над головой персонажа. Т.о. не перекрывается ракурс и остаётся некоторая видимость ситуации для игрока.

Итак, основные две задачи которые нужно было решить:

- Камера должна плавно менять ракурс от ближнего на дальний

- Плавно подниматься над головой персонажа при сокращении дистанции

Посмотрев другие решения, в которых использовался Timeline для плавной интерполяции длинны Spring Arm и даже двойная камера, одна из которых использовалась как proxy, я пришел к выводу, что они по моему мнению, несколько избыточны или же выглядят не оптимально для использования в реальном проекте. Я решил упростить и сделать максимально простую быструю для переноса реализацию плавной камеры.

Моё решение состоит из нескольких моментов:

1) Проверка на столкновение камеры с геометрией. Реализовано с помощью SphereTraceByChannel. Начальной координатой служит центр капсулы персонажа. Конечной координатой - вектор направления камеры полученный из поворота контроллера помноженный на текущую длину Spring Arm:

Third person Smooth Camera

2) Если коллизия имеет место быть, то выбираем в качестве актуальной длины Spring Arm - длину между точкой столкновения и центром от капсулы персонажа.

Если камера ни с чем не сталкивается, то берём заданную длину для Spring Arm, которая используется для нормального игрового ракурса. В данном примере значение равно 300 и хранится в переменной InGameArmLenght.

Third person Smooth Camera

3) Полученное значение сглаживаем каждый кадр с помощью FinterpTo между текущим и целевым и сохраняем в переменную ResultArmLenght.

Текущее - то которое было на предыдущем кадре. Т.о. если на текущем кадре камера ни с чем не сталкивается, то целевое значение длины SpringArm станет равно 300, соотв. будет плавный откат камеры назад от текущего меньшего значения до 300.

Задача No. 1 решена.

Third person Smooth Camera

4) При помощи MapRange мы пересчитываем текущее значение длины Spring Arm в диапазон для смещения центра Spring Arm вверх. Диапазон имеет границы от стартового значения Z координаты для Spring Arm (заносится на старте в переменную InGameArmRelativeLocation) до значения половинчатой высоты капсулы, которое можно получить из самой капсулы.

Т.о. чем ближе камера к персонажу, тем она стремится выше подняться за счёт сдвига положения SpringArm по оси Z вверх.

Задача No. 2 решена.

Third person Smooth Camera

В самом минимальном приближении камера будет находиться над головой персонажа оставляя игроку актуальный ракурс для игровой ситуации:

Third person Smooth Camera

5) Блокировка полёта камеры из нижнего положения. Примерные углы для контроллера по pitch для нижнего ракурса камеры будут: 40...60 градусов.

Т.о. в данных углах и при наличии коллизии камеры с нижней поверхностью (полом) камера пролетает в геометрию персонажа, т.к. стремится поднять Spirng Arm по Z координате.

Чтобы решить это небольшое неудобство, достаточно добавить к текущей длине SpringArm (при наличии коллизии у камеры) дополнительное значение в зависимости от поворота контроллера при помощи ClampAngle в диапазоне от 0 до половинчатого значения размера капсулы по высоте.

Third person Smooth Camera

В результате смотреть снизу мы можем, но камера теперь не стремится пролететь в персонажа:

Third person Smooth Camera

Безусловно я не претендую на 100% правильность и единственность решения подобной задачи, тем не менее данная реализация вполне может послужить хорошей отправной точкой.

Проект доступен на моём GitHub в версии для Unreal Engine 4.23.

Всем хороших игр!

2222
3 комментария

Hold on brother. Что это за любовь к кастомным костылям, когда в базовом классе уже все придумали до нас (pic#1)?

И если хочется добавить приятный бонус в виде смещения при близких коллизиях, то pic#2 

3
Ответить

Camera lag не про это. Socket не трогается, т.к. на положение сокета завязан Aim режим. 

Ответить

Пасиба. Будет полезно когда руки дойдут ;c

1
Ответить