Как реализовать lerp для плавного движения - PullRequest
1 голос
/ 18 июня 2019

Я хочу достичь движущегося объекта по оси x только с помощью lerp, чтобы получить плавное движение.

это картинка, которая мне нужна

enter image description here

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

Этомой рабочий код, который телепортирует игрока:

void Start()
{

}


void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Vector3 desiredPos = new Vector3(transform.position.x + 1.5f, transform.position.y, transform.position.z);
        transform.position = desiredPos;
    }

    if (Input.GetMouseButtonDown(1))
    {
        Vector3 desiredPos = new Vector3(transform.position.x -1.5f, transform.position.y, transform.position.z);
        transform.position = desiredPos;
    }
}

Я хочу реализовать это, но я не понимаю, как это сделать .. Когда я помещаю весь код в обновление, плеер даже не двигается ..работает только для меня, когда я копирую, вставляю весь код из документов, но как я могу перемещать время от метода запуска к обновлению и всегда делать то же самое, чтобы добиться плавного движения для игрока при движении влево и вправо, я не знаю, на самом делеПожалуйста, помогите мне, ребята ..

Это код, который работает, но я не знаю, как изменить его для моего примера ..

https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

Ответы [ 2 ]

2 голосов
/ 18 июня 2019

Есть несколько способов.Я бы не использовал Translate, поскольку это дает вам небольшой контроль, а, например, MoveTowards, который гарантирует, что у вас нет перестрелки в конце.Используйте это для линейного движения с заданной moveSpeed ​​:

// set move speed in Units/seconds in the Inspector
public float moveSpeed = 1f;

private Vector3 desiredPos;
private bool isMoving;

private void Update()
{
    if (!isMoving && Input.GetMouseButtonDown(0))
    {
        desiredPos = transform.position + Vector3.right * 1.5f;
        isMoving = true;
    }

    if (!isMoving && Input.GetMouseButtonDown(1))
    {
        desiredPos = transform.position - Vector3.right * 1.5f;
        isMoving = true;
    }

    if(isMoving)
    {
        transform.position = Vector3.MoveTowards(transform.position, desiredPos, moveSpeed * Time.deltaTime);

        // this == is true if the difference between both
        // vectors is smaller than 0.00001
        if(transform.position == desiredPos)
        {
            isMoving = false;

            // So in order to eliminate any remaining difference
            // make sure to set it to the correct target position
            transform.position = desiredPos;
        }
    }
}

Или, как вы просили, используйте Vector3.Lerp, например,

// a factor between 0 and 1
[Range(0, 1)] public float lerpFactor;

...

transform.position = Vector3.Lerp(transform.position, desiredPos, lerpFactor);

lerpFactor должно быть значением от 0 до 1, где в нашем случае 0 означает, что объект никогда не перемещается, а 1 напрямую переходит на целевую позицию.Другими словами, чем ближе вы установите его на 0, тем медленнее он достигнет цели, чем ближе вы установите на 1, тем быстрее он достигнет цели.

многие люди делают это дляполучить "плавные" движения, но на самом деле происходит, например, если вы установите 0.5 для lerpFactor, то каждый кадр, в котором объект находится посередине между текущей позицией и целевой позицией.

Это выглядит как-то плавно, движетсяочень быстрый в начале и очень очень медленный в конце ... но: на самом деле он никогда не достигает целевой позиции, а просто становится очень медленным.

Для вашего случая это хорошо, так как в любом случае мы сравниваем ток ицелевое положение с использованием == с точностью до 0.00001.Нужно просто иметь в виду, как работает Lerp.

Но при этом вы не будете иметь никакого контроля ни над скоростью перемещения, ни над продолжительностью.


Если вы хотите в целом больше контроля (как и я) Я бы порекомендовал использовать Coroutine (он не является абсолютно необходимым, и вы могли бы сделать то же самое в Update, но на мой взгляд, сопрограммы лучше поддерживать и отслеживать).

Чем вы могли бы также сделать плавное ускорение и замедление с постоянной фиксированной продолжительностью независимо от того, как далеко расстояние

// set desired move duration in seconds
public float moveDuration = 1;

private bool isMoving;

privtae void Update()
{
    if (!isMoving && Input.GetMouseButtonDown(0))
    {
        StartCoroutine(transform.position + Vector3.right * 1.5f, moveDuration);
    }

    if (!isMoving && Input.GetMouseButtonDown(1))
    {
        StartCoroutine(transform.position - Vector3.right * 1.5f, moveDuration);
    }
}

private IEnumerator Move(Vector3 targetPosition, float duration)
{
    if(isMoving) yield break;

    isMoving = true;

    var startPosition = transform.position;
    var passedTime = 0f;

    do
    {
        // This would move the object with a linear speed
        var lerpfactor = passedTime / duration;

        // This is a cool trick to simply ease-in and ease-out
        // the move speed 
        var smoothLerpfactor = Mathf.SmoothStep(0, 1, lerpfactor);

        transform.position = Vector3.Lerp(startPosition, targetPosition, smoothLerpfactor);

        // increase the passedTime by the time 
        // that passed since the last frame
        passedTime += Time.deltaTime;

        // Return to the main thread, render this frame and go on
        // from here in the next frame
        yield return null;

    } while (passedTime < duration);

    // just like before set the target position just to avoid any
    // under shooting
    transform.position = targetPosition;

    isMoving = false;
}

, и вы могли быпродолжайте расширять этот пример, чтобы использовать dtsnace для учета, например,

var actualDuration = duration * Vector3.Distance(startPosition, targetPosition);

, а затем повсеместно использовать actualDuration.

1 голос
/ 18 июня 2019

Используйте transform.Translate вместо:

public float moveSpeed = 3f;

void Update ()
{

//Moves Left and right along x Axis              
transform.Translate(Vector3.right * Time.deltaTime * Input.GetAxis("Horizontal")* moveSpeed);      
}
...