Типы коллизий
Коллизия в Unreal Engine похожа на Unity, но имеет некоторые отличия, о которых мы расскажем далее. Если вы работали с системой обнаружения коллизий в Unity на основе слоёв, настройки коллизий в проекте, скорее всего, будут выглядеть для вас похожими на матрицу коллизий. Вы можете найти это в разделе Правка > Настройки проекта > Коллизия. Если раскрыть вкладку Заготовка, вы увидите все профили заготовок по умолчанию, а также описания к ним.
Вы можете обратить внимание, что у Unreal есть несколько дополнительных вариантов обработки коллизий. Более подробно о них рассказано в разделе «Общая информация о коллизиях в Unreal Engine». Такой уровень детализации при обнаружении коллизий, помимо прочего, может помочь добиться лучшей производительности игры. Важно понимать следующее.
Каналы или отдельные объекты коллизий можно настроить на блокировку, пересечение или игнорирование.
Достаточно распространённой ошибкой является отсутствие флажка рядом с параметром генерации событий пересечения для объектов коллизий при необходимости получения данных событий.
Статичная геометрия должна выполнять блокировку или пересечение, но не обязательно должна генерировать события пересечения или попадания, поскольку это не требуется для игрового процесса.
События пересечения могут возникать даже в том случае, если один объект блокирует другой, особенно при движении на высоких скоростях. В Unity это может стать проблемой, если вы напрямую изменяете перенос, а не компонент Rigidbody. В этом случае мы не учитываем аспект физики.
В Unreal при вызове любой функции, обновляющей преобразование актора, мы работаем с двумя логическими параметрами, которые и определяют, как будет двигаться актор:
поиск пересечений устанавливает значение true для триггеров пересечения и останавливает актор, не давая ему дойти до цели при блокировке; телепортация определяет, будет ли сохраняться физическая скорость.
Каналы также можно использовать для трассировок, аналогом которых в Unity является «приведение физики» (т. е. Raycast, SphereCast и т. д.). Вы можете передать канал во время вызова функции линейной трассировки аналогично тому, как вы передаёте маску слоя в Raycast в Unity.
Пользовательские типы коллизий в игре Parrot
В игре Parrot подготовлено несколько пользовательских каналов для объектов коллизии: Player, Cannonball и Enemy.
После добавления этих типов объектов игра сможет контролировать, как именно эти каналы объектов будут взаимодействовать с каналами трассировки в момент, когда в мире возникают трассировки столкновений. По умолчанию задаётся реакция, которая должна происходить в большинстве случаев, но её можно настроить по своему усмотрению. В игре Parrot также предусмотрено несколько пользовательских заготовок каналов трассировки: Player, OverlapAllPlayers, BlockAllPlayers, Cannonball и Enemy.
Эти заготовки особенно пригодятся при работе с триггерами игрового процесса. К примеру, OverlapAllPlayers может игнорировать все остальные столкновения и реагировать только на события столкновения с типами объектов коллизии игроков. Если взглянуть на настройки коллизий для различных сеток в игре, то вы можете заметить, что эти заготовки используются достаточно часто.
Если необходимо, параметры коллизий можно настроить для каждой отдельной сетки.
Границы мира
При создании уровней важно продумывать границы мира. Задать их можно, перейдя в Настройки мира > Мир. Вы можете реализовать собственный тип урона на случай, когда актор будет взаимодействовать с заданными границами мира. В игре Parrot используется сочетание настройки мира KillZ и области активации За пределами границ.
Триггерные объемы
В Unreal Engine предусмотрены встроенные акторы областей активации (см. раздел «Акторы областей активации в Unreal Engine»), которые можно использовать для запуска различных событий. В качестве примеров, где разработчики используют их в игре Parrot, вы можете взять области активации За пределами границ и Линия финиша. Области активации часто используются в сочетании со схемой уровня (см. раздел разработчиков Схемы Blueprint уровней в игре Parrot), однако это необязательно. Триггером игры Parrot на выход за пределы границ выступает триггер кубоида с довольно простым графом событий:
Если взглянуть на настройки коллизии актора на панели «Сведения», то можно заметить, что значительную часть работы здесь выполняет заготовка канала столкновений.
Подбор усиления
Давайте рассмотрим пример системы коллизий на примере реализации подбираемого предмета. Если открыть BP_PickupBase в Содержимое > Blueprints > Pickups, то в окне просмотра вы увидите иерархию, содержащую компонент коллизии.
В настройках коллизий и выхода за пределы границ есть заготовка триггера, которая генерирует события пересечения для игроков:
Если взглянуть на граф событий, вы увидите событие ActorBeginOverlap с другим актором в качестве параметра. Это событие похоже на OnCollisionEnter из Unity. Разница в том, что вместо компонента объекта коллизии вам передаётся сам актор.
В игре выполняется приведение для проверки того, является ли актор игроком, который выполнил пересечение. Затем выполняется вызов события OnPickedUp. Это позволяет производным классам схем определять собственное поведение для OnPickedUp, в то время как базовый класс будет сам обрабатывать событие пересечения актора.
Разработчики используют базовую схему для того, чтобы все подбираемые предметы воспроизводили звук и создавали эффекты частиц. Переменные звука, издаваемого подбираемыми предметами, и эффекта частиц являются изменяемыми по экземпляру, поэтому их можно задать в настройках класса по умолчанию производных классов. Настройки класса по умолчанию находятся в редакторе схем Blueprint в верхней части рядом с кнопкой компиляции:
Примером изменённых настроек класса по умолчанию может служить подбираемый предмет, придающий скорость, который использует систему Niagara с зелёными частицами (в отличие от подбираемого «сердца», в котором используются розовые частицы). Аналогичным образом, сетку подбираемого предмета можно задать на производных схемах. Последним шагом в логике пересечения будет уничтожение актора подбираемого предмета, поскольку вам не нужно, чтобы он сохранялся после того, как игрок подберёт его.
С помощью всего нескольких узлов вы сможете создать полноценную рабочую логику, которую мы будем также использовать и в производных схемах. Все производные схемы следуют из события пересечения, связанного с актором.
Спрыгивание персонажа игрока с противника
Ещё один отличный пример — это спрыгивание игрока с противника. Тип объекта коллизии противника будет «вражеским» и он будет сталкиваться с типами объектов игрока. Противники с мечами также имеют аналогичное событие пересечения. Их принято называть хитбоксами, которые представляют собой место, где атака считается удачной.
Но когда игрок спрыгивает с противника, как игра Parrot обрабатывает это действие? Решение заключалось в том, чтобы поместить хёртбоксы на головы противников. Когда игрок пересекается с областью хёртбокса, персонаж игрока может выполнить набор проверок, чтобы убедиться, что сам прыжок является допустимым с учётом местоположения персонажа, хёртбокса и размеров кубоида. Если проверки успешно проходят, игрок может выполнить прыжок и поразить противника. Основную работу здесь снова выполняют каналы столкновений, фильтруя только те пересечения, которые важны для самой игры: объект коллизии игрока и противник на области хёртбокса.