Unity协程内部时间错误

时间:2019-09-22 11:54:14

标签: c# unity3d coroutine

我在动画作品中使用协程。而且我必须确保时机完美。例如,我需要增加超时值,设置时间和stepCount来执行此操作。我的代码如下:

IEnumerator ScaleDown(float time)
{
    print(Time.time);
    float value = 0f;
    float deltaValue = 1 / (stepCount*time);
    float deltaTime = 1/stepCount;
    while (value < 1f)
    {
        value += deltaValue;
        meshRenderer.SetBlendShapeWeight(1, value * 100f);
        yield return new WaitForSeconds(deltaTime);
    }
    print(Time.time);
}

因此,当我设置time = 1f和stepCount = 1时,开始打印和结束打印之间的实时时间为1秒。 但是,当我将stepCount增加到100或更多时,保持时间= 1时,实时时间将超过1秒。 关于〜1.67f

所以我有一个问题:如何使用带有特定stepCount的协程并拥有完美的计时?我使用stepCount在blenshape,着色器变量(如不透明度)上实现更平滑的过渡。并且必须使用stepCount> = 100。

1 个答案:

答案 0 :(得分:0)

  

我使用stepCount在blenshape,着色器变量(如不透明度)上实现更平滑的过渡。并且必须使用stepCount> = 100。

这些步骤都将在1秒内完成... 但是

您的代码以特定的{strong>帧速率最佳方式运行,60 f/s(在PC上,在编辑器中通常更高),这导致Time.deltaTime的“标准” {两帧之间的{1}}!

0.017 seconds

或通常使用yield return new WaitForSeconds(XY); 任何内容等待至少一帧

因此,当然,yield变小时,您的功能就会中断,然后实际可能的帧速率和两帧之间的实时时间就会中断。尤其是例如当您说要每秒deltaTime次执行此操作时。

比帧速率更频繁地更新值也是没有意义的,因为用户不会比实际渲染帧更快地注意到任何变化。

另外>=100可能是一个性能密集的调用(不说实话),因此也可能减慢执行速度,从而导致额外的延迟。


  

如何使用带有特定stepCount的协程并具有完美的计时

超出一定限制,您将无法做到。

但是,为什么您需要/想要对SetBlendShapeWeight 全部使用固定的步骤?

由于valuevalue,而您实际上想要的是一个相当平滑的过渡,您只需要做

float

我仍然想以另一种方式伪造它,并以固定的步长更新IEnumerator ScaleDown(float duration) { print(Time.time); timePassed = 0f; do { // a linear interpolated value between 0 and 1 var value = timePassed / duration; // optionaly you could even add some ease-in and ease-out //value = SmoothStep(0, 1, value); meshRenderer.SetBlendShapeWeight(1, value * 100f); // increase by the time passed since last frame // to avoid overshooting use Mathf.Min with the remaining difference // between duration and passedTime timePassed += Mathf.Min(duration - timePassed, Time.deltaTime); yield return null; } while (timePassed < duration); print(Time.time); } <帧速率,您可以简单地将平滑过渡的值四舍五入为该值,例如

stepCount

应该向上或向下舍入到value = Mathf.Round(value / deltaValue)) * deltaValue; 的下一个完整步骤。


还要注意,在newer Unity版本中,deltaValue不再像在previous versions中那样自动限制在SetBlendShapeWeight范围内。< / p>

尽管如此,大多数3D建模程序在Unity中导出的范围为[0; 100]的模型

  

BlendShape权重范围包括模型中定义的最小和最大权重之间的值。