专栏的上一篇角色控制器控制角色移动跳崖,这一篇来说说Unity的物理系统。
本篇小编还要带大家做一个碰撞检测效果实例,先放效果图:流星撞击地面产生爆炸效果
一、Rigidbody
我们给胶囊添加了 Rigidbody 组件它才有的重力,我们来看看 Rigidbody组件中的参数。
- 首先质量不用多说就是代表物体的质量
- 阻力是物体下落时遇到的空气阻力
- 角阻力是物体旋转时受到的阻力
- 使用重力是判断物体单纯的受不受重力影响,重力只是物理特性之一,我们来做个实验:
创建一个球体、立方体和平面,球体和立方体都挂载 Rigidbody 组件,立方体把 使用重力 取消勾选后运行,用球体去撞立方体。
然后立方体就说:我要当太空人,球体给了我爱吃的大嘴巴子。
立方体就这样飞走了
这就是物体在不受重力影响下的场景,那受重力影响就和我们现实生活差不多在这里就不说了,我们接着往下看:
- Is Kinematic: 物体是否受到运动学的影响,除了重力,运动学也是物理特性之一。
注:IsKinematic = false 是受到运动学影响,IsKinematic = true 是不受影响
我们来接着实验 :还是立方体和球体,我们让立方体不受运动学影响即勾上 Is Kinematic 选项
立方体说:我不想当太空人了,我要当GTA(侠盗猎车手)里的树,能把我撞倒算你厉害 。
- 碰撞检测:离散的是节省性能、非连续性的检测 ,如果有高速物体产生碰撞,那么有可能检测不到这次碰撞;持续、连续动态就是连续性检测但更耗费性能。Continuous Speculative 中间状态,性能低于持续高于离散,
这是我们上个动图的截图
可以看到用离散的碰撞检测在高速下碰撞这次就没有检测到,球体都进到立方体里了。大家有没有想到CF里的卡箱子😃
- Constraints 冻结位置、冻结旋转 是控制 X、Y、Z轴局部的不受运动学影响和旋转,当然如果你都勾选上效果就和 Is Kinematic 一样了。
二、碰撞检测的产生与监听
1. 产生碰撞的条件
- 碰撞的两个物体都要有碰撞组件
- 两个物体其中的一个有刚体(Rigidbody),没有刚体就不会产生运动也就不会发生碰撞
- 碰撞检测脚本挂在两个物体的任意一个上都可以
碰撞组件有很多,比如:Mesh Collider网格碰撞器、Box Collider 立方体碰撞器、Terrain Collider 地形碰撞器、Sphere Collider球形碰撞器
比如图中我们挂载球形碰撞器,绿色边框 就是碰撞器的边框,我们也可以调节大小位置等参数
2. 做一个碰撞检测实例
我们先在资源商店导入免费资源:小编今天刚下的,资源还在
我们选择绿色的流星(Magic fire0)和爆炸物 (Explosion)
场景描述:流星落到地面上发生碰撞,检测到碰撞后流星销毁产生爆炸物,爆炸完后爆炸物销毁。
给 流星 Magic fire0 挂载 Sphere Collider球形碰撞器 和 Rigidbody刚体,这是碰撞检测产生的条件之一。
编写FireTest脚本,挂载到流星上用来做碰撞检测:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FireTest : MonoBehaviour
{
//创建一个爆炸的预设体
public GameObject Prefab;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
//监听发生碰撞: 只监听发生碰撞的一瞬间
private void OnCollisionEnter(Collision collision) //参数 collision 就是你碰撞到的物体的碰撞信息
{
//创建一个爆炸物体
Instantiate(Prefab, transform.position, Quaternion.identity); //参数: 预设体,爆炸位置是自身火焰位置,不旋转
//销毁自身(流星): 流星撞击地面爆炸物产生流星销毁
Destroy(gameObject);
//获取碰撞到物体看一下参数collision —— 打印一下物体名称,这里打印的是地面的名称
Debug.Log(collision.gameObject.name);
}
//持续碰撞中: 只要物体挨着就会执行该方法
private void OnCollisionStay(Collision collisionInfo)
{
}
//结束碰撞
private void OnCollisionExit(Collision other)
{
}
}
同时把爆炸物预设体挂载到FireTest脚本,就是我们在脚本里写的 Prefab 预设体。
这里流星撞击地面销毁后爆炸物还没有销毁,我们在编写销毁爆炸物的脚本 ExplosionTest 挂在爆炸物上 :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ExplosionTest : MonoBehaviour
{
float timer = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
//如果时间大于一秒就销毁爆炸物
timer += Time.deltaTime;
if (timer > 1)
{
Destroy(gameObject);
}
}
}
运行就是我们本篇开头演示的效果了,好了摸鱼结束下班小编要回家了,拜拜┏(^0^)┛