问题描述
我在协程中使用 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,transform.position.z);
yield return null;
maxHight
只是 4f,而 TempoSalita
是 2f。协程在 OnTriggerEnter 中启动并且工作正常,对象到达 4f 的 y 并在 2 秒内退出 while。
问题
基本上,elapsedtime / TempoSalita
在 2 秒后变为 1,这是应该的,但是对象在 0.3 秒后到达结束位置,此时 elapsed/TempoSalita
为 0.2 并且对我来说完全是无稽之谈。 Vector3.Lerp 应该在 t 值从 0 到 1 的时候从 startpos 到 endpos。但是它到最后在 0.2 秒内定位,我不知道为什么。
我尝试了什么
我尝试 Debug.Log
的 elapsedtime 并且它正在改变,尝试在 y 值之间仅使用 Mathf.Lerp
并且它做同样的事情。该脚本中没有其他内容可以影响它,这就是协程的启动方式:
void OnTriggerEnter(Collider other)
{
if(other.CompareTag("Saltino"))
{
StartCoroutine(InVolo());
}
}
它只开始一次。你知道是什么导致了这个奇怪的问题吗?
解决方法
这可能是您使用的条件对我来说似乎有点可疑。
通常我会写得有点不同,比如..
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。