Unity3D – Camera Shake. Как сделать подвижную камеру, чтобы улучшить отдачу от вашей игры
Доброго времени суток. Представлюсь, для тех, кто меня не знает. Меня зовут Дима. Я работаю C++ разработчиком уже более 5-ти лет. На данный момент работаю в крупной Gamedev-студии, предыдущее место работы: SK hynix memory solutions Eastern Europe. Помимо работы увлекаюсь созданием образовательного контента для YouTube и Twitch каналов.
Сложно подобрать аналог данного понятия в русском языке, чтобы он не звучал странно. Тем не менее, в данной статье речь пойдёт о вибрации камеры(Camera Shake) в играх и её реализации на движке Unity.
В процессе подготовки к написанию статьи и записи видео, я натыкался на несколько видео-уроков, которые демонстрировали весьма корявую реализацию данного функционала лишь для того, чтобы в конце прорекламировать Вам какой-то ассет, который всё сделает за Вас. В связи с этим я решил написать решение, которое будет законченным и пригодным для применения в Ваших продуктах.
Зачем нужны подобные эффекты? Чтобы лучше передать ощущение от игры, чтобы игрок чувствовал большее погружение. Особенно важно это делать в PC-играх, где отсутствуют возможности тактильно сообщать игроку о полученном уроне через вибрацию геймпада.
Сравним взрывы в разных компьютерных играх и то, как они ощущаются без вибрации камеры:
И с ней:
Особенно хорошо ощущается разница передачи, если нет звука: в первом случае больше похоже на лопнувшую банку оранжевой краски, нежели на взрыв робота. Во втором случае же однозначно чувствуется, что произошёл взрыв космического корабля страшной силы. Хотя не могу не признать, что тряска чересчур уж сильная.
Приведённые выше примеры касаются только вибрации камеры. Есть и другие эффекты. Рассмотрим еще один эффект. Это направленное вращение камеры, имитирующее удар. С помощью этого эффекта можно отлично передать сильную отдачу оружия, полученный от оружия урон, либо же в целом сделать более живыми и правдоподобными анимации персонажа:
Думаю, вступлений достаточно, перейдём к реализации. За основу взят небольшой проект, в котором я на стримах реализую геймплейные механики из игры Doom Eternal на движке Unity.
Вибрация Камеры
Вся суть вибрации камеры заключается в том, чтобы заставить камеру вибрировать на протяжении определённого промежутка времени, с определённой силой, то есть смещением относительно исходной позиции камеры, и в резкостью(плавностью) данной вибрации. По сути на протяжении отрезка времени мы будем генерировать очередную позицию камеры, смещать её в данную точку, по завершению вибрации следует вернуть камеру в исходную позицию.
Рассмотрим код функций:
Главной прелестью данного решения является генерация очередной позиции с помощью шума Перлина. По сути мы генерируем две координаты на текстуре шума и двигаемся от данных координат в сторону нуля. Параметр noize регулирует длину данных координат, то есть векторов:
Преимущество использования функции Mathf.PerlinNoise, в отличие от обычной генерации случайных чисел, состоит в том, что близкие друг к другу координаты дадут близкие результаты и дельты получатся плавными.
Вращение камеры
Существует множество различных способов реализовать вращение. Я выбираю следующий. Продемонстрирую сигнатуру функции, дабы объяснение было более наглядным:
Где duration - время в секундах, продолжительность вращения камеры, angleDeg - угол в градусах на который камера будет отклонена от направления взгляда игрока, к которому она в итоге должна вернуться, direction - направление, в котором будет происходить наклон.
На примере это всё выглядит так, с помощью угла, а точнее тангенса угла наклона, мы вычисляем длину направляющего вектора, суммируем его с вектором нашего взгляда и получаем результирующий вектора направления камеры:
Перейдём к реализации функционала:
Для составления полной картины: реализации, иерархии объектов, демонстрации работы, настройки параметров, - рекомендую ознакомиться с записью моего стрима, где всё это реализовано:
На этом, пожалуй, всё. Я придумал еще один вариант реализации ударного вращения камеры, чему планирую посвятить отдельную статью. Также вибрацию камеры не помешало бы объединить с вращением. Пишите свои замечания и идеи для улучшения данных механик.
Полезные ссылки:
Добавлю что тряска камеры через position лучше подходит для 2д игр, где камера всегда смотрит сбоку или сверху, вдали от объектов игрового мира. Для 3д игр, особенно для игр от третьего лица лучше всегда использовать тряску камеры через rotation, чтобы камера всегда оставалась на месте и не улетала, например, в стену, если персонаж находится в узком коридоре.
Соглашусь. Думаю идеальным вариантом будет улучшить тряску камеры, добавив туда тряску через вращение. И сделать два параметра разброса настраиваемыми. То есть разброс позиции и разброс углов вращения.
Комментарий недоступен
А потом просто берём и накатываем Cinemachine, где всё это уже реализовано, удобно и бесплатно) По крайней мере для простых задач подходит отлично
Да. Но мне эта задача показалась достаточно интересной, чтобы её разобрать и написать статью. Я думаю, полезно уметь решать такие задачи, если вдруг это будет не Unity и готового решения под руками не окажется. Unity в таких ситуациях хорош из-за скорости реализация и демонстрации результата.
Комментарий недоступен
Вы Правы. Исправил в тексте статьи. Только в названии оставил.