Как я делал эффект пулемётной очереди более сочным

Или рассказ о том, в какое место иногда нам приходится засовывать физическую достоверность ради эстетики

Конечный результат
Конечный результат

Напишу такую маленькую статью, потому что имхо на офф.подсайт материал не тянет, но тем не менее интересно.

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

На экране можно видеть примерно с десяток летящих снарядов, но разглядеть можно только один - и тот вблизи. Чем дальше снаряды, тем они меньше, тем нереальнее их разглядеть.<br />
На экране можно видеть примерно с десяток летящих снарядов, но разглядеть можно только один - и тот вблизи. Чем дальше снаряды, тем они меньше, тем нереальнее их разглядеть.

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

К тому же, пользователи не будут явно чувствовать связь между процессом стрельбы и её результатом, урон будет защитываться там, где патрон не был нарисован — и наоборот, там где патрон был, урона не будет. Что может быть хуже.

В чём проблема? В том, что патрон на экране становится слишком маленьким, чем дальше он от камеры. Какое решение первым пришло в голову? Менять размер патрона! Вот так это и работает: чем дальше патрон от камеры, тем больше становятся его размеры. Причём, размеры только графические, физика стрельбы работает исключительно на рейкасте.

Ниже вы можете видеть, как это выглядит в реальности, сбоку.

Да, чем дальше патроны от камеры, тем более монструозных размеров они достигают. В том числе, в десятки раз больших, чем их оригинальные размеры.

Ну, скажем так, объяснение, данное выше, намного проще, чем на самом деле. Мне потребовалось несколько дней работы, чтобы найти правильные формулы и отладить параметры.

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

Вдалеке можно видеть пулемётную очередь, состоящую из огроменных цилиндров, образующих стену. Выглядит очень странно<br />
Вдалеке можно видеть пулемётную очередь, состоящую из огроменных цилиндров, образующих стену. Выглядит очень странно

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

Вот по таким не очень хитрым расчётам я узнаю коэффициент перехода, который потом я засуну в Mathf.Lerp.<br />
Вот по таким не очень хитрым расчётам я узнаю коэффициент перехода, который потом я засуну в Mathf.Lerp.

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

<br />

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

Больше 300 метров от камеры - снаряд перестаёт увеличиваться вообще. Впрочем, максимальную дальность можно задавать отдельно.
Больше 300 метров от камеры - снаряд перестаёт увеличиваться вообще. Впрочем, максимальную дальность можно задавать отдельно.

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

66
4 комментария

Гифки бы, так лучше было бы видно разницу.

Ну а сама идея крутая. Лет через N можно про нее писать в твиттере в треде про хитрости разработчиков.

Ответить

Да я не знаю, как гифки записывать, если честно

Ответить