1

好的,所以我有一个动画,其速度由用户点击 m 来控制,这意味着我不能只在设定的时间内放松,但必须取决于这是否属实:

cameraAnim.GetCurrentAnimatorStateInfo (0).IsName ("stillOpening")

在这个动画结束时(不管它花了多长时间,快或慢)我需要在我的材质中使用这个浮点数来达到它的最终值:

skybox.SetFloat ("_Exponent1",Mathf.Lerp(skybox.GetFloat("_Exponent1"), topSkyBoxOpen, ratio));

这意味着它必须等于“stillOpening”末尾的 topSkyBoxOpen。我不知道如何协调时间。

我在 Update() 中试过这个:

void openSkyLerp()
    {
        float ratio = 0;
        float duration = 0.5f; // this is the one that will control how long it takes
        // value is in second 
        float multiplier = 1 / duration;

        while (cameraAnim.GetCurrentAnimatorStateInfo (0).IsName ("stillOpening")) {
            ratio += Time.deltaTime * multiplier;
            skybox.SetFloat ("_Exponent1",Mathf.Lerp(skybox.GetFloat("_Exponent1"), topSkyBoxOpen, ratio));

        }
    }

但什么都没有发生——我读到这可能是因为它试图在一帧中让所有的 lerp 发生。这可能吗?无论动画速度如何,我如何才能在播放动画时感到困惑?

4

1 回答 1

0

这意味着它必须等于“stillOpening”末尾的 topSkyBoxOpen。我不知道如何协调时间。

问题是你甚至没有在等待一帧。所以,即使你的方程是正确的,所有这些也不能在一帧中顺利发生。你等待一个yield return null;需要协程的帧。

几个小时前回答了一个非常相似但不相同的问题。

如果stillOpening变量是目标值,则_Exponent1在进入 while 循环之前获取当前值。有一个计数器变量,当计数器小于 时每帧递增topSkyBoxOpen。然后就可以Mathf.Lerp(currentVal, topSkyBoxOpen, counter / duration);SetFloat函数中使用了。

bool running = false;

void openSkyLerp()
{
    if (running)
    {
        return;
    }
    running = true;
    StartCoroutine(OpenSky(5));
}

IEnumerator OpenSky(float duration)
{
    float currentVal = skybox.GetFloat("_Exponent1");
    float counter = 0;
    while (counter < topSkyBoxOpen)
    {
        //Exit if not still opening
        if (!cameraAnim.GetCurrentAnimatorStateInfo(0).IsName("stillOpening"))
        {
            yield break;
        }
        counter = counter + Time.deltaTime;

        float val = Mathf.Lerp(currentVal, topSkyBoxOpen, counter / duration);

        skybox.SetFloat("_Exponent1", val);
        yield return null; //Wait for a frame
    }
    running = false;
}
于 2017-01-14T20:58:41.730 回答