碰撞产生的必要条件:
1.Mass:质量 默认为千克,质量越大惯性越大
2.Drag:空气阻力 根据力移动对象时影响空气阻力大小 ,0 表示没有空气阻力
3.Augular Drag:旋转阻力 根据扭矩旋转对象时影响对象的空气阻力大小,0 表示没有阻力
4.Use Gravity:是否受重力影响
5.Is Kinematic:是否设置为运动学
如果启用,对象将不会被物理引擎驱动,只能通过 Transform 对其进行操作,对于移动平台,或者如果要动画附加了 HingeJoint 的刚体,此属性将非常有用
6.Interpolate:插值运算
None:不应用插值运算
Interpolate:根据前一帧的变换来平滑变换
Extrapolate:插值运算
根据下一帧的估计变换来平滑变换,若物理帧时间过长,此效果将不好
7.Collison Detection:碰撞检测模式
None:Discrete:离散检测
Interpolate:根据前一帧的变换来平滑变换
Discrete:离散检测
对场景中的所有其他碰撞体使用离散碰撞检测,其他碰撞体在测试碰撞时会使用离散检测。用于正常碰撞(默认值)
Continuous:连续检测
对动态碰撞体(具有刚体)使用离散碰撞检测
对静态碰撞体(没有刚体)使用连续碰撞检测
设置为连续动态的刚体,将在测试与该刚体的碰撞时使用连续碰撞检测(物理性能消耗较大,物体运动缓慢时请设置为 Discrete)
其他刚体将使用离散碰撞检测
Continuous Dynamic:连续动态检测
对设置为连续和连续动态碰撞的对象使用连续碰撞检测
对静态碰撞体(没有刚体)使用连续碰撞检测
对其他碰撞体使用离散碰撞检测
用于快速移动的对象
Continuous Speculative:连续推测检测
对刚体和碰撞体使用推测性连续碰撞检测
通常比连续碰撞检测的成本更低
无刚体碰撞盒 | Discrete | Continuous | Continuous Dynamic | Continuous Speculative | |
无刚体碰撞盒 | 不检测碰撞 | Discrete | Continuous | Continuous | Continuous Speculative |
Discrete | Discrete | Discrete | Discrete | Discrete | Continuous Speculative |
Continuous | Continuous | Discrete | Discrete | Continuous | Continuous Speculative |
Continuous Dynamic | Continuous | Discrete | Continuous | Continuous | Continuous Speculative |
Continuous Speculative | Continuous Speculative | Continuous Speculative | Continuous Speculative | Continuous Speculative | Continuous Speculative |
性能消耗关系:Continuous Dynamic > Continuous Speculative > Continuous > Discrete
8.Constrains:对刚体运动的约束
9.Info:用于显示参数的面板,不修改里面的值
Is Trigger:是否为触发器
如果启用,则该碰撞体用于触发事件,并被物理引擎所忽略
主要用于进行没有物理效果的碰撞检测
Material:物理材质
可以确定碰撞体和其他对象碰撞时的交互(表现)方式
Center:碰撞体的中心偏移位置
1.Box Collider
Size:碰撞体在 X、Y、Z 方向上的大小
2.Sphere Collider
Radius:球形碰撞体的半径大小
3.Capsule Collider
刚体对象的子对象碰撞信息参与碰撞检测(即父物体添加 Rigid Body,子物体设置 Collider。)
1.Mesh Collider
Convex:是否为凸面的
勾选后,该 Mesh Collider 将会与其他 Mesh Collider 发生碰撞,最多支持 255 个三角面片
如果该对象添加了刚体 Rigid Body,则该选项必须勾选,否则会报错
2.Wheel Collider
赛车游戏中使用,其他时候不常用
注意:添加 Wheel Collider 后一定要添加 Rigid Body(或在父物体添加),否则将失效
3.Terrain Collider
地形系统中使用
性能较为低下,很少使用
在 Project 中创建物理材质 Physics Material
已在移动时使用的摩擦力。通常为О到1之间的值。值为零就像冰一样,值为1将使对象迅速静止(除非用很大的力或重力推动对象)
当对象静止在表面上时使用的摩擦力。通常为О到1之间的值。值为零就像冰一样,值为1将导致很难让对象移动。
表面的弹性如何?值为О将不会反弹。值为1将在反弹时不产生任何能量损失,预计会有一些近似值,但可能只会给模拟增加少量能量。
两个碰撞对象的弹性的组合方式。其模式与Friction Combine模式相同
注意:碰撞和触发响应函数 属于 特殊的生命周期函数 也是通过反射调用
1.碰撞触发接触时会 自动执行这个函数
- private void OnCollisionEnter(Collision collision)
- {
- //Collision类型的 参数 包含了 碰到自己的对象的相关信息
-
- //关键参数
- //1.碰撞到的对象碰撞器的信息
- //collision.collider
-
- //2.碰撞对象的依附对象(GameObject)
- //collision.gameObject
-
- //3.碰撞对象的依附对象的位置信息
- //collision.transform
-
- //4.触碰点数相关
- //collision.contactCount
- //接触点 具体的坐标
- //ContactPoint[] pos = collision.contacts;
-
- //只要得到了 碰撞到的对象的 任意一个信息 就可以得到它所有的信息
-
- print(this.name + "被" + collision.gameObject.name + "撞到了");
- }
2.碰撞结束分离时 会自动执行的函数
- private void OnCollisionExit(Collision collision)
- {
- print(this.name + "被" + collision.gameObject.name + "结束碰撞了");
- }
3.两个物体相互接触摩擦时 会不停的调用该函数
- private void OnCollisionStay(Collision collision)
- {
- print(this.name + "一直在和" + collision.gameObject.name + "接触");
- }
1.触发开始的函数 当第一次接触时 会自动调用
- private void OnTriggerEnter(Collider other)
- {
- print(this.name + "被" + other.gameObject.name + "触发了");
- }
2.触发结束的函数 当水乳相融的状态结束的时 会调用一次
- private void OnTriggerExit(Collider other)
- {
- print(this.name + "和" + other.gameObject.name + "结束水乳相融的状态了");
- }
3.当两个对象 水乳交融的时候 会不停调用
- private void OnTriggerStay(Collider other)
- {
- print(this.name + "正在和" + other.gameObject.name + "水乳相融");
- }
一般会把想要重写的 碰撞和触发函数 写成保护类型的 没有必要写成 public 因为不会自己手动调用
都是Unity 通过反射帮助我们自动调用的
给刚体加力的目标就是 让其有一个速度 朝向某一个方向移动
1.首先应该获取刚体组件
rigidBody = this.GetComponent();
2.添加力
- 1.相对世界坐标
- 世界坐标系 z轴正方向加了一个力
- rigidBody.AddForce(Vector3.forward*10);
- 如果想要在 世界坐标系方法中 让对象 相对于自己的面朝向动
- rigidBody.AddForce(this.transform.forward * 10);
-
- 2.相对本地坐标
- 本地坐标系 z轴正方向加了一个力
- rigidBody.AddRelativeForce(Vector3.forward * 10);
3.添加扭矩力,让其旋转
- 1.相对世界坐标
- 世界坐标系 y轴正方向加了一个力
- rigidBody.AddTorque(Vector3.up * 10);
-
- 2.相对本地坐标
- rigidBody.AddRelativeTorque(Vector3.up*10);
4.直接改变速度
- 这个速度方向 是相对于 世界坐标系
- 如果要直接通过改变速度 来让其移动 一定要注意这一点
- rigidBody.velocity = Vector3.forward * 5;
5.模拟爆炸的效果
- 参数一:力的大小
- 参数二:爆炸点
- 参数三:力的范围
- 模拟爆炸的力 一定是 所有希望产生爆炸效果影响的对象
- 都需要得到他们的刚体 来执行这个方法 才能都有效果
- rigidBody.AddExplosionForce(100, Vector3.zero,10);
第二个参数 力的模式 主要的作用 就是 计算方式不同而已
由于4种计算方式的不同 最终的移动速度就会不同
rigidBody.AddForce(Vector3.forward * 10, ForceMode.Acceleration);
动量定理
Ft = mv
v = Ft/m
F:力
t:时间
m:质量
v:速度
- 1.Acceleration
- 给物体增加一个持续的加速度,忽略其质量
- v = Ft/m
- F(0,0,10)
- t:0.02s
- m:默认为1
- v = 10*0.02/1 =0.2m/s
- 每物理帧移动0.2m/s*0.02s=0.004m
-
- 2.Force
- 给物体添加一个持续的力,与物体的质量有关
- v = Ft/m
- F:(0,0,10)
- t:0.02s
- m:2kg
- v = 10*0.02s/2kg = 0.1m/s
- 每物理帧移动 0.1m/s*0.02s = 0.002m
-
- 3.Impulse
- 给物体添加一个瞬间的力,与物体的质量有关,忽略时间 默认为1
- v = Ft/m
- F:(0,0,10)
- t:默认为1
- m:2kg
- v = 10*1/2kg = 5m/s
- 每物理帧移动 5m/s*0.02s = 0.1m
-
- 4.VelocityChange
- 给物体添加一个瞬时速度,忽略时间、质量
- v = Ft/m
- F:(0,0,10)
- t:默认为1
- m:默认为1
- v = 10*1/1kg = 10m/s
- 每物理帧移动 10m/s*0.02s = 0.2m
Constant Force
给物体一个持续的力
- 获取刚体是否处于休眠状态 如果是休眠状态就唤醒它
- if (rigidBody.IsSleeping())
- {
- //唤醒
- rigidBody.WakeUp();
- }