Проблема в том, что вы никогда не достигнете цели.
Ваш рывок с коэффициентом
currentMovementTimeF / totalMovementTimeF
не имеет особого смысла, поскольку вы сбрасываете каждый кадр на
var currentMovementTimeF = Time.deltaTime;
, что в большинстве случаев будет < 0.3f
(это будет означать, что у вас будет только около 3 кадров в секунду), поэтому оно всегда будет
currentMovementTimeF < totalMovementTimeF
и, следовательно,
currentMovementTimeF / totalMovementTimeF < 1
Таким образом, вы всегда начинаете новую интерполяцию между текущей позицией и целью.Таким образом, расстояние становится все меньше и меньше, но буквально никогда не достигает конечной позиции на самом деле (хотя это кажется так).
Кроме того, вы смешали position
и localPosition
, поэтому, если GameObject
не находится на корневом уровне, становится еще хуже!
То, что вы хотите вместо этого, вероятно, либоиспользуя MoveTowards
с определенным speed
.(на основе позиции)
// adjust these in the Inspector
public float speed;
public float MoveDistance;
public IEnumerator Move(Vector3 direction)
{
var destinaton = transform.position + direction * MoveDistance;
while (Vector3.Distance(transform.position, destinaton) > 0)
{
transform.position = Vector3.MoveTowards(transform.position, MoveDistance, Time.deltaTime* speed);
yield return null;
}
}
MoveTowards
обеспечивает отсутствие перерегулирования.
или использование Lerp (на основе времени), например
// adjust these in the Inspector
public float totalMovementTime = 0.3f;
public float MoveDistance;
public IEnumerator Move(Vector3 direction)
{
var originalPosition = transform.position;
var destination = transform.position + direction * MoveDistance;
// here you could make it even more accurate
// by moving allways with the same speed
// regardless how far the object is from the target
//var moveDuration = totalMovementTime * Vector3.Distance(transform.position, destinaton);
// and than replacing totalMovementTime with moveDuration
var currentDuration = 0.0f;
while (currentDuration < totalMovementTime)
{
transform.position = Vector3.Lerp(originalPosition, destination, currentDuration / totalMovementTime);
currentDuration += Time.deltaTime;
yield return null;
}
// to be really sure set a fixed position in the end
transform.position = destinaton;
}
Другойпроблема в том, что в настоящее время вы все еще можете запустить две сопрограммы, которые ведут к странному поведению.Вам лучше либо прерывать сопрограммы каждый раз, когда вы запускаете новую, например
if (currentSwipe.y > 0 && currentSwipe.x > -0.5f && currentSwipe.x < 0.5f)
{
// stop all current routines
stopAllCoroutines();
StartCoroutine(MoveForward());
}
, либо добавлять флаг, чтобы запустить только одну подпрограмму, и игнорировать ввод за это время:
private bool isSwiping;
public IEnumerator MoveForward()
{
if(isSwiping)
{
Debug.LogWarning("Already swiping -> ignored", this);
yield break;
}
isSwiping = true;
//...
isSwiping = false;
}