本章将介绍Unity的物理引擎,通过使用物理组件,可以方便地实现游戏物体受力、碰撞的效果,真实地创建出符合物理规律的场景。
基本概念
刚体
挂载刚体组件,能让游戏物体受到重力以及外加的力
移动物体建议采用施加力的方式,不宜再用Transform组件
开启IsKinematic开关
,可以让物体脱离物理引擎的控制,而采用脚本控制,这种刚体运动被称为“是运动学的”
休眠
休眠即Sleeping模式
,这是一种性能优化方案,进入休眠的物体无需被物理引擎反复更新状态
刚体的移动或旋转速度低于一定的阈值时,进入休眠状态,这是自动进行的,对开发者透明
特殊情况,物体无法被唤醒,可以调用脚本的WakeUp方法
特殊情况包括静态碰撞体(无刚体,有碰撞体)与刚体的接触,如刚体放在地面上,地面被移除,刚体不会下落而是留在原位
碰撞体
碰撞体有多种类型,如盒子、球形、胶囊、2D
碰撞体的外形可以调整,一个物体可以带有多个碰撞体组件
触发器
勾选碰撞体组件的Is Trigger
,从而将碰撞体变为触发器
不产生物理上的实际碰撞,用于检测两物体是否重叠
两物体必须至少一个含有刚体组件才能触发脚本函数
物理材质
与普通材质不同,其注重物理层面的效果
用来设置摩擦力和弹力
碰撞与脚本行为
- 碰撞
OnCollisionEnter
OnCollisionStay
OnCollisionExit
- 触发
OnTriggerEnter
OnTriggerStay
OnTriggerExit
对于2D物体,只需在函数末尾加上2D即可
碰撞体分类
-
静态碰撞体
不挂载刚体组件,挂载碰撞体组件,常用做地形和障碍物,刚体碰撞时也不会移动
-
刚体碰撞体
挂载了刚体和碰撞体组件,在游戏中最普遍
-
Kinematic刚体碰撞体
挂载了刚体和碰撞体组件,刚体组件勾选
Kinematic
不会对碰撞和力做出反应,但有摩擦力,和刚体碰撞时能唤醒其他刚体,用脚本控制
碰撞事件触发表
-
碰撞时是否产生碰撞事件
对于能发生碰撞事件的,不管谁碰谁,两者都能触发碰撞事件,当然前提是带有碰撞体组件
静态碰撞体---刚体碰撞体
刚体碰撞体---所有碰撞体
Kinematic刚体碰撞体---刚体碰撞体
-
碰撞时是否产生触发器事件
对于能发生触发事件的,不管谁碰谁,两者都能触发触发事件,当然前提是带有触发器组件
对于静态碰撞体、刚体碰撞体、Kinernatic刚体碰撞体这些不带触发器的,只有对方带了触发器才能触发事件
对于静态触发器、刚体触发器、Kinernatic刚体触发器这些带有触发器的,对方带不带触发器都能触发事件
物理关节
关节(Joints),限制一类运动的自由度,允许另一类运动的自由度
作用:制作房门的开关、滑动门、笔记本屏幕与机身
角色控制器
让角色不受物理引擎控制,若控制角色采用刚体的话,很容易出现bug
刚体
添加方式:Components>Physics>Rigidbody
参数介绍
- Mass:质量,单位kg
- Drag:阻尼,指的是空气阻尼
- Augular Drag:角阻尼
- Use Gravity
- Is Kinematic
- Interpolate:差值平滑方式,当刚体出现抖动时设置,选项分别为不适用,使用上一帧,使用未来一帧进行平滑处理
- Collision Detection:碰撞检测方式
- Constraints:约束和限制某些方向的移动和旋转,移动是世界坐标系,旋转是局部坐标系
父子关系
在物理引擎中,对父物体施加力产生的移动,子物体也会跟着移动,而子物体移动,父物体不跟着
脚本控制
施加力:刚体实例.AddForce()
施加扭矩:刚体实例.AddTorque()
开关Kinematic
通过脚本可开关该选项,常用于物理系统控制和动画系统控制间的切换(布偶系统)
添加碰撞体组件
若无碰撞体组件,两刚体相遇会相互穿过,一般都要加个碰撞体组件
连续碰撞检测
速度过快,碰撞体间可能会相互穿过,需要设置连续碰撞检测,当然减少物理更新的间隔时间也可以
Collision Detection属性有三个参数可选:
- Discrete:不连续检测方式
- Continuous:连续检测方式,防止刚体与静态碰撞体相互穿过
- Continuous Dynamic:连续动态检测方式,防止刚体直接相互穿过
比例与单位
物理系统中,1个单位表示1米
建议场景内的模型和人物符合真实环境的尺寸
其他问题
两刚体质量比不同,碰撞后的运动方式不同
两个小球同时下落,下落速度调Drag参数,0.001为金属块,10为羽毛
物体想要接收到碰撞或触发器事件,必须挂载刚体
角阻尼设置为无穷大并不能使刚体旋转立即停止
碰撞体
盒子碰撞体
参数有是否为触发器、物理材质、中心点坐标(采用局部坐标系)、尺寸
胶囊碰撞体
参数同上,尺寸一栏为半径、高度、方向
球体碰撞体
参数同上,尺寸一栏变为球体半径
地形碰撞体
参数有物理材质、地形数据、树木是否也有碰撞效果
网格碰撞体
用来创建一个任意外形的碰撞体,需要基于模型的外形网格
只有凸的网格碰撞体才能与其他网格碰撞体发生碰撞
参数有是否为触发器、物理材质、是否标记为凸的、指定的模型网格
同时挂载网格碰撞体和刚体组件会报错,需要勾选网格碰撞体的凸Convex
属性,勾选后网格会有变化
物理材质
创建:右键>Create>Physic Material
属性
- 动摩擦系数
- 静摩擦系数
- 弹性
- 两物体综合摩擦力
- 两物体综合弹性
两物体相碰,各自有各自的摩擦力和弹性,需要得出综合的摩擦力和弹性
有取平均值、最小值、最大值、相乘
不同物体有不同的综合方式,优先级:最大>相乘>最小>平均
会出现一种情况,将弹性设置为1,球会越弹越高,这是引擎内部的偏差造成
关节
固定关节Fixed Joint
相当于胶水,将一个物体固定在另一个物体的身上,两者可以一起运动,也可以被外力断开
组件属性有连接物体、断开需要的力、扭矩、是否相互碰撞、性能开关
应用:粘性炸弹
铰链关节
用来连接两个刚体,限制两者的相对运动,相当于用一个链子将两者连接,两者可以随着链子的轴旋转
其会默认连接在场景上,可不设置连接物体
应用:房门、链条、钟摆
弹簧关节
连接两个刚体,相当于弹簧,让两者保持一定距离,不太近也不太远
组件属性有最小施力距离、最大施力距离、阻尼、强度、断开需要的力、扭矩等
角色控制器
主要用于第三人称和第一人称视角的游戏,不使用刚体的物理特性来控制角色。
参数说明:
- 能爬上最大斜坡的角度
- 能爬上最高台阶的高度
- 表面厚度(碰撞体与碰撞体之间允许穿透的深度)
- 最小移动距离(减小抖动)
- 参数偏移胶囊碰撞体的位置
- 胶囊的半径
- 胶囊的高度
小技巧
- 角色如果被卡住,建议增大皮肤厚度,预设为大于0.01且大于半径的10%
- 最小移动距离建议设为0
- 角色不会对物理影响做出反应,不过可以通过脚本让角色对其他物体造成物理上影响
常量力
用来添加持续力的组件,挂载该组件的物体会持续受到一个固定大小、固定方向的力
参数说明:
- 世界坐标系表示的力
- 世界坐标系表示的力
- 世界坐标系表示的扭矩
- 世界坐标系表示的扭矩
小技巧:
物体上浮,给世界坐标系的Y轴加力
物体前进,给局部坐标系的Z轴加力
车轮碰撞体
参数说明:
- 车辆质量
- 车轮半径
- 阻尼
- 避震器行程
- 力的施加点
- 车轮中心的位置
- 避震器设置
- 前向阻尼
- 侧向阻尼
具体设置详见书本P164
物理系统可视化调试
打开调试窗口:菜单栏>Window>Physics Debug,注意勾选场景右下角的选项
作用:
- 快速检查场景中的碰撞体:不同类型的碰撞体用不同类型的颜色表示
- 判断刚体是否休眠:显示效果不同
- 隐藏和显示某些类型的碰撞体
调试窗口中的属性如英文含义所示