我知道如果在update()
中做了太多事情,结果会导致帧速率降低到目标帧速率以下。但如果我在fixedUpdate()
做同样的事情会怎么样?
它会导致Unity的物理引擎陷入困境,还是会导致程序崩溃?
答案 0 :(得分:3)
答案和评论非常有用,但他们对我的问题缺乏清晰,信息丰富的答案。每个人都知道当你在FixedUpdate()
循环中加载太多工作时会发生不好的事情,我的问题是要问那时会发生什么坏事。
自从我终于拿到电脑后,我决定自己做一些测试。仅供参考,这是我以前测试的:
public class TestFixedUpdate : MonoBehaviour {
public int loopNo = 500000;
private int noOfCall = 0;
private int collisionTimes = 0;
private void FixedUpdate()
{
if (noOfCall > 100) return;
float time = Time.timeSinceLevelLoad;
for (int i = 0; i < loopNo; i++) {
Quaternion.Slerp(Quaternion.identity, Quaternion.FromToRotation(Vector3.up, Vector3.forward), Mathf.Abs(Mathf.Sin(Time.timeSinceLevelLoad)));
}
Debug.Log(Time.timeSinceLevelLoad.ToString("0.00"));
if (noOfCall > 99) Debug.Log("Simulation finished. Times collided:" + collisionTimes);
noOfCall++;
}
private void OnCollisionEnter(Collision collision)
{
if (noOfCall > 100) return;
collisionTimes++;
Debug.Log("Times collided:" + collisionTimes);
}
}
我把它放在一个不断在飞机上反弹的球体上。通过更改FixedUpdate()
和Update()
的函数并比较差异来进行测试。
我发现的主要区别是,在FixedUpdate()
的情况下,Unity模拟Time
(游戏世界的时间)延迟与实际时间不同步。换句话说,任何依赖于Unity Time
系统的函数都会表现得好像整个世界都在放慢速度。
此外:
Unity报告两种情况的帧速率相同,即使对于FixedUpdate()
情况,显然实际帧速率 - 每个真实世界的帧数 - 显着降低。
除了减速,碰撞检测和物理模拟逻辑似乎正常工作。应该碰撞的尸体仍然碰撞;加速,施力等仍然有效。在20毫秒内没有跳过对撞机的刚体(Unity&#39; s ms)仍然像往常一样碰撞并反弹。
项目设置中的Maximum Allowed Timestep
选项定义了必须绘制帧之前(Unity的模拟时间)的最大数量(我以前从未知道它的用途) 。澄清:如果我将其设置为0.5秒,那么无论我将两个函数放入多少代码,都会在Update()
轮模拟0.5-后立即调用逻辑更新步骤(FixedUpdate()
)第二个,然后场景将被渲染。
答案 1 :(得分:0)
在任何函数内部处理重负载(例如,如果执行无限循环)时,引擎将停止。如果帧速率下降得太低,依赖于Time.DeltaTime的事情将开始起作用。无论是更新还是使用FixedUpdate都无关紧要。
如果你需要一个运行重负载的过程,你可以做的是使用协同程序,例如IEnumerator函数和yield,允许您在多个帧上拆分处理,或者通过回调调用某些函数。例如如果您有一个AI检查路径,每秒5次,您可以使用每个帧的计数器处理更新,或者您可以安排回调。
基本上,在不降低性能的情况下,每帧可以运行多少代码会受到限制。聪明的重写应该使这不必要。看看你是否可以缓存计算结果或预先计算尽可能多的数据。