
Unity物理引擎简介 - 2019.3
Tutorial
Beginner
+0XP
30 mins
(61)
Unity Technologies

物理引擎可通过(近似于)现实世界中存在的作用力(例如重力、速度和加速度)来控制物体。本教程将介绍一些关键概念。
Languages available:
1. 碰撞体
如果您使用的是Unity 2019.2或更低版本,请单击此处。
当游戏对象相互碰撞或相交时,碰撞体会帮助Unity记录这一过程。
游戏对象必须有附加的RigidBody(刚体)组件才能发生碰撞。
碰撞体的类型包括:Box Collider(盒碰撞体)、Capsule Collider(胶囊碰撞体)、Mesh Collider(网格碰撞体)、Sphere Collider(球形碰撞体)、Terrain Collider(地形碰撞器)和Wheel Collider(车轮碰撞体)(图01)。 请注意,Mesh Collider需要占用更多的计算资源,计算成本较高。 如果显示的网格非常细密,最好使用“计算成本较低”的网格进行碰撞。 借助ProBuilder,可以构建更简单的“代理”网格以满足复杂网格的形状要求。
“GameObject”下拉菜单中的许多Unity 3D对象都包含碰撞体。
要为独立或空的游戏对象启用Unity物理引擎,请在检查器窗口中选择“Add Component”按钮,选择“Physics”,然后指定碰撞体的类型。 这里,我们选择的是“Box Collider”(图02)。
2. 触发器
可以通过选中相应的复选框来启用触发器。触发器的功能与碰撞体相同,但会禁用组件上的物理引擎,从而使对象能够经某个区域穿过它。当对象进入或离开触发器时,可以调用事件(图03)。
其中一个对象必须附加Rigidbody组件。最佳做法是,在触发器内移动的对象具有此组件。
3. 刚体
Rigidbody组件(图04)可以让游戏对象受到物理属性(例如重力)的影响。这其中还包括质量、速度和阻力(空气阻力)等属性。 质量较大的对象受质量较小的对象的影响较小,反之亦然。阻力会影响速度随时间的衰减。角阻力会影响角速度。
“Is Kinematic”复选框允许刚体通过Unity物理引擎影响其他对象,但自身却不会受到影响。例如,VR游戏中的“Hand Avatar”可以通过物理引擎与对象相互作用,但我们并不希望物理引擎作用到手上。
“Is Kinematic”复选框还将影响由动画引擎控制的对象。如果选中“Is Kinematic”复选框(开启),动画引擎便会影响相关对象。 如果取消选中(关闭),那么起控制作用的就是物理引擎。
- Interpolation:碰撞检测方式
- Interpolate:对象的平滑移动基于动画时间轴中前一帧的信息。
- Extrapolate:对象的平滑运动基于对下一帧的猜测。
- Collision Detection:碰撞检测速率
- Discrete:默认设置
- Continuous:检测与静态对象交互的快速运动对象
- Continuous Dynamic:检测与其他快速运动对象交互的快速运动对象
- Continuous Speculative:预测碰撞检测
- Constraints:定义哪些轴的对象不应移动
此外,我们可以通过在下拉菜单中进行选择来重新定义和更改Unity物理引擎值的元素:“Edit”>“Project Settings”>“Physics”(图05)。
4. 脚本编写
与其他游戏对象交互时,可用于碰撞体的函数包括:
OnCollisionEnter (Collision)在记录碰撞时调用。 例如:
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.CompareTag("Enemy")
{
//Hit the enemy
}
}OnCollisionStay (Collision)在碰撞期间调用
OnCollisionExit (Collision)在碰撞停止时调用
为了启用或禁用重力,可以使用useGravity函数。
bool rigidBody.useGravity为了向特定方向添加作用力,可以使用.AddForce()函数。
*rigidBody.AddForce(Vector3)为了添加绕轴的旋转力,可以使用.AddTorque()函数。
rigidBody.AddTorque(Vector3, Force Mode)请注意,在FixedUpdate()中调用AddForce和AddTorque时,将会随时间推移施加此作用力。
5. 作用力方式
- Acceleration:施加以恒定速率增加的作用力
- Force:默认设置,即在考虑质量因素的情况下逐渐施加作用力。
- Impulse:施加瞬时作用力,而不是逐渐增加的作用力。
- VelocityChange:沿不同方向施加瞬时作用力。忽略质量因素。
6. 关于更新
- Update: 每帧调用一次。
- FixedUpdate: 每帧调用多次。 FixedUpdate期间会调用大多数物理计算。顾名思义,计算之间的时间是固定的。
7. 物理材质
控制表面的摩擦力与其他表面相互作用的方式。 物理碰撞体可以应用自定义材质。 您可以指定以下值:Dynamic Friction (动态摩擦力)、Static Friction(静态摩擦力)和Bounciness(弹力)。您也可以自定义以下参数:Friction Combine(摩擦力合并)和Bounce Combine(合并反弹)。
要创建自定义物理材质,请从“Top Menu”下拉菜单中选择:“Assets”>“Create”>“Physic Material”(图06),然后在“Project”窗口中选择新创建的物理材质并将其拖到Inspector中游戏对象的“Material”属性上,从而将其添加至游戏对象。
8. 物理关节
Joint(关节)组件用于将一个刚体连接到另一个刚体或空间中的固定点。关节
施加使刚体移动的作用力。通过关节限制也可以限制某些运动。 物理关节的类型包括:Character Joint(角色关节)、Configurable Joint(可配置关节)、Fixed Joint(固定关节)、Hinge Joint(铰链关节)和Spring Joint(弹簧关节)(图07)
- Character Joint:模拟角色的关节,例如髋关节或肩关节。 此选项限制刚体的所有线性自由运动,可实现全角度自由运动。附着在Character Joint上的刚体可从共用原点围绕每个轴和枢轴旋转。
- Configurable Joint:模拟任何骨骼关节,例如布娃娃中的关节。您可以对此关节进行配置,从而强制和限制刚体以某个自由度移动。
- Fixed Joint:限制刚体的运动,使其跟随所附着的刚体进行移动。当您需要一种能轻松分离的刚体,或者您想关联两个刚体的运动而无需在“Transform”层次结构中建立父级关系时,即可使用这种关节。
- Hinge Joint:在共用原点上将一个刚体附加到另一个刚体或空间点上,并允许刚体从该原点围绕特定的轴旋转。可用于模拟门和手指关节。
- Spring Joint:保持刚体彼此分开,但刚体之间的距离可略微伸展。弹簧就像一块弹性体,它会尝试聚拢两个锚定点并维持原来的位置。
9. 光线投射
在一个物理对象与另一个物理对象之间投射光线或建立隐形连接。
Physics.Raycast (Vector3 Origin, Vector3 Direction)
Physics.Raycast (Vector3 Origin, Vector3 Direction, RaycastHit Info, float Distance, int Layermask)或
Physics.Raycast (Ray RayName, RaycastHit Info, float Distance, int Layermask)参数:
origin: 光线在“世界”空间中的起点。
direction: 光线在“物体”空间中的投射方向。
maxDistance: 光线用于检查碰撞时的最大距离。
layerMask: 一种用于在投射光线时有选择地忽略碰撞体的图层蒙版。
queryTriggerInteraction:指定此查询是否应命中触发器。
可以为发生碰撞的游戏对象分配一个新标签或已有标签,这样会更易于识别RaycastHit(图08)。
在本例中,Raycast将从附加该脚本的任何游戏对象的原点向下投射光线。
如果“Transform”位置与地面(带有环境标签的游戏对象)之间的距离为“DeploymentHeight”,则调用以下函数:DeployParachute()。
使用Raycast时,最佳做法是:
- 减少场景中Raycast的数量。
- 不要在FixedUpdate()或Update()函数内部调用Raycast。
- 应避免使用MeshColliders。
10. 图层和碰撞矩阵
将默认行为分配给游戏对象的默认图层时,它会与所有对象发生碰撞。这样会造成效率低下。 因此,可以将游戏对象分配到一个新的图层。这些图层之间的碰撞关系可以由碰撞矩阵来确定。
要打开物理引擎设置,请从“Top Menu”下拉菜单中选择:
“Edit”>“Project Settings”>“Physics”。 “Project Settings”窗口的底部就是图层碰撞矩阵(图09)。
11. 优化注意事项
最好明确定义哪些对象与其他对象发生碰撞,从而减少计算次数和脚本编写。
此外,建议不要将某些物理属性应用于静态对象。 例如,不要在静态对象上使用“Transform”, 否则会令性能变差。
12. 总结
Unity物理引擎可以让物体受到近似于自然界中各种力(例如重力、速度、加速度和摩擦力)的作用。 它允许具有不同物理属性的各种对象与场景中的其他对象进行动态交互。