Как я делал эффект пулемётной очереди более сочным
Или рассказ о том, в какое место иногда нам приходится засовывать физическую достоверность ради эстетики
Напишу такую маленькую статью, потому что имхо на офф.подсайт материал не тянет, но тем не менее интересно.
Собственно, какая постановка задачи: есть пулемёт, он стреляет очередью, причём скорострельность довольно высокая. Но пространство, на которой происходит игра, довольно большое, а скорость снаряда соответствующая. Поэтому очередь очень быстро становится не видна. Как это выглядит в оригинале:
Заказчику такое поведение не нравится, он хочет, чтобы стрельба выглядело сочно. С самого начала было предложено отделить физическую реализацию от графической, то есть чтобы патроны были невидимые, а на пулемёте просто висел эффект из системы частиц. Имхо, даже если со скорострельным пулемётом это будет работать, то с любым другим оружием, например выпускающим по патрону в секунду, придётся писать что-то новое. Я же хотел универсальное решение.
К тому же, пользователи не будут явно чувствовать связь между процессом стрельбы и её результатом, урон будет защитываться там, где патрон не был нарисован — и наоборот, там где патрон был, урона не будет. Что может быть хуже.
В чём проблема? В том, что патрон на экране становится слишком маленьким, чем дальше он от камеры. Какое решение первым пришло в голову? Менять размер патрона! Вот так это и работает: чем дальше патрон от камеры, тем больше становятся его размеры. Причём, размеры только графические, физика стрельбы работает исключительно на рейкасте.
Ниже вы можете видеть, как это выглядит в реальности, сбоку.
Да, чем дальше патроны от камеры, тем более монструозных размеров они достигают. В том числе, в десятки раз больших, чем их оригинальные размеры.
Ну, скажем так, объяснение, данное выше, намного проще, чем на самом деле. Мне потребовалось несколько дней работы, чтобы найти правильные формулы и отладить параметры.
Во-первых, если делать в лоб, то есть увеличивать размер патрона независимо ни от чего, кроме как от дальности от камеры, то это перестаёт работать сразу же, как только мы вводим пулемёты, стреляющие не у камеры.
Поэтому я сделал учёт угла, под которым снаряд летит относительно камеры. Снаряд будет увеличиваться по одним параметрам, если он летит параллельно направлению камеры, и по другим, если он летит перпендикулярно. Так, если он летит перпендикулярно, то коэффициент увеличения длины уменьшается.
Во-вторых, коэффициенты увеличения разные у каждой компоненты. Это сделано для того, чтобы снаряд не превращался в жирные точки на экране. Так, длина увеличивается сильнее, чем ширина и высота снаряда.
В-третьих, увеличивать размеры снаряда лучше тоже неравномерно, а с затуханием. То есть, если снаряд улетел на добрые 1000 метров, то не стоит его держать видимым на экране ровно в тех же пропорциях, что и вплотную к камере. Вот так выглядит график функции, которая преобразует дальность от камеры в затухающую величину, если так можно выражаться.
Собственно, как я уже говорил, такой маленький эффект занял у меня несколько дней раздумий того, как это лучше сделать и какие формулы использовать. Вообще, разработка игр — неожиданно долгий процесс. Можно, конечно, сделать на тяп-ляп и готово. Но дъявол в деталях, и если хочешь, чтобы всё выглядело не как получится, а согласно твоему видению, то готовься убить пару-тройку лет.