我正在使用Mathf.Lerp为圆形进度栏设置动画。
进度条是具有名为“ FillAmount”的属性的图像:
0 means not filled
1 means filled
连同Fill属性“ Radial 360”一样,它的作用有点像时钟。
由于某种原因,错过了执行Lerp函数后的最终值,我看不出如何改进该函数以达到预期的结果。
我的圆形进度条是3/4圈,这就是为什么我将uFrom和uTo(介于0和100之间)乘以0.75的原因。
这是我的代码:
public IEnumerator AnimateHealthChange(int uFrom, int uTo)
{
float fFade = 0.25f;
float fOld = ((uFrom * 0.75f) / 100);
float fNew = ((uTo * 0.75f) / 100);
Debug.Log("Changing from " + fOld.ToString() + " to " + fNew.ToString());
for (float t = 0.01f; t < fFade; t += Time.deltaTime)
{
ImageHealthRing.fillAmount = Mathf.Lerp(fOld, fNew, Mathf.Min(1, t / fFade));
yield return null;//
}
Debug.Log("Final filling after for-next-statement: " + ImageHealthRing.fillAmount.ToString());
yield return null;
}
例如,当我调用AnimateHealthChange(0,100)时,得到以下日志输出:
Changing from 0 to 0.75
Final filling after for-next-statement: 0.6807814
我希望最终结果为0.75,而不是0.6807814。
有人看到我的错误,还是我错误地使用了Lerp?
答案 0 :(得分:2)
您的for
循环是一个问题,因为它无法保证:
for (float t = 0.01f; t < fFade; t += Time.deltaTime)
Time.deltaTime
可以是任意数字(取决于游戏的性能和帧速率),并且您使用的是t < fFade
而不是t <= fFade
,因此即使您偶然这样做,以t == fFade
结尾(这是应该正确填充的值),它将跳过循环的迭代。
最简单的解决方案是在循环后添加一个额外的语句,将fillAmount
强制设置为适当的值:
...
yield return null;//
}
ImageHealthRing.fillAmount = fNew;
这样,您的循环仍然可以处理动画,并且当函数结束时,可以保证动画以正确的值结束。
答案 1 :(得分:2)
可能在for
循环中。查看其执行方式:
最初,t
设置为0.01
。 Healthbar有所更改。
然后,t
增加Time.deltaTime
。例如,它恰好是0.17
。现在t
等于0.18
,循环继续运行。
但是,当另一个增量t
大于或等于fFade
时,程序将退出循环,而不会更改运行状况栏。在我的示例中,最后处理的号码为0.18
。
该如何解决?您应在循环后立即将fillAmount
设置为fNew。
答案 2 :(得分:0)
代替使用for
循环。使用while
循环。因此您的代码将运行直到达到所需的值。
现在,您要根据时间而不是根据期望的结果退出。 您仍然可以按时间运行每个帧并设置动画,但是您不应该根据其运行时间来停止代码。
此外,退出循环时,还应该钳位/设置值。将其设置为您在函数中输入的参数(或fNew
)。