碰撞检测
碰撞产生的必要条件是两个物体都有碰撞器(Collider),至少一个物体有刚体(rigidbody)
有了刚体才会模拟受到力的作用
Mass - 质量 默认为千克
Drag - 阻力 0表示没有阻力
Angular Drag - 扭矩阻力 阻碍旋转的阻力 0表示没有阻力
Is Kinematic - 如果启动此选项,则对象将不会被物理引擎驱动,只能通过Transform操作
Interpolate - 插值运算 让刚体物体运动更平滑
Interpolate 根据前一帧
Extrapolate 根据后一帧
一般于物理帧更新间隔过大的场景
Collision Detection - 碰撞检测模式
用于防止快速移动的对象穿过其他对象而不检测碰撞
Discrete - 离散检测
Continuous - 连续检测
Continuous Dynamic - 连续动态检测
Continuous Speculative - 连续推测检测
性能消耗:连续动态>连续推测>连续>离散

Constraints - 约束 对刚体运动的限制
对什么轴进行约束就在什么轴上不会产生位移,旋转同理
3D碰撞器的类型
盒装,球状,胶囊,网格,轮胎,地形
Is Trigger 是否是触发器,如果启用此属性,则该碰撞体将用于触发事件,并被物理引擎忽略,主要用于进行没有物理效果的碰撞检测
Center 碰撞器中心点相对物体的偏移
异形物体使用多种碰撞体组合 刚体的子对象碰撞器参与碰撞检测
网格碰撞器 加了刚体的网格碰撞器必须勾选Convex才能模拟力的租用
轮胎碰撞器 必须在根物体(车本体父对象)上添加刚体才会生效
物理材质
Dynamic Friction - 动摩擦力 越小动摩擦力越小
Static Friction - 静摩擦力
Bounciness - 弹性 越大弹性越好
Friction Combine 碰撞对象摩擦力组合方式
unce Combine 碰撞对象弹力组合方式
检测函数
public class Lesson16 : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
//碰撞和触发响应函数属于特殊生命周期函数,也是通过反射调用
#region 物理碰撞检测响应函数
//碰撞触发时会自动调用这个函数
private void OnCollisionEnter(Collision collision)
{
//碰撞到的对象的碰撞器信息
//collision.collider
//碰撞对象的依附对象
//collision.gameObject
//碰撞对象的依附对象的位置信息
//collision.transform
//触碰点相关
//点数
//collision.contactCount
//接触点坐标
//ContactPoint[] pos = collision.contacts;
print("被" + collision.gameObject.name + "撞到了");
}
//碰撞结束分离时自动调用的函数
private void OnCollisionExit(Collision collision)
{
print("和" + collision.gameObject.name + "分开了");
}
//碰撞发生过程中一直调用的函数
private void OnCollisionStay(Collision collision)
{
print("和" + collision.gameObject.name + "正在接触");
}
#endregion
#region 触发器检测响应函数
//接触时会调用
private void OnTriggerEnter(Collider other)
{
print("被" + other.gameObject.name + "触发");
}
//分开时调用
private void OnTriggerExit(Collider other)
{
print("和" + other.gameObject.name + "分开了");
}
//接触过程中一直调用
private void OnTriggerStay(Collider other)
{
print(other.gameObject.name + "正在触发");
}
#endregion
//父对象刚体上面没有挂载碰撞器而子对象上挂载碰撞器时,如果把碰撞或触发响应代码相关脚本挂载在子对象身上时
//此时碰撞或触发响应相关代码不会有响应,只能把相关脚本挂载到父对象上
//碰撞和触发响应函数都可以写成虚函数,在子类中去重写逻辑
//一般会把想重写的碰撞和触发响应函数都写成protected
}
public class Lesson17 : MonoBehaviour
{
Rigidbody rigidBody;
// Start is called before the first frame update
void Start()
{
#region 刚体自带的添加力的方法
//给刚体加力的目的是为了让它有一个速度
//首先要获取刚体组件
rigidBody = GetComponent<Rigidbody>();
//添加力
//相对世界坐标添加力
//相对世界坐标系Z轴正方向加力
rigidBody.AddForce(Vector3.forward);
//相对本地坐标添加力
rigidBody.AddRelativeForce(Vector3.forward);
//添加扭矩力,让其旋转
//相对世界坐标系
rigidBody.AddTorque(Vector3.forward);
//相对本地坐标系
rigidBody.AddRelativeTorque(Vector3.forward);
//直接改变速度
//相对世界坐标系
rigidBody.velocity = Vector3.forward;
//模拟爆炸效果
//第一个参数是力的大小,第二个是爆炸中心,第三个是爆炸半径
//仅影响挂载了该脚本的物体
rigidBody.AddExplosionForce(10, Vector3.zero, 10);
#endregion
#region 力的不同模式
//第二个参数为力的模式,主要作用是影响计算过程,最终得出的移动速度不同
rigidBody.AddForce(Vector3.forward,ForceMode.Acceleration);
//动量定理 Ft = mv , v =Ft/m
//不忽略时间的话,时间按物理帧间隔时间算,t=0.02s;
//Acceleration
//给物体一个持续的加速度,忽略其质量
//质量默认为1
//Force
//给物体加一个持续的力,与物体的质量有关
//Impulse
//给物体添加一个瞬时的力,与物体质量有关,忽略时间,默认时间为1
//VelocityChange
//给物体添加一个瞬时速度,忽略质量和时间,都默认为1
#endregion
#region 力场脚本
//Constant Force
#endregion
//刚体的休眠
//判断刚体是否休眠
if(rigidBody.IsSleeping())
{
//唤醒刚体
rigidBody.WakeUp();
}
}
}

浙公网安备 33010602011771号