前言:物理引擎仅仅是对现实物理的一种近似模拟。无论是从运算精度和时间连续性都不够准确。目的只是为了让游戏具备令人信服的物理表现,增强游戏的表现力和用户的沉浸感。
一、刚体Rigidbody
刚体是让物体产生物理行为的主要组件。一旦挂载了Rigidbody组件,它就纳入了物理引擎的控制之中,可以受到力的影响并做出反应。
已经被挂载刚体的组件,不建议再用脚本直接修改该物体的位置或者直接改变物体的朝向。如果要让物体运动,可以考虑对刚体施加作用力来推动物体,然后让物理引擎计算并产生想要的结果;或者直接修改物体的速度(velocity)和角速度(angular velocity),这样比施加作用力更直接。
一些情况下,只需要物体具有Rigidbody组件,但又不能让它的运动受到物理引擎的控制。例如,让角色完全受脚本直接控制,但同时又不让角色被触发器检测到,这种不直接受物理控制的、但用其他方式进行的刚体运动成为运动学(Kinematic)。这种刚体的运动方式虽然部分脱离了物理系统控制而不再受到力的影响,但在需要碰撞检测等情况下依旧会被物理系统处理。
可以在脚本中随时开启或关闭物体的Is Kinematic选项,但这样以来会带来一些性能开销,不应频繁使用
二、休眠
当一个刚体的移动速度和旋转速度已经低于某个事先定义的阈值,并保持一定事件,那么物理引擎就可以假定它暂时稳定了。这种情况下,直到其再次收到力的影响之前,物理引擎都不再需要反复计算该物体的运动,这是就可以说该物体进入了"休眠"。
这是一种优化性能的方案。
大多数情况下,刚体的休眠和唤醒都是自动进行的,也就是说我们不用关心这个细节。但是,总有一些情况下,物体无法自动唤醒。例如,一个稳定放在地面上且带有Rigidbody组件的物体,在地面被移除后其仍然悬挂在空中。如果遇到类似的情况,可以在脚本中主动调用WakeUp方法
三、碰撞体Collider
碰撞体组件定义的物体的物理形状。碰撞体本身是隐身的,不一定要和物体的外观完全一致
实际制作时,更多的时候会用物体的近似形状,而不是准确形状,这样可以提升游戏的运行效率。
最节约资源的是一系列基本碰撞体,包括:
- 盒子碰撞体(Box Collider)
- 球体碰撞体(Sphere Collider) //⚠️:不会因为物体伸缩变成椭球体
- 胶囊碰撞体(Capsule Collider)
一个物体上可以同时挂载多个碰撞体组件,这样就形成了组合碰撞体
组合碰撞体是一个Unity术语,不是一个组件。指的是一个物体挂载了多个碰撞体组件或该物体具有多个碰撞体的子物体。子物体所挂载的碰撞体组件,也会成为父物体物理外形的一部分。
在模拟外形复杂的物体时,建议多添加几个子物体来表示物理外形,因为用子物体方便单独控制偏移和旋转。但要注意,只在父物体上挂载一个刚体组件,子物体上不要挂载刚体组件。
四、物理材质Physics Materials
必须模拟碰撞体表面材质的特性,这样碰撞体之间发生交互时才能正确模拟实际的物理效果
可以设置摩擦系数、弹性等表面特性
五、触发器Trigger
碰撞体会默认阻挡刚体运动。如果想要检测两个物体是否接触,又不引起物理上的实际碰撞,就需要勾选碰撞体组件的Is Trigger属性,使其变成一个触发器
当一个碰撞体进入了触发器的范围,就会调用脚本的OnTriggerEnter()方法。但要注意,两个物体中至少有一个带有刚体组件(可以是动力学刚体),否则无法触发脚本。
六、碰撞体的分类
对于包含了碰撞体组件的物体来说,物体上是否具有刚体,以及刚体组件上动力学设置的不同,都会使物体的物理碰撞特性发生变化。根据这些特性,对碰撞体进行分类。
1、静态碰撞体Static Collider
没有挂载刚体的碰撞体。静态碰撞体通常用于制作关卡中固定的部分,例如地形、障碍物等。
2、刚体碰撞体Rigidbody Collider
挂载了普通刚体组件的碰撞体。物理引擎会一直模拟计算刚体碰撞体的物理状态,因此刚体碰撞体会对碰撞以及脚本施加的力做出反应
3、动力学刚体碰撞体Kinematic Rigidbody Collider
挂载了刚体组件且刚体组件设置为动力学刚体的碰撞体。可以在脚本中直接修改动力学刚体碰撞体的位置来移动它,不会对碰撞、力和速度的变化做出反应。
触发器的分类与碰撞体类似,不再说明
七、碰撞事件表
碰撞事件表
|
静态碰撞体 |
刚体碰撞体 |
动力学刚体碰撞体 |
静态碰撞体 |
|
✔️ |
|
刚体碰撞体 |
✔️ |
✔️ |
✔️ |
动力学刚体碰撞体 |
|
✔️ |
|
触发事件表
|
静态碰撞体 |
刚体碰撞体 |
动力学刚体碰撞体 |
静态触发器 |
刚体触发器 |
动力学刚体触发器 |
静态碰撞体 |
|
|
|
|
✔️ |
✔️ |
刚体碰撞体 |
|
|
|
✔️ |
✔️ |
✔️ |
动力学刚体碰撞体 |
|
|
|
✔️ |
✔️ |
✔️ |
静态触发器 |
|
✔️ |
✔️ |
|
✔️ |
✔️ |
刚体触发器 |
✔️ |
✔️ |
✔️ |
✔️ |
✔️ |
✔️ |
动力学刚体触发器 |
✔️ |
✔️ |
✔️ |
✔️ |
✔️ |
✔️ |
小结:
- 有刚体碰撞体才会碰撞
- 只有两个都是静态的才不会触发。
八、层Layer
与标签(Tag)类似,每个物体也可以属于一个"层"。将不同物体安排在不同的层上,并指定哪些层之间不能碰撞,就可以巧妙地完成目的。
可在Unity主菜单的Edit->Project Settings->Physice中找到层碰撞矩阵。层碰撞矩阵左边和上边都是所有层的名称,勾选表示对应两层会发生碰撞。
九、物理关节
关节(Joints)特指一种物理上的连接关系。它总是限制一类运动的自由度,允许另外一类运动的自由度。
Unity提供了很多不同类型的关节。下表列了一些3D场景中的关节
物理关节 |
组件 |
简介 |
固定关节 |
Fixed Joint |
用于固定连接两个物体,不可滑动或旋转。例如可以表现黏住、抓住物体 |
铰链关节 |
Hinge Joint |
连接的两个物体可以以关节为中心循转,例如屋门 |
弹簧关节 |
Spring Joint |
用弹簧连接两个物体,两者太近或太远都会受到弹簧的回复力。可以用弹性(Spring)和阻尼(Damper)调节弹簧的弹性 |
人物关节 |
Character Joint |
专门用来制作任性角色的关节连接。一般用于表现游戏中无生命的人形角色随外力运动的效果。由于配置复杂,需要使用Ragdoll工具辅助制作 |
十、射线检测
"射线检测"是在游戏开发实践中不可或缺的一项技术。简单来说,它就是在游戏世界中发射一条虚拟的"射线",并观察该射线是否击中了某个物体,以及具体击中了该物体的哪个位置。虽然名字叫做"射线"(Ray),但实际发射的位置、方向和长度句可以根据实际需求来设置。不仅有直线的射线,还有球形射线、盒子射线等。所以射线检测中的"射线"可以看作有一定范围和oxide广义"射线"。
十一、角色控制器与物理系统
控制角色大体上有两种方法:
- 用脚本直接控制物体的位置和朝向
- 通过刚体施加力和改变速度来控制角色的行为
用刚体实现的优点在于工作量少,大部分处理都可以依赖物理系统完成。但缺点是角色可能被墙角卡住啊,因障碍物挤压被弹飞之类的,产生bug难以避免。
若不使用刚体,自己写脚本,有点事灵活性和可控性高,但缺点是工作量、难度较大。