什么是FixedTimeDelta实际代表什么?

时间:2018-01-31 13:06:03

标签: unity3d

我想让unity3D每隔n毫秒调用一个函数 。我们将n设置为20

创建一个全新的空白Unity3D项目。

.Net version更改为4(文件>构建设置>播放器设置>其他设置>配置)

创建一个新脚本并添加以下内容:

System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
private void FixedUpdate()
{
    Debug.Log(sw.ElapsedMilliseconds);
    sw.Restart();
}

点击播放。

你会看到你混合zeros, 29's and 30's ...... 现在转到TimeManager(编辑>项目设置>时间)

Maximum Allowed Timestep更改为匹配Fixed Timestep(0.02)。

再次点击播放。

现在你会看到没有更多的零,但仍然在30ms左右。

我知道Unity中有Time.fixedDeltaTime,但FixedUpdate是否应该每20毫秒调用一次,而不是29/30毫秒?如果将TimeManager中的所有属性设置为1,情况会更糟:现在我们看到大量(> 10ms)差异。

发生了什么事?为什么FixedUpdate的调用晚于Unity3D所说的?

1 个答案:

答案 0 :(得分:4)

首先,你不能在计算毫秒数时使用Debug.Log方法,这个方法本身执行起来很慢,所以你应该创建一个保存在List内的脚本时间,然后在控制台中打印它们。像这样:

using UnityEngine;
using System.Collections.Generic;

public class Fixedtest : MonoBehaviour {

    List<long> myList = new List<long>();
    System.Diagnostics.Stopwatch sw;
    int i = 0;
    bool hasCountFinished = false;

    private void Start() {
        Time.fixedDeltaTime = 0.02f;            
        QualitySettings.vSyncCount = 0;
        sw = System.Diagnostics.Stopwatch.StartNew();
    }

    private void FixedUpdate() {
        sw.Stop();
        if (i<100) {            
            myList.Add(sw.ElapsedMilliseconds);     
            i++;
            sw.Restart();
        }
    }

    private void Update() {
        if (!hasCountFinished && i>=100) {
            hasCountFinished = true;
            foreach (long myLong in myList) {
                Debug.Log(myLong);
            }
        }
    }
}

请注意,我设置了vSync,这是为了告诉Unity NOT等待一个通常为16毫秒(60赫兹)的完整刷新周期,因此即使你在将fixedDeltaTime设为0.2。

如果你使用这个脚本,你会发现列表中的大部分结果大约是20ms,显然由于引擎的其他组件会导致差异,执行时间为{{1等等。

修改

第一个结果(一些0然后是一个高于300毫秒的峰值)是由于Unity按下播放(序列化等)时所做的场景准备,它们完全正常,你可以&#39;做任何事情。

然后其他结果,正如我所说,取决于很多因素,即单行代码的执行时间,由于你的操作系统正在为Unity线程分配时间而可能会有所不同流程仍在运行

请注意sw.Restart()以这种方式运作:当您设置fixedDeltaTime时,让我们假设您以{30}的刷新率保持vSync。这意味着您希望物理引擎每20毫秒运行一次更新,无论您使用的是什么刷新率。

但是物理引擎在Unity的主游戏循环中运行,所以它可以执行零,每帧一次或多次执行。因此,在我们的示例中,会发生这种情况:

第1帧:修正更新,更新

游戏循环等待以完成单个刷新率,33ms。

第2帧:自上次固定更新以来已经过去了33ms,执行了一次固定更新和一次更新。

其他33毫秒等待。

第3帧:现在,自第一个帧以来,已经过了66ms,物理引擎应该从第2帧(66/20 = 3.3)更新三次,但直到现在它已执行只需一次,因此Unity将执行固定更新两次,以保持fixedDeltaTime = 0.2f设置的一致性。

这就是为什么,当你在原始测试代码中保持fixedDeltaTime时,你得到了那些结果,有时是16ms,有些则是33ms,因为16&lt; 20有时固定更新不会在单一游戏循环,但每两个游戏循环一次。