C# 统一协同程序中的错误时间
我在动画工作中使用协同程序。我必须确保时间安排是完美的。例如,我需要增加超时值。我设置了时间和步数来执行此操作。我的代码如下所示:C# 统一协同程序中的错误时间,c#,unity3d,coroutine,C#,Unity3d,Coroutine,我在动画工作中使用协同程序。我必须确保时间安排是完美的。例如,我需要增加超时值。我设置了时间和步数来执行此操作。我的代码如下所示: IEnumerator ScaleDown(float time) { print(Time.time); float value = 0f; float deltaValue = 1 / (stepCount*time); float deltaTime = 1/stepCount; while (value < 1f
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);
}
IEnumerator ScaleDown(浮动时间)
{
打印(时间,时间);
浮动值=0f;
浮点增量值=1/(步数*时间);
浮动增量时间=1/步计数;
而(值<1f)
{
值+=增量值;
meshRenderer.SetBlendShapeView(1,值*100f);
收益返回新的WaitForSeconds(deltaTime);
}
打印(时间,时间);
}
所以当我设置时间=1f,步数=1时,开始和结束打印之间的实时时间是1秒。
但当我将stepCount增加到100或更多时,保持时间=1,则实时时间超过1秒。
大约1.67华氏度
所以我有一个问题:我如何使用具有特定步数的协同程序,并拥有完美的时间安排?我使用stepCount在形状、着色器变量(如不透明度)上实现更平滑的过渡。并且必须使用步长计数>=100
我使用stepCount在形状、着色器变量(如不透明度)上实现更平滑的过渡。并且必须使用步长计数>=100
这些步骤都应在1
秒内完成但是:
您的代码以特定的帧速率运行,大约60 f/s
(在PC上和编辑器中,帧速率通常更高),这会导致两帧之间的“标准”时间。deltaTime
约为0.017秒
yield return new WaitForSeconds(XY);
或者通常使用yield
的任何东西都至少等待一帧
因此,当deltaTime
小于实际可能的帧速率和两帧之间的实时性时,您的功能就会中断。尤其是当您说希望每秒执行100次时
更新值的频率高于帧速率也是没有意义的,因为用户在实际渲染帧时不会更快地注意到任何更改
此外,setblendshapewight
可能是一个性能要求很高的调用(老实说不知道),因此它也可能会减慢执行速度,从而导致额外的延迟
我如何使用具有特定步数的协同程序并具有完美的时间安排 超过一定限度,你就是不能 但是为什么您需要/想要对
值使用固定的步骤呢
因为值
是一个浮动
,而您实际上想要的是一个相当平稳的过渡,您可以简单地执行
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);
}
它应该向上或向下取整到deltaValue
的下一个完整步骤
还请注意,在版本中,setBlendShapeView
不再自动限制在[0;100]
范围内
尽管如此,大多数3D建模程序导出的模型范围为Unity中的[0;100]
混合形状权重范围包括模型中定义的最小权重和最大权重之间的值
您可以尝试改用waitforsecondrealtime
。然而,请注意,若在该帧中由于繁重的计算而出现延迟,那个么当然更新该帧可能需要更长的时间。。这可能是原因吗?请注意,对于小于实际帧速率的值,设置yield return WaitForSeconds
是没有意义的WaitForSeconds
将始终至少等待下一帧,即使t
为0。这适用于所有yield
语句。@Draco18s是的,谢谢您提供的信息。。实际上是有意义的,因为无论如何,yield
至少被调用过一次。谢谢)非常有用,我知道了一些新的东西)@kerkаааAliceаu和аAlex很乐意帮助!如果此答案解决了您的问题,请随时接受
value = Mathf.Round(value / deltaValue)) * deltaValue;