Per aspera ad astra или RoadMap по вашей будущей игре. Godot 4 C# Часть 8 "Коллизии и коллайдеры".
Итак, коллайдеры и коллизии — что это такое и с чем это едят?
В игровом мире объекты не наделены физикой «по слову божьему». Нельзя создать землю из текстуры и рассчитывать, что персонаж начнёт по ней ходить. Чтобы придать объектам физические свойства, необходимо проделать определённую работу, а именно — добавить коллайдер (фигуру столкновений) к телу.
Например, мы пытаемся создать персонажа в подземелье (о котором я говорил в предыдущей статье). С чего же начать?
Думаю, стоит начать с определений.
Коллайдер — это невидимая упрощённая форма объекта, которая используется для расчёта физических взаимодействий: столкновений, пересечений и реакций на них (что бы с этим работать для нас и будет важно понимание сигналов).
Коллизии — это и есть столкновения. Программно их можно представить как пересечение координат объектов.
Важно понимать, что подобные расчёты не выполняются моментально, и тела могут незаметно слегка заходить друг в друга. Иногда это вызывает дрожание персонажа при движении по коллайдеру. Такое поведение возникает из-за того, что тело выталкивает персонажа слишком резко. Этот эффект можно устранить, задав в свойствах коллизии параметр safe_margin — так вы укажете движку создавать небольшой отступ для сглаживания столкновений.
Локационный урон (разные зоны коллизий)
Форма столкновения у персонажа не обязательно должна быть одна. Вы можете назначить разным частям тела отдельные Area2D/3D и обрабатывать попадания по ним индивидуально. Это позволит реализовать механику повреждений конечностей (например, отдельно для рук, ног или головы).
Пересечение коллайдеров и оптимизация
Чем проще форма коллайдера, тем быстрее его расчёт. Например, если для персонажа использовать простую капсулу, она будет обрабатываться гораздо быстрее, чем сложная форма, повторяющая его геометрию. Поэтому, если нет особой необходимости, лучше выбирать простые формы.
Коллайдеры могут пересекаться друг с другом (например, рука заходит в зону тела). Даже если у родительского узла есть коллайдер, он может учитывать столкновения с дочерними объектами. Это увеличивает нагрузку на движок. Чтобы избежать проблем, правильно распределяйте слои (collision_layer) и маски (collision_mask) столкновений:
- Слой (layer) — определяет, к какой группе принадлежит объект ( на каком слое находится ).
- Маска (mask) — указывает, с какими слоями объект может сталкиваться.
Пример: Если первый объект имеет mask = 2, а второй — layer = 2, то первый будет регистрировать столкновения со вторым. Все остальные слои игнорируются.
Итак, какие же узлы нам доступных для физики? Их достаточно много, и они расположены в разделе CollisionObject2D.
- StaticBody2D – неподвижное тело (например, полы, стены, платформы). Позволяет выстраивать окружение в игре. Гравитация на этот тип тела не работает, если разместить его в игре, оно останется на тех позициях, в которые вы его определили.
- RigidBody2D – динамическое тело с полной физической симуляцией (под действием гравитации, столкновений и сил). Например, фигуры в «Angry Birds», при попадании по ним рассыпаются по физическим законам.
- CharacterBody2D – тело, управляемое кодом (например, игрок), с поддержкой коллизий, но без автоматической физики. Если создать персонажа из RigidBody2D, на него будет работать много лишних физических процессов, например, тело начнет заваливаться набок, а попадание каких-либо физических объектов будет отбрасывать персонажа и валять по полу. Придется приложить усилия, чтобы персонаж нормально вел себя, поэтому для персонажей был выделен отдельный узел с ограниченной физикой.
- Area2D – зона, которая обнаруживает другие тела (например, для триггеров). Невидимая в игре зона, которая фиксирует вход и выход тела в нее. Можно подключиться к этим событиям и запустить свой код.
- CollisionShape2D – форма коллизии для тел (круг, прямоугольник, полигон и др.). Определяет размеры и форму коллайдера. Обычно используется там, где необходима простая форма (квадрат, капсула, сфера и т.д.).
- CollisionPolygon2D – полигональная форма коллизии (можно задавать свои формы коллизий, что позволяет создать пользовательскую фигуру). Имеет массивы точек, по которым вы можете выстроить любую фигуру в 2D. Так же с помощью этого массива можно программно изменять форму.
- RayCast2D – луч для обнаружения объектов на пути (Например, используется для расчета расстояния от игрока до объекта атаки, может ли игрок атаковать цель).
- PhysicsMaterial – настройки трения и упругости для тел (например, бег по асфальту или песку, создание следов на земле).
CollisionShape2D или CollisionPolygon2D используются как дочерние узлы для других физических узлов. Поэтому при добавлении какого либо Area2D, движок начнет ругаться, что в его состав должен входить CollisionShape2D.
PhysicsMaterial - указывается как параметр для RigidBody2D и других. Он не является узлом.
Добавил все это в список для удобства.
Концепция работы коллайдеров достаточно проста для понимания. Вешаем на объект, например, RigidBody2D, добавляем ему дочерним узлом CollisionShape2D и в настройках узла выбираем форму.
Растягиваем форму так, чтобы она была вровень с формой объекта. Задаем слои столкновений и маски. Создаем объекту файл скрипта. Смотрим, какие есть сигналы у RigidBody2D и CollisionObject2D.
Создаем в скрипте приватный метод для сигнала. Подписываемся на любой из сигналов в скрипте и указываем ему созданный метод ( подробнее на ТГ ).
Готово!
Можете в методе написать следующую строку: GD.Print(1). Когда ваш объект обработает столкновение, в консоли редактора будет выведена 1.
Спасибо за поддержку!