欢迎光临散文网 会员登陆 & 注册

Unity实现时缓机制的一些注意点

2023-08-02 13:36 作者:DeadCyber  | 我要投稿

主要和物理模拟相关。

众所周知,unity中物理模拟在FixedUpdate前以Time.fixedUpdate(可在Project Setting中调整)速率进行物理模拟。

PS:Unity的物理引擎,根据官方文档显示

  • Built-in 3D physics (Nvidia PhysX engine integration)

  • Built-in 2D physics (Box2D engine integration)

当我们使用Time.scale改变时间速率时,也就是

之后,需要额外处理,来解决一些表现问题。因为由于时间变慢,但物理更新速率没变,会出现物理帧数表现不够,一卡一卡。(也就是说数值正常,但是表现卡顿)


错误做法:假设我们的时间scale为timescale,那么一个典型的“错误”做法是,令代码调用:

从表现上来说,这么做能够使得物理表现恢复“丝滑”,因为此时提高了物理更新速率。但是如果在一段物理模拟过程中,突然改变Time.fixedUpdateTime,也就是dt,那么物理模拟会出现错误。因为Unity物理模拟是实时解算,有赖于上一帧的结果和dt的稳定,此时改变dt一定会导致接下来的物理解算出错。所以这个“错误”做法不能用于物理过程中改变Time.scale。


正确做法:

第一,我们可以去Project Setting里适当降低fixedUpdateTime,以提高基础的物理模拟速率。

第二,对于RigidBody,在时缓时使用

来开启自带的插值功能,使得表现变顺滑。

第三,对于我们自己实现的(在FixedUpdate中更新的)一些位移或者旋转逻辑,我们自己去Update里实现我们自己的顺滑插值。至于怎么实现,需要我们有最基本的物理模拟插值认知。


我们自己位移逻辑的物理插值实现例子:

假设我们之前在FixedUpdate中维护了一个功能dash,用于每物理帧往一个方向冲刺:

那现在要改写。一个最简单常见的插值思路是,假定每一物理帧瞬间都是匀速直线运动,那么就可以根据上一个物理帧的位置,预测当前位置,直到下一个物理帧再硬set回正确位置。(看似暴力,但实际上可以应付99%的情况,并且在极端情况下,即使多考虑一些帧数信息也不一定能更好预测,除非上卡尔曼滤波,那就太复杂了。其实SLAM领域里也是这么做的)

改写物理帧如下:

然后在Update函数里,进行插值:


至此,Unity中实现时缓机制的一些问题就解决了。

Unity实现时缓机制的一些注意点的评论 (共 条)

分享到微博请遵守国家法律