Unity Vector2.Lerp "t" не работает должным образом, это быстро - PullRequest
0 голосов
/ 24 января 2020

Я не могу получить, чтобы положение объекта заняло 20 секунд, чтобы измениться из точки А в В, потому что он движется быстрее, чем должен, но сообщение «Готово» действительно появляется за 20 секунд, как и должно.

Что я пропускаю?

private bool canMove = true;

...

private IEnumerator SmoothMove() {
    canMove = false;
    Vector2 target = new Vector2(transform.position.x + 1.5f, transform.position.y);

    float moveDurationTimer = 0.0f;
    float moveDuration = 20f;

    while (moveDurationTimer < moveDuration) {
        moveDurationTimer += Time.deltaTime;
        transform.position = Vector2.Lerp(transform.position, target, moveDurationTimer / moveDuration);
        yield return null;
    }

    Debug.Log("Ready");
    canMove = true;
}

Я использую сопрограмму, которую я вызываю из Update ().

Редактировать:

Когда я сказал «Я использую сопрограмму, которую я вызываю из Update ()», я должен был быть более точным c, извините:

void Update() {

    if (canMove && Input.GetKeyDown(KeyCode.RightArrow)) {
            StartCoroutine(SmoothMove());
        }
}

Ответы [ 2 ]

1 голос
/ 24 января 2020

Ваша ошибка в том, что Lerp интерполирует между двумя входными значениями!

Вы всегда переходите в новую текущую позицию, поэтому она теперь интерполирует, начиная с нового начала

transform.position = Vector2.Lerp(transform.position, target, moveDurationTimer / moveDuration);

То, что вы хотите сделать, это сохранить начальную позицию и использовать ее вместо

private IEnumerator SmoothMove() 
{
    canMove = false;
    // Store initial value
    var startPos = transform.position;

    Vector2 target = new Vector2(transform.position.x + 1.5f, transform.position.y);

    float moveDurationTimer = 0.0f;
    float moveDuration = 20f;

    while (moveDurationTimer < moveDuration) {
        moveDurationTimer += Time.deltaTime;
        // Lerp using initial value!
        transform.position = Vector2.Lerp(startPos, target, moveDurationTimer / moveDuration);
        yield return null;
    }

    Debug.Log("Ready");
    canMove = true;
}
0 голосов
/ 24 января 2020

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

Example

using System.Collections;
using UnityEngine;

public class Traveler : MonoBehaviour
{
    [SerializeField] private float _movementDuration = 2.0f;
    [SerializeField] private Transform _wayPointOne = null;
    [SerializeField] private Transform _wayPointTwo = null;
    [SerializeField] private float _percentComplete = 0.0f;

    private void Start()
    {
        StartCoroutine(Move());
    }

    private IEnumerator Move()
    {
        var startMoveTime = Time.time;
        while (Time.time - startMoveTime < _movementDuration)
        {
            _percentComplete = (Time.time - startMoveTime) / _movementDuration;
            transform.position = Vector3.Lerp(_wayPointOne.position, _wayPointTwo.position, _percentComplete);
            yield return null;
        }

        transform.position = _wayPointTwo.transform.position;
    }
}

Так как у вас есть спецификация c длительность для движения, вы можете использовать некоторое время l oop в IEnumerator, чтобы отразить ваше transform.position предсказуемым образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...