#c# #unity3d #coroutine #ienumerator
#c# #unity3d #сопрограмма #ienumerator
Вопрос:
У меня странная проблема при использовании a Vector3.Lerp
внутри сопрограммы, и это не имеет смысла, потому что в моей игре много сопрограмм, и все они работают нормально.
ЧЕГО Я ПЫТАЮСЬ ДОСТИЧЬ
Я просто пытаюсь переместить объект с начальной высоты на конечную высоту с помощью вызываемой сопрограммы InVolo()
и простого Vector3.Lerp
изменения положения объекта.
МОЙ КОД
float elapsedTime = 0f;
while (elapsedTime < TempoSalita)
{
transform.position = Vector3.Lerp(transform.position,
new Vector3(transform.position.x, maxHight, transform.position.z), (elapsedTime / TempoSalita));
elapsedTime = Time.deltaTime;
yield return null;
}
transform.position = new Vector3(transform.position.x, maxHight, transform.position.z);
yield return null;
Это maxHight
просто 4f и TempoSalita
2f . Сопрограмма запускается в OnTriggerEnter и работает нормально, объект достигает y 4f и завершает работу через 2 секунды.
ПРОБЛЕМА
В принципе, elapsedTime / TempoSalita
становится 1 через 2 секунды, как и должно быть, но объект достигает конечной позиции примерно через 0,3 секунды, когда elapsed/TempoSalita
это 0,2, и для меня это не имеет смысла. Vector3.Lerp должен переходить от startpos к endpos за время, пока значение t изменяется с 0 на 1. Но он переходит в конечную позицию через 0,2 секунды, и я понятия не имею, почему.
ЧТО я ПРОБОВАЛ
Я попытался Debug.Log
использовать прошедшее время, и оно меняется нормально, пытался использовать только Mathf.Lerp
между значениями y, и это делает то же самое. В этом скрипте больше нет ничего, что могло бы повлиять на это, так запускается сопрограмма:
void OnTriggerEnter(Collider other)
{
if(other.CompareTag("Saltino"))
{
StartCoroutine(InVolo());
}
}
Он запускается только один раз. Знаете ли вы, что может вызвать эту странную проблему?
Комментарии:
1.
Vector3.Lerp should go from startpos to endpos
да, но вы всегда используете текущую позицию как startpos => вы интерполируете из уже продвинутой позиции, а остальная часть «анимации» просто движется очень медленно, поскольку начальная и конечная позиции сближаются
Ответ №1:
Это может быть условие, которое вы используете, которое кажется мне немного подозрительным.
Обычно я бы написал это немного по-другому, что-то вроде..
var t = 0f;
var start = transform.position;
var target = new Vector3(transform.position.x, maxHight, transform.position.z);
while (t < 1)
{
t = Time.deltaTime / TempoSalita;
if (t > 1) t = 1;
transform.position = Vector3.Lerp(start, target, t);
yield return null;
}
Сначала вы создаете свои начальные и целевые значения, прежде чем изменять позицию. Значение t будет увеличиваться до тех пор, пока не достигнет (или не пройдет) 1. Поскольку мы не хотим, чтобы t превышало 1, мы выполняем проверку перед применением lerp. Наше значение t вычисляется вне lerp, чтобы сделать его понятным и простым для чтения / изменения.
Вышеуказанное будет выполняться в течение указанного времени и не требует дополнительных строк в конце, поскольку t в конечном итоге будет ровно 1.
Комментарии:
1. Я не уверен, почему это работает, но, БОЖЕ, это работает, спасибо!
2. @Leoverload чтобы узнать больше о lerp и о том, как работает этот код, вы можете обратиться к этой замечательной статье: chicounity3d.wordpress.com/2014/05/23/how-to-lerp-like-a-pro
3. @Leoverload Прошу прощения; Я действительно не знаю.
4. Проблема вовсе не в условии, а в том, что OP всегда использует текущую позицию в качестве начального значения для
Lerp
=> Начальная и конечная позиции с каждым разом становятся ближе друг к другу => в остальной части цикла объект просто перемещается очень маленькими шагами5. Понял, спасибо, Дарт @derHugo мудрый: D