Передвинуть объект в Unity

Помогите пожалуйста. Нужен скрипт для 2D игры в Unity. Нужно чтобы при ОДИНОЧНОМ нажатии кнопки персонаж передвигался на n-количество влево (или вправо в зависимости от кнопки). Главная проблема в том, чтобы персонаж не телепортировался, а плавно перемещался.


Ответы (1 шт):

Автор решения: Анастасия

Можно реализовать это, например, так. Повесить на Вашего игрока (который является Rigidbody2D) скрипт PlayerController, в котором прописать такой код:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed;
    private float moveInput;

    private Rigidbody2D rb;

    private void Start()
    {
        rb = GetComponent<Rigidbody2D>(); // инициализируем объект игрока
    }

    private void FixedUpdate()
    {
        moveInput = Input.GetAxis("Horizontal");
        //указываем движение персонажа по горизонтальной оси, в зависимости от указанной Вами скорости, и учитывая направление
        rb.velocity = new Vector2(moveInput * speed, rb.velocity.y); 
    }
}

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

Гляньте этот туториал, тут очень толково всё объясняется. Можно добавить возможность прыжков, поворота персонажа при ходьбе в разные стороны, анимацию хождения и прыжков...

UPDATE С учетом уточнения о том, что персонаж должен плавно перемещаться при одноразовом нажатии на заданную кнопку, код меняется. В таком случае логично использовать Couroutine. Например, так.

void Clicked(bool left)
{
     Vector2 relativeLocation = new Vector2(5, 0); 
     if (left) relativeLocation = new Vector2(-5, 0);
     /* 5 - произвольное число, "расстояние", на которое должен перемещаться персонаж. 
     Можно вынести в public-переменную и играться*/
        
     Vector2 targetLocation = new Vector2(rb.transform.position.x, rb.transform.position.y) + relativeLocation;
     float timeDelta = 0.05f; // время, за которое персонаж должен совершить перемещение
     this.StartCoroutine(SmoothMove(targetLocation, timeDelta));
}

IEnumerator SmoothMove(Vector3 target, float delta)
{
     float closeEnough = 0.2f;
     float distance = (rb.transform.position - target).magnitude;

     WaitForEndOfFrame wait = new WaitForEndOfFrame();
     while (distance >= closeEnough)
     {
         transform.position = Vector2.Lerp(new Vector2(rb.transform.position.x, rb.transform.position.y), target, delta);
         yield return wait;
         distance = (rb.transform.position - target).magnitude;
     }
     rb.transform.position = target;
}

Тогда в FixedUpdate() будет такой код (в примере я использовала кнопки A и S для управления персонажем):

private void FixedUpdate()
{
    if(Input.GetKeyDown(KeyCode.S)) Clicked(false);
    if(Input.GetKeyDown(KeyCode.A)) Clicked(true);
}

Тут ключевой метод - Lerp. Он производит линейную интерполяцию между двумя точками, поэтому движение объекта плавное.

→ Ссылка