在fixedUpdate()中做繁重工作的后果是什么?

时间:2017-02-16 12:16:33

标签: unity3d unity5 unity3d-2dtools

我知道如果在update()中做了太多事情,结果会导致帧速率降低到目标帧速率以下。但如果我在fixedUpdate()做同样的事情会怎么样?

它会导致Unity的物理引擎陷入困境,还是会导致程序崩溃?

2 个答案:

答案 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系统的函数都会表现得好像整个世界都在放慢速度。

此外:

  1. Unity报告两种情况的帧速率相同,即使对于FixedUpdate()情况,显然实际帧速率 - 每个真实世界的帧数 - 显着降低。

  2. 除了减速,碰撞检测和物理模拟逻辑似乎正常工作。应该碰撞的尸体仍然碰撞;加速,施力等仍然有效。在20毫秒内没有跳过对撞机的刚体(Unity&#39; s ms)仍然像往常一样碰撞并反弹。

  3. 项目设置中的Maximum Allowed Timestep选项定义了必须绘制帧之前(Unity的模拟时间)的最大数量(我以前从未知道它的用途) 。澄清:如果我将其设置为0.5秒,那么无论我将两个函数放入多少代码,都会在Update()轮模拟0.5-后立即调用逻辑更新步骤(FixedUpdate())第二个,然后场景将被渲染。

答案 1 :(得分:0)

在任何函数内部处理重负载(例如,如果执行无限循环)时,引擎将停止。如果帧速率下降得太低,依赖于Time.DeltaTime的事情将开始起作用。无论是更新还是使用FixedUpdate都无关紧要。

如果你需要一个运行重负载的过程,你可以做的是使用协同程序,例如IEnumerator函数和yield,允许您在多个帧上拆分处理,或者通过回调调用某些函数。例如如果您有一个AI检查路径,每秒5次,您可以使用每个帧的计数器处理更新,或者您可以安排回调。

基本上,在不降低性能的情况下,每帧可以运行多少代码会受到限制。聪明的重写应该使这不必要。看看你是否可以缓存计算结果或预先计算尽可能多的数据。