Unity3D完全自学教程(第4章 物理引擎)

2,392 阅读8分钟

本章将介绍Unity的物理引擎,通过使用物理组件,可以方便地实现游戏物体受力、碰撞的效果,真实地创建出符合物理规律的场景。

基本概念

刚体

挂载刚体组件,能让游戏物体受到重力以及外加的力

移动物体建议采用施加力的方式,不宜再用Transform组件

开启IsKinematic开关,可以让物体脱离物理引擎的控制,而采用脚本控制,这种刚体运动被称为“是运动学的”

休眠

休眠即Sleeping模式,这是一种性能优化方案,进入休眠的物体无需被物理引擎反复更新状态

刚体的移动或旋转速度低于一定的阈值时,进入休眠状态,这是自动进行的,对开发者透明

特殊情况,物体无法被唤醒,可以调用脚本的WakeUp方法

特殊情况包括静态碰撞体(无刚体,有碰撞体)与刚体的接触,如刚体放在地面上,地面被移除,刚体不会下落而是留在原位

碰撞体

碰撞体有多种类型,如盒子、球形、胶囊、2D

碰撞体的外形可以调整,一个物体可以带有多个碰撞体组件

触发器

勾选碰撞体组件的Is Trigger,从而将碰撞体变为触发器

不产生物理上的实际碰撞,用于检测两物体是否重叠

两物体必须至少一个含有刚体组件才能触发脚本函数

物理材质

与普通材质不同,其注重物理层面的效果

用来设置摩擦力和弹力

碰撞与脚本行为

  1. 碰撞
  • OnCollisionEnter
  • OnCollisionStay
  • OnCollisionExit
  1. 触发
  • OnTriggerEnter
  • OnTriggerStay
  • OnTriggerExit

对于2D物体,只需在函数末尾加上2D即可

碰撞体分类

  1. 静态碰撞体

    不挂载刚体组件,挂载碰撞体组件,常用做地形和障碍物,刚体碰撞时也不会移动

  2. 刚体碰撞体

    挂载了刚体和碰撞体组件,在游戏中最普遍

  3. Kinematic刚体碰撞体

    挂载了刚体和碰撞体组件,刚体组件勾选Kinematic

    不会对碰撞和力做出反应,但有摩擦力,和刚体碰撞时能唤醒其他刚体,用脚本控制

碰撞事件触发表

  1. 碰撞时是否产生碰撞事件

    对于能发生碰撞事件的,不管谁碰谁,两者都能触发碰撞事件,当然前提是带有碰撞体组件

    静态碰撞体---刚体碰撞体

    刚体碰撞体---所有碰撞体

    Kinematic刚体碰撞体---刚体碰撞体

  2. 碰撞时是否产生触发器事件

    对于能发生触发事件的,不管谁碰谁,两者都能触发触发事件,当然前提是带有触发器组件

    对于静态碰撞体、刚体碰撞体、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,注意勾选场景右下角的选项

作用

  • 快速检查场景中的碰撞体:不同类型的碰撞体用不同类型的颜色表示
  • 判断刚体是否休眠:显示效果不同
  • 隐藏和显示某些类型的碰撞体

调试窗口中的属性如英文含义所示