Проблема
Вы хотите, чтобы тело вашего персонажа взаимодействовало с твердыми телами.
Решение
По умолчанию, CharacterBody2D
, перемещаемый с помощью move_and_slide()
или move_and_collide()
, не будет толкать RigidBody2D
, с которым сталкивается. Твердое тело не реагирует и ведет себя как StaticBody2D
.

В некоторых случаях этого может быть достаточно. Однако, если вы хотите, чтобы тела можно было толкать, потребуется внести изменения.
Для этого примера мы используем 2D-персонажа, описанного в рецепте платформера. В этом примере применяется самый распространенный метод движения для тел персонажей: move_and_slide()
. Если вы используете move_and_collide()
, вам нужно будет адаптировать примеры ниже.
У вас есть два варианта взаимодействия с твердыми телами:
- Вы можете просто толкать их, игнорируя физику. Если вы знакомы с Godot 3.x, это эквивалентно опции «бесконечная инерция».
- Вы можете толкать их, основываясь на «массе» и скорости персонажа. Это даст «реалистичный» результат — тяжелые тела будут двигаться медленно, а легкие — быстрее.
Мы рассмотрим оба варианта ниже.
Бесконечная инерция
У этого варианта есть свои плюсы и минусы. Главный плюс — вам не нужно писать дополнительный код. Достаточно правильно настроить слои и маски коллизий объектов. В этом примере мы определили три физических слоя:


Для твердого тела мы разместили его на слое «предметы» (слой 3) и оставили маску по умолчанию (маскирует все слои).
Проверь свои знания в нашем бесплатном ТЕСТЕ по Godot! Узнай, насколько хорошо ты его знаешь!


Для игрока мы разместили его на слое «игрок» (слой 2) и настроили маску так, чтобы игнорировать слой «предметы».


Запустив игру, мы видим, что можем толкать коробки. При этом масса коробки не имеет значения — все они будут двигаться одинаково.

Здесь также виден минус этого варианта. Поскольку физика коробок игнорируется, они могут проходить сквозь стены, и на них нельзя запрыгнуть.
Для некоторых игр это подойдет. Если вы хотите избежать прохождения сквозь стены, нужно выбрать второй вариант.
Применение импульсов
Чтобы придать сталкивающемуся телу «толчок», нужно применить импульс. Импульс — это мгновенный «удар», как при ударе биты по мячу. Это отличается от силы, которая представляет собой постоянное «давление» на объект.
# This represents the player's inertia.
var push_force = 80.0
func _physics_process(delta):
# after calling move_and_slide()
for i in get_slide_collision_count():
var c = get_slide_collision(i)
if c.get_collider() is RigidBody2D:
c.get_collider().apply_central_impulse(-c.get_normal() * push_force)
Нормаль коллизии указывает направление от твердого тела, поэтому мы меняем ее направление на противоположное и применяем коэффициент push_force
. Теперь толкание снова работает, но твердые тела не будут проходить сквозь стены:

Вам нужно будет настроить push_force
в зависимости от массы ваших твердых тел. Слишком большая сила все еще может вызывать прохождение сквозь стены, а слишком маленькая — не позволит толкать тела.
Экспериментируйте, чтобы найти настройки, которые подходят для вашей игры.