Взаимодействие персонажа с твердым телом

Проблема

Вы хотите, чтобы тело вашего персонажа взаимодействовало с твердыми телами.

Решение

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

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

Для этого примера мы используем 2D-персонажа, описанного в рецепте платформера. В этом примере применяется самый распространенный метод движения для тел персонажей: move_and_slide(). Если вы используете move_and_collide(), вам нужно будет адаптировать примеры ниже.

У вас есть два варианта взаимодействия с твердыми телами:

  1. Вы можете просто толкать их, игнорируя физику. Если вы знакомы с Godot 3.x, это эквивалентно опции «бесконечная инерция».
  2. Вы можете толкать их, основываясь на «массе» и скорости персонажа. Это даст «реалистичный» результат — тяжелые тела будут двигаться медленно, а легкие — быстрее.

Мы рассмотрим оба варианта ниже.

Бесконечная инерция

У этого варианта есть свои плюсы и минусы. Главный плюс — вам не нужно писать дополнительный код. Достаточно правильно настроить слои и маски коллизий объектов. В этом примере мы определили три физических слоя:

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

Для игрока мы разместили его на слое «игрок» (слой 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 в зависимости от массы ваших твердых тел. Слишком большая сила все еще может вызывать прохождение сквозь стены, а слишком маленькая — не позволит толкать тела.

Экспериментируйте, чтобы найти настройки, которые подходят для вашей игры.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

два + девятнадцать =

Прокрутить вверх