Физика в 2D-играх: твёрдые тела, коллайдеры и триггеры
Физика в 2D-играх держится на трёх строительных блоках, которые вы расставляете в каждой сцене: твёрдое тело — объект с моделируемой массой и движением; коллайдер — фигура, регистрирующая контакт между объектами; и триггер — коллайдер, который замечает пересечение, но ничего не задерживает. Динамическое тело падает и получает толчки; статическое — это неподвижная земля, на которую оно опускается; кинематическое — движущаяся платформа, которую ни то ни другое не сдвинет с пути. Контакт запускает события в момент начала, продолжения и окончания касания, а слои столкновений определяют, какие пары тел вообще взаимодействуют. В руководстве разобрано, что делает каждый примитив, как они складываются в движение игрока, подбор предметов и опасности, как одни и те же идеи называются в Unity и Godot и какие ошибки делают 2D-физику сломанной.
Физика в 2D-играх держится на трёх строительных блоках, которые встречаются в каждой сцене: твёрдом теле — объекте с моделируемой массой и движением; коллайдере — фигуре, регистрирующей контакт; и триггере — коллайдере, который замечает пересечение, но ничего не блокирует. Персонаж платформера — это твёрдое тело с коллайдером. Пол под ним — другое такое тело. Монета, которую персонаж собирает, — триггер: он фиксирует пересечение и исчезает, но никогда не преграждает игроку путь. Всё остальное в 2D-физике — гравитация, трение, упругость, сочленения, события — надстроено над этими тремя примитивами и зависит от того, как вы их сочетаете.
Это руководство о строительных блоках. О том, как устроен лежащий под ними движок — конвейер симуляции, широкая и узкая фаза, проблема масштаба мира, — рассказывает разбор «Движок 2D-физики: всё, что нужно знать». А выбрать подходящий движок помогает сравнение физических движков для 2D. Здесь мы разбираем три элемента, которые вы непосредственно расставляете в сцене и связываете между собой.
Твёрдые тела: объекты, которые движутся
Твёрдое тело — это физический объект: нечто, что симуляция наделяет массой, положением, скоростью и вращением, и всем этим управляют силы и столкновения, а не прямое указание координат. Слово «твёрдое» здесь не случайно: такие тела не гнутся и не ломаются. Это цельные куски, поэтому ящик кувыркается как единое целое, а доска не прогибается.
Каждое твёрдое тело относится к одному из трёх типов, и выбор типа определяет его поведение.
| Тип тела | Гравитация | Реагирует на столкновения | Как движется | Для чего |
|---|---|---|---|---|
| Динамическое | Да | Да | Толкают силы, импульсы и скорость | Игрок, ящики, мячи — всё, что должно реагировать |
| Статическое | Нет | Нет (другие сталкиваются с ним) | Никак — ставится один раз и не двигается | Земля, стены, постоянные платформы |
| Кинематическое | Нет | Нет | Вы двигаете его через скорость | Движущиеся платформы, вращающиеся лезвия, двери |
Два правила несут основную нагрузку. Динамическое тело полностью подчинено симуляции: гравитация тянет его, столкновения толкают, и оно толкает в ответ. Статическое тело — это неподвижные декорации, от которых остальное отскакивает. Кинематическое тело занимает промежуточное положение: вы управляете им кодом, поэтому на него не действует гравитация и его нельзя сбить с курса, но динамическое тело, опустившееся на него, всё равно двигается вместе с ним. Именно это и нужно движущейся платформе.
Коллайдеры: фигуры, создающие контакт
Коллайдер — это невидимая фигура, задающая, где тело твёрдое. Она отделена от спрайта, который вы рисуете, и это правильно: визуальное искусство и геометрия столкновений служат разным целям. У круглой монеты может быть квадратный коллайдер; у колючего персонажа — простая капсула, чтобы он не цеплялся за каждый край.
Базовые формы коллайдеров выбраны не случайно. Ящик, круг или капсула дёшевы для движка и устойчивы при вращении. Многоугольник точнее повторяет рисунок, но обходится дороже и ведёт себя непредсказуемо, если он вогнутый. Практический совет — брать самую простую форму, которая читается правильно: круг для мяча, прямоугольник для ящика, капсула для гуманоида, — и переходить к многоугольникам только там, где нужна точность.
Каждый коллайдер может нести физический материал, определяющий поведение при контакте. Трение сопротивляется скольжению: пол с высоким трением позволяет игроку подниматься по пологому склону, а почти нулевое превращает его в лёд. Упругость — это отскок, то есть доля энергии, которую тело сохраняет после удара: почти нулевая для тяжёлого ящика и выше 0,8 для резинового мяча. Именно эти два числа больше всего отвечают за то, чтобы поверхности ощущались по-разному.
Триггеры: коллайдеры, которые замечают, а не блокируют
Триггер — это коллайдер, у которого переключено одно свойство: он фиксирует пересечение, но не создаёт физического отклика. Два тела, в контакте которых участвует триггер, проходят прямо друг сквозь друга — ничто не блокирует, ничто не отскакивает, — но движок всё равно запускает событие в момент пересечения. В некоторых движках это называется датчиком (sensor).
Это механизм, на котором держится в игре любой контакт, не создающий физического отклика. Монета — триггер, сквозь который проходит игрок: пересечение срабатывает, монета собирается, а игрок ни на миг не замедляется. Радиус обнаружения врага — триггер, который переводит врага в режим погони, едва в него входит игрок. Чекпоинт, зона выхода с уровня, область урона от взрыва — всё это триггеры. Схема одна: зафиксировать контакт, выполнить логику, пропустить физический отклик.
Коллайдер против триггера: главное отличие
Начинающие разработчики теряют часы, путая эти две вещи, потому что в редакторе они выглядят одинаково — обе представляют собой фигуру, прикреплённую к телу. Разница целиком в том, что они делают при контакте.
| Коллайдер | Триггер | |
|---|---|---|
| Блокирует движение | Да | Нет |
| Создаёт физический отклик (толчок, отскок) | Да | Нет |
| Запускает событие при пересечении | Да | Да |
| Типичное применение | Пол, стены, игрок, ящики | Подбираемые предметы, зоны обнаружения, чекпоинты, ловушки |
Характерные ошибки зеркальны. Сделайте игрока чистым триггером — и он провалится сквозь пол. Сделайте монету жёстким коллайдером — и игрок отскочит от неё вместо того, чтобы подобрать. Когда физическое взаимодействие ощущается неправильным, первый вопрос: является ли каждая задействованная фигура твёрдой или чувствительной.
Связываем блоки: события и слои
Расставить тела — полдела; вторая половина — отреагировать, когда они встретятся. Связать примитивы с игровой логикой помогают два механизма.
События столкновений для каждой пары срабатывают в трёх случаях: при входе, когда пересечение началось; при удержании, на каждом шаге физики, пока оно продолжается; и при выходе, когда оно завершилось. У жёстких столкновений и триггеров свой набор таких событий. Так и пишут код, реагирующий в момент контакта, а не проверяющий его каждый кадр.
Слои и маски столкновений определяют, каким телам вообще позволено взаимодействовать, поэтому движок пропускает пары, которые вас не касаются. Слой задаёт группу — игрок, враги, снаряды, декорации. Маска перечисляет, с какими другими группами тело сталкивается или какие замечает. Поместите игрока на слой Player, который сталкивается с декорациями, но игнорирует других игроков, и пусть триггеры обнаружения врагов реагируют только на слой игрока. Слои — инструмент одновременно корректности (пули игрока не бьют самого игрока) и производительности (движок не проверяет пары, которые вы отфильтровали).
Шаг физики — коротко
Всё это работает на фиксированном шаге: симуляция продвигается одинаковыми порциями времени — 50 шагов в секунду, обычное значение по умолчанию, — независимо от того, как быстро перерисовывается экран. Именно постоянство шага делает дугу прыжка одинаковой на телефоне с 60 Гц и мониторе с 144 Гц. Один быстрый объект может нарушить эту стабильность, проскочив насквозь: за один шаг он оказывается по другую сторону тонкой стены, и движок не замечает пересечения. Непрерывное обнаружение столкновений лечит это, отслеживая движение тела на протяжении всего шага, а не в одной точке. В разборе про движок 2D-физики конвейер описан подробно; здесь важно другое — шаг физики — это тот ритм, в котором движутся ваши тела, коллайдеры и триггеры.
Как движки называют одно и то же
Три примитива универсальны, но каждый движок зовёт их по-своему. То, что в одном инструменте галочка, в другом — отдельный узел.
| Понятие | Unity (2D) | Godot |
|---|---|---|
| Динамическое тело | Rigidbody2D (Body Type: Dynamic) | RigidBody2D |
| Статическое тело | Rigidbody2D (Body Type: Static) | StaticBody2D |
| Кинематическое тело | Rigidbody2D (Body Type: Kinematic) | AnimatableBody2D |
| Игрок, которым управляете сами | Rigidbody2D или собственный контроллер | CharacterBody2D |
| Форма столкновения | Collider2D (Box / Circle / Polygon) | CollisionShape2D + ресурс Shape2D |
| Триггер | Collider2D с галочкой Is Trigger | Area2D |
| Событие жёсткого столкновения | OnCollisionEnter2D (и Stay / Exit) | сигналы body_entered / body_exited |
| Событие триггера | OnTriggerEnter2D (и Stay / Exit) | area_entered / body_entered у Area2D |
Стоит знать один нюанс: в Godot CharacterBody2D — это тело кинематического типа, которое вы двигаете сами методом move_and_slide, а не то, что толкает решатель физики. В Unity та же идея — многие платформеры вовсе не отдают игрока под полную динамическую симуляцию, а двигают его вручную и используют коллайдеры лишь для разрешения контакта. Оба подхода допустимы; компромисс — между реалистичной симуляцией и чётким, предсказуемым контролем.
Частые ошибки
| Ошибка | Что не так | Как правильно |
|---|---|---|
| Игрок — триггер | Проваливается сквозь пол и стены | Дайте игроку жёсткий коллайдер; триггеры оставьте для обнаружения |
| Статическое тело двигают напрямую | Дрожь, телепортация, пропущенные столкновения | Для того, что двигаете кодом, используйте кинематическое тело |
| Коллайдер скопирован со спрайта | Зацепы за края, неточный контакт | Возьмите простую форму (ящик/круг/капсула), подобранную под геймплей |
| Физику читают в кадровом обновлении | Пропущенные или задвоенные контакты | Обрабатывайте контакт в шаге физики (FixedUpdate / _physics_process) |
| Нет CCD у быстрых снарядов | Снаряды пролетают сквозь тонкие стены | Включите непрерывное обнаружение столкновений для быстрых тел |
| Всё на одном слое столкновений | Объекты сталкиваются, хотя не должны | Разнесите тела по слоям и задайте маски осознанно |
Более широкий набор ошибок настройки — масштаб мира, сочленения, создаваемые каждый кадр, физика, привязанная к частоте кадров, — разбирает гид по типичным ошибкам 2D-физики, а руководство по исправлению багов физики подскажет, что делать, когда всё уже сломалось.
Как вписывается Egmatic
Работа с этими примитивами — по сути настройочный цикл: положить коллайдер, запустить сцену, посмотреть, скользит ли ящик и срабатывает ли монета, поправить, повторить. Всё, что добавляет шаг между изменением значения и результатом — сборка, повторный импорт, переключение контекста, — замедляет и саму настройку.
Egmatic построен вокруг этого цикла. Его редактор 2D-сцен позволяет поместить твёрдое тело, задать форму коллайдера, превратить фигуру в триггер, а затем запустить сцену и сразу почувствовать контакт. Поскольку физика, композиция сцены и игровая логика, реагирующая на события столкновений, живут в одном инструменте с живым предпросмотром, путь от «монета не сработала» до «триггер срабатывает, и монета исчезает» занимает секунды, а не цикл сборки. Более подробно о том, зачем нужен быстрый цикл предпросмотра, рассказывает гид про редактор физики в реальном времени.
Вывод
Три примитива — основа всей 2D-физики. Твёрдые тела — это движущиеся объекты, разделённые на динамические, статические и кинематические по тому, как они должны откликаться на мир. Коллайдеры — это твёрдые фигуры, заставляющие тела соприкасаться и блокировать друг друга, настраиваемые трением и упругостью. Триггеры — это чувствительные фигуры, фиксирующие пересечение без блокировки и обеспечивающие работу любого подбираемого предмета, зоны обнаружения и чекпоинта. Свяжите их событиями столкновений для логики и слоями для фильтрации, держите на фиксированном шаге с непрерывным обнаружением для всего быстрого — и вы получите полный словарь 2D-физических взаимодействий. Названия меняются от движка к движку, но идеи — тело, коллайдер, триггер — остаются неизменными.
Источники
- Три типа твёрдого тела (динамическое, статическое, кинематическое) и различия в реакции на гравитацию и столкновения — документация Box2D: Bodies, руководство Unity: типы тел Rigidbody 2D
- Триггер (sensor) — это фигура, фиксирующая пересечение, но не создающая отклика на столкновение — документация Box2D: Sensors
- События столкновений и триггеров (вход / удержание / выход) для 2D-контакта — руководство Unity: события Collider2D (OnCollisionEnter2D, OnTriggerEnter2D)
- Узлы 2D-физики Godot: RigidBody2D, StaticBody2D, AnimatableBody2D, CharacterBody2D, CollisionShape2D и Area2D как узел-триггер — документация Godot: физика в 2D
- Сигналы body_entered / body_exited / area_entered в Godot для обнаружения контакта и пересечения — документация Godot: работа с Area2D
- Физика должна работать на фиксированном шаге, независимом от частоты кадров — руководство Unity: время и фиксированный шаг, Glenn Fiedler, Fix Your Timestep!
- Непрерывное обнаружение столкновений не даёт быстрым объектам пролетать сквозь тонкие поверхности — Box2D на GitHub
- Слои и маски столкновений для фильтрации взаимодействующих тел — руководство Unity: обнаружение столкновений по слоям, документация Godot: слои и маски столкновений