При разработке игры мы столкнулись с необходимостью отображать информацию так, чтобы пользователь её заметил. Например, подбирая аптечку, игроки не всегда замечают что в углу экрана в HUD начинает прибавляться здоровье. Так появилась задача по добавлению визуального эффекта поверх игрового процесса.
Задача. Необходимо показать эффект лечения. Из нижней части экрана летят плюсики, каждый из них покачивается влево-вправо, меняет яркость и плавно исчезает в центре. Все это сделать через PostProcess.
Прежде всего, подготавливаем текстуру с плюсиками, которая понадобится для эффекта. Каждый канал содержит определенную информацию:
В итоге получаем такую текстуру:
Чтобы избежать артефактов сверху и снизу у плюсиков надо настроить текстуру при импорте в Unreal Engine следующим образом:
Когда текстура готова и импортирована, создаем новый материал. В настройках материала устанавливаем свойство Material Domain в PostProcess.
Само написание материала можно разделить на несколько этапов.
Во-первых, нужно добавить движение плюсиков вверх. Для этого вызовем Panner от Screen Position и укажем в параметрах скорость по Y = 0.2. Таким образом, наша текстура будет постепенно двигаться вверх.
Чтобы плюсики равномерно распределялись по экрану и не растягивались, текстурные координаты по X умножаем на отношение ширины экрана к высоте. Добавляем сдвиг в половину дробной части. И умножаем текстурные координаты на CoordsScale (в нашем случае равен 2), чтобы плюсиков было больше и они были меньшего размера (не пришлось тратить много времени на рисование большого количества плюсиков в текстуре).
Во-вторых, добавим покачивание плюсиков. Из зеленой компоненты текстуры берем значение начального сдвига, умножаем на период покачивания и добавляем текущему времени Time. Все это передаем в функцию LinearSine и результат умножаем на амплитуду покачивания. Полученное значение добавляем к текстурной координате по X.
В третьих, изменение яркости плюсиков. По новым текстурным координатам мы получаем начальное значение яркости (красный канал текстуры), которое будет изменяться до 1 и обратно. Итоговая яркость получается: (1 — red) * RoundedLinearSin + red. Где RoundedLinearSin это значения от 0 до 1 из функции LinearSine, а red — это значение из красного канала. Результат умножаем на цвет плюсика (светло-зеленый в нашем случае).
Яркость используем для смешивания с текущим изображением сцены, чтобы наложить наш эффект поверх игрового процесса. Для этого умножим его на округленное вверх значение (Ceil) из красного канала (чтобы ничего за пределами плюсика не мигало). Затем, на значение из синего канала, которое берем по экранным координатам. Это добавит эффект плавного исчезновения плюсиков ближе к центру экрана. Кроме того, нам потребуется параметр Scale, который пригодится для постепенного появления эффекта лечения. Полученное значение используем для линейной интерполяции (Lepr) между изображением сцены и цветом плюсика.
Чтобы не выполнять лишние расчеты там, где это не нужно, добавим условие, проверяющее, где точно нет плюсика. В итоге у нас получился такой материал (картинка кликабельна):
Осталось только вызвать плавное появление и исчезновение эффекта при подбирании аптечки и при окончании ее действия. Добавляем Timeline в котором меняем параметр Scale и события для запуска и завершения эффекта.