Добавление компонента 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":
Итоговый скрипт. На скрине представлен не весь скрипт, а только внесенные изменения по определению положения персонажа: