Коллайдеры и форма столкновений

Rigidbody даёт телу физику, но чтобы оно с чем-то сталкивалось, нужна форма. Эту форму задаёт коллайдер.

Суть: Коллайдер (Collider2D) — невидимая форма объекта для физики. BoxCollider2D — прямоугольник, CircleCollider2D — круг, PolygonCollider2D — произвольный контур. Движок проверяет пересечение этих форм, а не картинок. Форма коллайдера не обязана точно повторять спрайт.

Спрайт — это просто картинка, движок про столкновения из неё ничего не знает. Чтобы объект мог во что-то врезаться, ему нужен коллайдер — невидимая геометрическая форма. Герой обычно получает BoxCollider2D или CapsuleCollider2D, мяч — CircleCollider2D, сложный объект — PolygonCollider2D.

Важно: коллайдер и спрайт — разные вещи. Картинка героя может быть детальной, а коллайдер — простым прямоугольником. Это правильно: простые формы считаются быстрее, и игроку не нужна попиксельная точность столкновений.

Как работает под капотом

Самый дешёвый тест столкновения — AABB (Axis-Aligned Bounding Box), пересечение двух прямоугольников. Движок сначала грубо проверяет AABB, и только если они пересеклись, считает точную форму.

AABB-проверка двух прямоугольников:

  A: x[0..2], y[0..2]
  B: x[1..3], y[1..3]

  пересекаются по X?  A.right(2) >= B.left(1)  и  B.right(3) >= A.left(0)  -> да
  пересекаются по Y?  аналогично                                         -> да
  => прямоугольники ПЕРЕСЕКАЮТСЯ (столкновение)

Эта проверка — основа всех 2D-столкновений. Реализуем AABB на Python — именно её движок выполняет миллионы раз:

# Прямоугольник задан центром (cx, cy) и полуразмерами (hw, hh)
def aabb_overlap(a, b):
    acx, acy, ahw, ahh = a
    bcx, bcy, bhw, bhh = b
    overlap_x = abs(acx - bcx) <= (ahw + bhw)
    overlap_y = abs(acy - bcy) <= (ahh + bhh)
    return overlap_x and overlap_y

player = (0.0, 0.0, 0.5, 0.5)     # герой 1x1 в центре
wall   = (0.8, 0.0, 0.5, 0.5)     # стена рядом
coin   = (5.0, 0.0, 0.3, 0.3)     # монета далеко

print("Герой и стена столкнулись?", aabb_overlap(player, wall))
print("Герой и монета столкнулись?", aabb_overlap(player, coin))

Та же логика на Python ▶ — два прямоугольника пересекаются, если расстояние между центрами по каждой оси меньше суммы их полуразмеров. Эта формула лежит в основе физики любой 2D-игры.

Коллайдеры бывают составными: на одном объекте можно повесить несколько коллайдеров, собрав сложную форму из простых. А компонент CompositeCollider2D объединяет коллайдеры тайлмапа в один контур — это оптимизация для уровней.

Частые ошибки

  • Коллайдер без Rigidbody у обоих объектов. Чтобы сработало событие столкновения, хотя бы у одного из участников нужен Rigidbody2D. Два чисто статичных коллайдера событие не дают.
  • Слишком точная форма. PolygonCollider2D с сотней точек на каждом враге сажает производительность. Используй простые формы, где можно.
  • Коллайдер не совпадает с видимым объектом. Игрок «упирается в воздух» — значит коллайдер больше спрайта. Проверь размеры в Scene View (коллайдер рисуется зелёным).

Best practices

  • Выбирай простейшую подходящую форму: Box для платформ, Circle для мячей, Capsule для персонажей.
  • Для персонажа коллайдер часто делают чуть уже спрайта — так движение ощущается отзывчивее.
  • Для тайловых уровней используй CompositeCollider2D — он склеивает тысячи тайлов в один контур.

Итоги: коллайдер — невидимая форма для физики, отдельная от спрайта. Box/Circle/Polygon под разные объекты. В основе столкновений лежит дешёвая AABB-проверка прямоугольников. Держи формы простыми и помни: для события столкновения нужен хотя бы один Rigidbody2D.

Физматериалы: трение и отскок

Сама форма коллайдера говорит, где объект, но не как он себя ведёт при контакте. За это отвечает физический материал (Physics Material 2D) — маленький ассет с двумя главными числами: трением (Friction) и упругостью (Bounciness). Нулевой отскок и высокое трение дадут «ящик», который замирает, едва коснувшись пола. Высокая упругость превратит тот же объект в мячик, скачущий по уровню. Лёд — это коллайдер с почти нулевым трением, по которому герой скользит. Один материал можно навесить на десятки коллайдеров сразу, и поменять «скользкость» всего льда в игре правкой одного ассета. Это ещё один пример фирменного подхода Unity: вынеси повторяющиеся настройки в отдельный переиспользуемый ресурс, а не прописывай их в каждом объекте вручную.

Проверьте себя
1. Должна ли форма коллайдера точно повторять спрайт?
AДа, обязательно попиксельно
BНет, обычно используют простую форму — её быстрее считать
CКоллайдер и спрайт — это одно и то же
DКоллайдер всегда круглый
2. На какой быстрой проверке основано большинство 2D-столкновений?
AНа сравнении цветов пикселей
BНа AABB — пересечении прямоугольников по осям
CНа FPS
DНа тегах