Notifications
Article
Unity 2018.3中的物理功能改进
Updated 22 days ago
72
0
在最新的Unity 2018.3中,我们对物理功能的主要改动是将3D物理引擎由PhysX 3.3.3升级到PhysX 3.4.2,这是我们首次发布最新版PhysX的支持。我们的目标是提高性能和稳定性,并让开发者非常轻松的升级项目。
本文将介绍Unity 2018.3中此次更新的所有具体改动以及与物理相关的新功能。

PhysX 3.4更新

PhysX 3.4是一个重大更新,对多个方面带来了明显的改进。
首先,PhysX 3.4解决了大量Bug。例如:PhysX 3.4显著改进凸面与凸面间的碰撞检测和反馈,因此当启用PCM碰撞检测时,不会出现任何奇怪的碰撞情况。针对窄长型三角的物理查询也得到了改进。PhysX 3.4还提高了地形接触计算的精度。
其次,新版物理引擎能使物理作业的线程更加饱和。我们重写了粗测阶段,碰撞检测和解算器,从而使它们尽可能多地分解为小型线程作业。因此,模拟一帧画面所需的时间将比以前更短。
最后,物理查询模块比以前快二倍的速度。
PhysX 3.4加入了大量新内容,我们将为大家介绍Unity 2018.3所支持的相关新功能。

多场景物理

Unity过去只有一个物理场景,该场景会填充来自所有Unity场景的物体和碰撞体。这样做会对很多情况产生限制,所以新版本将允许开发者创建多个物理场景。
你可以指定Unity场景使用默认物理场景或本地场景。额外场景和默认场景的功能相似,只不过所有常用Physics.* API会忽略额外场景,因为所有场景都是完全独立的。
使用额外场景有很多种方法,你可以使用PhysicsScene.Simulate在任何频率下对场景进行模拟,你也可以创建用于预测轨迹的隐形物理场景。此次改进应用于3D物理和2D物理。

更多批量查询

批量物理查询是一种从主线程外运行物理查询的方法。我们需要使用批量查询API,因为线程无法执行来自其它线程的API。
在Unity 2018.1中,我们发布了RaycastCommand.ScheduleBatch,它有助于计算主线程的光线投射。
在Unity 2018.3中,我们将其扩展,添加了其它单结果查询。例如:SphereCast、CapsuleCast和BoxCast。我们正在研究阻碍我们公开多结果查询的技术限制,以便在未来版本中发布该功能。

强化的结果输出

当所有输入内容一致时,PhysX能产生相同结果。然而对于物理引擎而言,很多信息都属于“输入内容”,物理场景本身就是一项输入内容。
在Unity 2018.3前,Unity无法销毁隐含的物理场景,开发者只能销毁场景中的所有对象,但这样做是不够的。加入多场景物理功能后,我们可以轻松解决该问题。
另一个常见问题是,添加距离较远且不会与其它对象交互的新物体后,也会改变模拟结果。
原因在于Unity中PhysX内部的对象分组方式。通过启用物理设置中的特别选项可以解决该问题。该功能目前仍对性能有影响,但它不会明显减慢项目的运行速度。

统一的高度图

TerrainCollider使用了一种特别的碰撞检测算法,该算法会处理计算接触时的不准确假设,以及少数类似地形厚度的不明显功能。
在Unity 2018.3中,碰撞检测方法和计算网格接触的方法是相同的。

推测性连续碰撞检测

连续碰撞检测选项已经加入到Unity中, 但是该过程的线性特性经常出现问题。该过程会沿着速度向量扫描对象的指定距离,用于计算下次碰撞的时间,而且模型不支持旋转。
该问题的最简单案例就是弹球游戏,游戏中弹板旋转速度很快,因为弹板不会线性移动。在Unity 2018.3加入新连续碰撞检测算法后,我们解决了该问题。
新算法的工作方式是扩大影响接触点生成的接触偏移。当对象足够接近扩张距离后,算法会生成实际接触流形。该模式不再使用预测性线性扫描,所以新算法会通过检测重叠物体的旋转或移动情况,得到更准确的结果。
如下图所示,这是弹球游戏加入新连续碰撞检测算法后的变化,左侧为未加入,右侧为加入后的运算结果。

定向摩擦

Unity 2018.3中加入了全新摩擦模式:单向摩擦和双向摩擦。
默认摩擦模型的工作方式是对每个接触对最多创建四个标量限制。这是计算速度最快的模型,它可以快速收敛,不需要太多次解算器迭代。
单向摩擦模式和双向摩擦模式都会针对每个接触点的基础进行处理,而不是接触对。这样一来能得到更准确的结果,但是需要收敛更多解算器迭代,如果项目根据每个接触对生成了多个接触点,项目的运行速度将被减慢。

新项目不会自动同步变换

默认情况下,对Unity变换属性的所有改动会在使用前同步到物理引擎。也就是说,在每次运行光线投射前,或每次运行模拟过程前都会进行同步。
同步不是速度最快的操作,它会降低被调用次数。因此,我们加入了新设置,用于禁用所有自动同步点。你应该调用Physics.SyncTransforms,不然Transform只会在模拟过程前,即FixedUpdate前进行同步。
同步点的另一个问题是,同步本身只能发生在主线程。这意味着你无法使用包含同步的光线投射。
通常情况下,随着Unity的多线程功能日益强大,新项目在多数情况下需要关闭自动同步点。现在我们将所有新项目创建时的Physics.autoSyncTransforms默认值由True改为False,这些改进应用于3D物理和2D物理。

获取接触信息时避免垃圾内存

获取接触信息总会造成不可避免的托管堆分配。这些分配是为了将Collision结构的实例传递给脚本的处理程序和接触点数组。根据事件发生的频率,该功能会在不同程度上降低部分项目的性能。
在Unity 2018.3中,我们引入了一个新属性Physics.reuseCollisionCallbacks,该属性默认情况下为禁用状态,以便在升级现有项目时保持行为一致。
如果启用该属性,Collision实例会被共享。这意味着每次触发回调时,只有一个Collision类的实例会被重用。因此它不会产生任何垃圾内存。然而,在回调中接收的碰撞信息需要手动复制。这项改进应用于3D物理和2D物理。

品质保证

我们的目标是使新版本的升级过程非常简单。为了实现这一目标,我们进行了比以前更多次的测试和审核。
我们将版本发送给早期使用者,然后在Unity 2018.2中进行了有限的功能升级工作,并使其在Unity 2018.2 Alpha版期间作为衍生版本进行测试。
当Unity 2018.2公开发布后,我们会在官方论坛集中接受用户的反馈。

小结

我们希望得到更多反馈,如果你对此感兴趣,欢迎加入Unity Beta版测试计划,并与我们在Physics论坛或Unity 2018.3 Beta论坛进行讨论。
获取Unity 2018.3 Beta:https://unity3d.com/unity/beta
Unity Physics论坛:https://forum.unity.com/forums/physics.78/
Unity 2018.3 Beta论坛:https://forum.unity.com/forums/2018-3-beta.163/
更多Unity最新信息尽在Unity官方中文论坛(UnityChina.cn)!

Unity China
379
Comments