Физика и столкновения
Выбор физического тела, формы столкновения, слоёв и шага обновления.
Начните с задачи объекта, а не с названия класса. Видимая модель, физическая форма и код движения выполняют разные функции; добавление спрайта или меша не создаёт коллизию.
Выберите тип
| Задача | 2D / 3D | Кто двигает |
|---|---|---|
| Неподвижные пол и стена | StaticBody2D / StaticBody3D | Не двигаются от контакта. |
| Игрок или управляемый персонаж | CharacterBody2D / CharacterBody3D | Ваш код с MoveAndSlide() или MoveAndCollide(). |
| Ящик, мяч, физический предмет | RigidBody2D / RigidBody3D | Симуляция; код прикладывает силы и импульсы. |
| Платформа с заданной траекторией | AnimatableBody2D / AnimatableBody3D | Скрипт или анимация задаёт движение. |
| Зона подбора, урона или обнаружения | Area2D / Area3D | Обнаруживает пересечения; сама не служит твёрдой стеной. |
CharacterBody2D не получает гравитацию автоматически: это часть вашего контроллера. RigidBody2D симулируется автоматически, поэтому не переписывайте его Position каждый кадр вместо управления силами.
Получите первый проверяемый результат
Для физического предмета откройте пример Area2D. Добавьте два полных файла LabBody2D.cs и CollisionLab2D.cs, назначьте второй корневой Entity2D отдельного уровня и запустите его. Условия примера: окно 640×420, 60 физических шагов в секунду, гравитация 980 вниз.
Ожидаемый результат: ящик проходит сквозь прямоугольную зону, счётчики входа/выхода увеличиваются, затем ящик останавливается на твёрдом полу. Так в одном опыте видна разница между обнаружением и блокировкой. R сбрасывает предмет через запрос к его физическому состоянию; автоматическая проверка вызывает тот же метод сброса программно, а не эмулирует физическую клавиатуру.
Если нужен игрок, сразу используйте готовый контроллер 2D или контроллер 3D. Не стройте управление игроком на примере физического ящика.
Настройте форму
Создайте дочернюю CollisionShape2D или CollisionShape3D и назначьте ресурс Shape. Сам Shape2D — ресурс, а не дочерняя Entity. Для ящика начните с прямоугольника/параллелепипеда, для шара — круга/сферы, для персонажа — подходящей капсулы.
Проверьте размер и положение формы относительно изображения. Меняйте размеры ресурса формы; не используйте неравномерный масштаб тела как замену настройке коллизии. Если несколько объектов используют один ресурс формы, изменение ресурса затронет их все; формы 2D, формы 3D.
Разберите слои на конкретной паре
CollisionLayer — принадлежность объекта. CollisionMask — фильтр взаимодействия или обнаружения. Это битовые маски uint; номер слоя 3 соответствует значению 4 (1u << 2), а не маске 3. Методы SetCollisionLayerValue и SetCollisionMaskValue принимают номер 1–32, а не готовую маску.
В выполненном примере пол имеет Layer=1, Mask=0, ящик — Layer=4, Mask=1. Они сталкиваются: не требуйте одинаковых взаимных масок от каждой пары тел. Зона имеет Mask=4 и обнаруживает ящик. Маска зоны направлена на слои обнаруживаемого тела; для луча задаётся собственная маска. Разбирайте фильтры конкретного типа запроса, а не переносите одно правило на все системы.
Слои физики, навигации и отображения — отдельные фильтры. Взаимодействовать могут объекты соответствующего физического мира: коллизия 2D не останавливает тело 3D.
Скорость, смещение и delta
| Действие | Что передать |
|---|---|
CharacterBody2D.Velocity, затем MoveAndSlide() | Скорость в единицах в секунду, без умножения на delta. |
MoveAndCollide(motion) | Смещение за шаг; для постоянной скорости — velocity * (float)delta. |
| Гравитация в контроллере | Прибавку скорости acceleration * (float)delta. |
ApplyCentralForce(force) | Силу в каждом нужном физическом шаге; не превращайте её предварительно в импульс через delta. |
ApplyCentralImpulse(impulse) | Одноразовый импульс по событию. Повторение каждый кадр — многократное воздействие. |
Движение персонажа выполняйте в _PhysicsProcess(double delta). Значение physics/common/physics_ticks_per_second задаёт частоту; 60 — условие примеров, а не обязательная частота любого проекта. В 2D обычно используют пиксели и положительный Y вниз; в 3D — метры и положительный Y вверх. Ваш масштаб должен быть согласован с настройками, но векторы сами единицы не проверяют.
Если результат неверный
- Тело проваливается: проверьте наличие
Shape, включение формы, мир, положение, слои и метод движения. - Зона не сообщает вход: проверьте
Monitoring, маску зоны и слой тела; дайте физике обновить пересечения. - Предмет дрожит: уберите покадровое присваивание трансформа симулируемому телу; управление RigidBody.
- Объект виден между шагами рывками: изучите интерполяцию. Она не исправляет коллизию и не делает физику детерминированной.
- Нужна только проверка попадания: используйте луч, а не невидимое движущееся тело.
Проверены контакт пола и предмета, асимметричные маски, вход/выход зоны, сброс, импульс и масса в связанных примерах. Это не гарантия одинаковой симуляции на всех платформах и бэкендах; движущиеся платформы, физические устройства ввода, высокоскоростные столкновения и производительность этой проверкой не оценивались.