Найти тему

Перемещение Dynamic Rigidbody2D

Добавление компонента Rigidbody к игровому объекту позволяет передать движение этого объекта под контроль физического движка Unity. Поскольку физическое тело подвержено влиянию различных сил, то перемещать его необходимо путем прикладывания этих сил к исходному объекту. Причем делать это необходимо в методе FixedUpdate(), так как этот метод вызывается непосредственно перед каждым обновлением физики, поэтому любые сделанные там изменения будут выполняться точно синхронно с самим физическим движком.

Плавное, равномерное перемещение игрового объекта по сцене реализуется с помощью задания ему скорости (velocity) в методе FixedUpdate():

rb.velocity = move;

Для начала давайте определим вектор перемещения для объекта с учетом действий пользователя:

float deltaX = Input.GetAxis("Horizontal");
move.Set(speed * deltaX, 0);

Плавное, равномерное перемещение игрового объекта по сцене реализуется с помощью задания ему скорости (velocity) в методе FixedUpdate(). Например, так можно переместить объект по оси X с определенной скоростью:

rb.velocity = new Vector2(speed, 0);

Скрипт будет выглядеть следующим образом:

Перемещение объекта
Перемещение объекта

Теперь наш объект может перемещаться следующим образом. Обратите внимание, что синей платформе и красному объекту добавлен компонент Collider2D, чтобы объект не улетал вниз.

Если необходимо связать перемещение объекта с пользовательским управлением, то для начала необходимо определить вектор перемещения для объекта с учетом действий пользователя:

float deltaX = Input.GetAxis("Horizontal");
float deltaY = Input.GetAxis("Vertical");
move.Set(speed * deltaX, speed * deltaY);

А затем в методе FixedUpdate() задать скорость персонажу при помощи этого вектора:

rb.velocity = move;

Скрипт будет выглядеть следующим образом:

Перемещение персонажа
Перемещение персонажа

Теперь давайте добавим персонажу прыжок. Для этого уберем вертикальное перемещение персонажа, которое мы заменим на прыжок. И приложим к физическому телу силу, как бы толкнем его вверх:

if (Input.GetAxis("Jump") > 0)
{
rb.AddForce(Vector2.up * jump);
}

Также необходимо внести изменения в определение вектора перемещения - сохранить вертикальную составляющую (координата Y) скорости физического тела, а не обнулять ее. Эта вертикальная появляется, когда мы прикладываем силу для прыжка:

move.Set(speed * deltaX, rb.velocity.y);

Скрипт будет выглядеть следующим образом:

Перемещение и прыжок персонажа
Перемещение и прыжок персонажа

Но если мы оставим код в таком виде, возникнет проблема - персонаж сможет прыгать даже находясь в воздухе. Если игра предполагает такие прыжки, то можно оставить код, как есть. Но мы хотим разрешить персонажу прыгать только в том случае. если он стоит на земле, а не находится в воздухе, давайте внесем следующие изменения.

Во-первых, нам понадобится переменная логического типа (bool), в которой мы будем хранить положение нашего персонажа - на земле или нет.

private bool isGround = true;

Тогда в условие прыжка мы добавим еще дополнительную проверку, что наш персонаж находится на земле и после прыжка сразу же установим переменную нахождения на земле в ложное значение:

if (Input.GetAxis("Jump") > 0 && isGround)
{
rb.AddForce(Vector2.up * jump);
isGround = false;
}

И последнее, что нужно сделать - при соприкосновении с объектом плоскости (землей) установим переменную нахождения на земле в истинное значение:

private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == ("Ground"))
{
isGround = true;
}
}

Обратите внимание, чтобы этот метод сработал необходимо, чтобы плоскости и персонажу был добавлен компонент Collider. А также у плоскости был задан тег "Ground":

Плоскость земли
Плоскость земли

Итоговый скрипт. На скрине представлен не весь скрипт, а только внесенные изменения по определению положения персонажа:

Перемещение и прыжок персонажа
Перемещение и прыжок персонажа