携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情
物理模拟的频率 Physics Simulation Frequency
物理模拟频率的设置
优化物理模拟首先要考虑的就是以多快的频率运行物理模拟。物理引擎以固定的时间间隔运行,即每次物理引擎的更新和上一次更新之间的时间间隔是固定不变的。Unity默认的物理更新频率是50Hz。
物理更新的频率和游戏的帧率是无关的。如果游戏帧率高于物理模拟频率,则每帧只会进行一次物理模拟。如果游戏的帧率目标是60FPS的话,将物理更新频率设置为60Hz可以让每帧进行一次物理模拟。当使用Unity默认的50Hz时,在60FPS下,每帧进行的物理模拟不超过一次,也就是说有些帧会跳过物理模拟。物理模拟频率过低可能会影响模拟的精确度。总之,根据你的目标帧率,设置一个合适的物理更新频率,尽量让每帧只进行一次物理模拟。
末日螺旋
如果游戏帧率低于物理模拟频率,每帧就有可能执行多次物理模拟,这可能会造成所谓的"末日螺旋"。即当FPS低于物理间隔时,运行一帧所花费的时间超过了物理需要的间隔时间,物理引擎只能一帧运行多次更新来让物理更新间隔保持在需要的间隔上。但这样每帧会计算多次物理,这不担造成了计算的浪费,而且会进一步拖慢帧率,导致一帧需要更多次的物理更新。如此重复下去,理论上就会导致性能螺旋下降,直到每帧执行无数次物理而使得帧率趋近于0。
Maximum Allowed Timestep
当然实际上Unity不会发生掉进末日螺旋的情况,因为Unity使用了Maximum Allowed Timestep来限制一帧中物理更新的次数。比如,当FPS为10,物理更新频率为50Hz时,一帧的时间间隔为1/10=0.1秒,而物理更新间隔为0.02秒,因此一帧需要更新0.1/0.02=5次物理,如果我们设置Maximum Allowed Timestep为0.04秒,那么虽然这帧实际花费了0.1秒,我们也当它只花费了0.04秒,那么需要物理更新的次数就是0.04/0.02=2次。这将限制每帧物理更新的次数,从而避免由于物理更新次数太多,导致帧率继续降低,落入末日螺旋。当然这样做也有副作用,因为我们实际减少了物理更新的次数,这会拖慢物理,物理世界的时间流逝速度将会慢于现实世界,你会发现物理驱动的物体的运动变慢了。
预防胜于治疗
除了使用Maximum Allowed Timestep来保底之外,更重要的还是优化游戏帧率,设置合理的物理更新频率,避免一帧执行多次物理计算。另外在FixedUpdate中,要避免执行物理无关的代码,因为当物理计算执行多次时,FixedUpdate也会被调用多次,如果在其中执行太多的物理无关的代码,将会更加拖慢帧率。我曾经见到一个项目将游戏逻辑整个都放到FixedUpdate中,虽然这可能有他们的理由,但是客观上会在低帧率时一帧执行多次游戏逻辑,即没有必要,也会更加拖慢帧率,从而更容易进入末日螺旋,直到被Maximum Allowed Timestep保底。