56.物理时间步长与最大允许时间步长

56.性能优化-CPU-物理-时间步长和最大允许时间步长


56.1 知识点

知识回顾:Unity 物理系统的更新机制

Unity 的 3D 物理系统基于 Nvidia 的 PhysX,2D 物理系统基于开源项目 Box2D。
Unity 对它们进行了封装,开发者只需要使用 Unity API 即可驱动物理引擎。

物理系统执行机制中最重要的概念是时间步长(Time Step),在 Unity 中通常称为固定更新时间步长。
它指的是物理世界更新的固定时间间隔,即每隔多长时间更新一次物理逻辑。

默认设置为每 20ms0.02s50Hz)更新一次,可在以下路径设置:
Project Settings -> Time -> Fixed Timestep

注意:
物理逻辑独立于帧率,不以帧为准,而是严格以固定时间步长为准。
一帧内可能执行 0 次、1 次甚至多次物理循环。

举例:

  1. 游戏较流畅,一帧耗时 15ms,该帧物理更新可能不需要执行。
  2. 游戏较卡顿,一帧耗时 40ms,该帧物理更新可能连续执行 2 次。

也就是说,物理更新只以实际经过的时间为准,时间累计到固定时间步长就必须更新一次。
当帧间隔时间过长,物理逻辑需要补满对应的执行次数。

但如果掉帧太严重,会丢弃部分时间片,避免无限补帧。
可在以下位置设置丢弃的时间上限:
Project Settings -> Time -> Maximum Allowed Timestep

示例:读取固定时间步长

float fixedTimeStep = Time.fixedDeltaTime;
Debug.Log($"Fixed Timestep = {fixedTimeStep}s");

降低物理步频

时间步长决定了单位时间内物理系统更新的频率。
可以通过增大固定时间步长来降低物理系统开销,相当于减少物理更新次数:

Project Settings -> Time -> Fixed Timestep

但需要权衡表现性:
较大的间隔时间可能提升物理不稳定性与穿透风险,影响效果表现。

示例:设置固定时间步长

Time.fixedDeltaTime = 0.02f;

谨慎修改最大允许时间步长

Maximum Allowed Timestep 用于防止游戏在非常卡顿时不停补物理帧。
超过该时间上限的时间会被直接丢弃。

举例说明:

  1. 默认最大允许时间步长为 0.333s333ms)。
  2. 若帧间隔时间超过该值,例如 0.5s500ms),该帧最多补 16 次物理更新(333/20),超出的时间会直接丢弃。

如果想通过改小它来优化性能,例如从 0.333s 改成 0.1s,需要注意:

  1. 高帧率时
    按 Fixed Timestep 正常算,Maximum Allowed Timestep 不会触发。
  2. 低帧率时
    假设某帧掉到 0.2s
    • 不修改时,Unity 会补 10 次物理更新
    • 修改为 0.1s 时,Unity 最多补 5 次,剩余 0.1s 的物理更新会被丢弃
      结果可能出现物理对象瞬移、跳跃等异常表现

因此,通过改小 Maximum Allowed Timestep 虽然 CPU 会少计算物理更新,但会牺牲物理表现的连续性,强行降低物理精度。

示例:设置最大允许时间步长

Time.maximumDeltaTime = 0.333f;

56.3 知识点代码

Lesson56_性能优化_CPU_物理_时间步长和最大允许时间步长.cs

public class Lesson56_性能优化_CPU_物理_时间步长和最大允许时间步长
{
    #region 知识回顾 Unity物理系统中的更新机制

    //Unity中的3D物理系统是基于Nvidia(英伟达)的PhysX
    //2D物理系统是基于开源项目Box2D的
    //Unity中对他们进行了封装,我们不需要知道内部是如何执行的
    //只要调用Unity相关API,既可以让两个物理引擎解决方案以相同的方式运行

    //物理系统的执行机制中,最重要的就是 时间步长(Time Step) 的概念
    //时间步长在Unity中我们一般称为 固定更新时间步长
    //指的是 物理世界 更新的固定时间间隔
    //即每隔多长时间更新一次物理逻辑
    //在Unity中默认为每 20ms(即0.02秒,50Hz) 更新一次
    //我们可以在Project Settings——>Time——>Fixed Timestep中进行设置

    //注意:
    //物理逻辑是独立于帧率的,不以帧为准,而是严格以固定时间步长为准
    //一帧里可能执行0次、1次、甚至多次物理循环
    //即 如果固定时间步长小于实际帧更新耗时,那么在一帧中可能会发生不止一次物理循环更新
    //举例
    //1.游戏比较流畅,一帧只跑了15ms,那么该帧中物理更新可能不需要执行和更新
    //2.游戏比较卡顿,一帧跑了40ms,那么该帧中物理更新需要连续执行2次
    //也就说,物理更新只以实际经过的时间为准,间隔时间到了固定时间步长就必须更新一次的规则
    //如果帧间隔时间过长,在执行物理逻辑时,必须补满对应执行次数

    //但是如果掉帧太严重,会丢弃部分时间片,避免无限补帧
    //可以自己设置丢弃的时间上线
    //Project Setting ——> Time ——> Maximum Allowed Timestep(最大允许时间步长) 进行设置

    #endregion

    #region 知识点一 降低物理步频

    //从知识回顾我们得知
    //时间步长其实就决定了在单位时间中物理系统更新的频率
    //因此,我们可以根据需求,通过提高
    //Project Settings——>Time——>Fixed Timestep 
    //固定时间步长的值来降低物理系统开销,相当于减少物理系统更新次数
    //但是我们需要进行表现性的权衡
    //即较高的间隔时间,是否会带来物理系统稳定性与穿透的风险上升
    //影响我们的表现

    #endregion

    #region 知识点二 谨慎修改最大允许时间步长

    //Maximum Allowed Timestep(最大允许时间步长)
    //是用于防止游戏在非常卡顿时,造成不停地补物理帧的情况
    //超过最大允许时间步长的时间会被直接丢弃
    //举例:
    //假设 最大允许时间步长 默认值为 0.333s(333ms)
    //如果真的卡顿造成帧间隔时间超过这个时间,比如为 0.5s(500Ms)
    //那么该帧最多也就补16次(333/20)物理更新逻辑,超过的时间会直接丢弃,不会进行更多次的物理更新了

    //如果想要通过改小它来优化性能
    //比如从 0.333s 改成 0.1s
    //需要注意
    //1.高帧率时
    //  按 Fixed Timestep(物理更新步长) 正常算,Maximum Allowed Timestep (最大允许时间步长)不会触发
    //2.低帧率时
    //  假设某帧掉到 0.2s
    //  如果不修改,Unity会补10个物理更新
    //  如果修改,Unity最多补5个物理更新,剩下0.1s的物理更新直接丢弃
    //  虽然看起来,少了一些物理计算,但是从表现上来看,物理对象可能出现瞬移或者跳跃等奇怪表现

    //因此通过改小Maximum Allowed Timestep(最大允许时间步长)
    //虽然CPU会少计算物理更新,看起来是减小了消耗,但是会牺牲物理表现的连续性,强行降低了物理精度!

    #endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏