为了账号安全,请及时绑定邮箱和手机立即绑定

Unity 协程中的时间错误

Unity 协程中的时间错误

C#
白衣非少年 2023-12-17 21:10:58
我在动画工作中使用协程。我必须确保时机是完美的。例如,我需要加班增加价值。我设置了 time 和 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 或更多保持 time=1 时,则实时时间超过 1 秒。 大约 ~1.67f所以我有一个问题:我怎样才能使用具有特定 stepCount 的协程并拥有完美的时序?我使用 stepCount 在 blenshapes、着色器变量(如不透明度)上实现更平滑的过渡。并且必须使用 stepCount>=100。
查看完整描述

1 回答

?
一只名叫tom的猫

TA贡献1906条经验 获得超3个赞

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

这些步骤都将在第二秒发生......但是1

您的代码以一定的最佳帧速率运行(在 PC 上和编辑器中大多更高),这导致“标准”大约在两帧之间!60 f/sTime.deltaTime0.017 seconds

yield return new WaitForSeconds(XY);

或者一般来说,任何使用的东西都会至少等待一帧yield

因此,当然,一旦变得比实际可能的帧速率和两帧之间的实时时间更小,您的功能就会中断。特别是例如,当您说您希望每秒执行几次时。deltaTime>=100

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

此外,可能是一个性能密集型调用(老实说不知道),因此它也可能减慢执行速度,从而导致额外的延迟。SetBlendShapeWeight


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

超过一定限度,你就做不到。

但是,为什么您需要/想要使用固定步骤呢?value

既然是一个,而且看起来你真正想要的是一个平稳的过渡,你可以简单地做valuefloat

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;

应向上或向下舍入到 的下一个完整步骤。deltaValue


另请注意,在较新的 Unity 版本中,不再像以前版本那样自动限制在范围内。SetBlendShapeWeight[0; 100]

不过,大多数 3D 建模程序都会导出具有 Unity 中范围的模型[0;100]

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


查看完整回答
反对 回复 2023-12-17
  • 1 回答
  • 0 关注
  • 158 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信