2

我正在使用 Mathf.Lerp 为圆形进度条设置动画。

进度条是一个具有名为“FillAmount”的属性的图像:

0 means not filled
1 means filled

连同填充属性“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?

在此处输入图像描述

4

3 回答 3

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;

这样你的循环仍在处理动画,当你的函数结束时,你保证它以正确的值结束。

于 2018-11-19T21:19:31.373 回答
2

大概是在for循环中。查看它是如何执行的:最初,t设置为0.01. 健康栏发生了一些变化。然后,t增加Time.deltaTime。例如,它恰好是0.17。现在t等于0.18和循环继续运行。

但是当另一个增量t大于或等于之后fFade,程序将退出循环而不改变健康条。在我的示例中,最后处理的数字将是0.18.

如何解决这个问题?您应该fillAmount在循环之后立即设置为 fNew。

于 2018-11-19T21:21:20.580 回答
0

而不是使用for循环。使用while循环。因此您的代码会一直运行,直到达到所需的值。

现在你是基于时间而不是基于期望的结果退出。您仍然可以运行每一帧并按时间设置动画,但您不应根据运行时间停止代码。

此外,退出循环时也可能值得钳制/设置该值。将其设置为您在函数中输入的参数(或fNew在您的情况下)。

于 2018-11-21T12:46:00.170 回答