本帖最后由 da11 于 2021-12-3 18:24 编辑
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 物理引擎讲解类
/// </summary>
public class PhysicsEngineDemo : MonoBehaviour
{
/* 什么是物理引擎:
* · 带有刚体组件的游戏物体
* Add Component--physics--Rigidbody
* · 刚体组件可使游戏对象受物理引擎控制,在受到外力时产生真实世界中的运动。
* · 碰撞器(Collider):让物体有了物理的边界,只有知道了物理的边界,才可以开始模拟物理中力的作用!
* · 物理引擎(Rigidbody(刚体)):模拟真实世界中物理物理特性的引擎。
*
* 在游戏物体挂载上Rigidbody(刚体)组件即有物理引擎效果,需配合上碰撞器使用
* 注意:手游(硬件性能一般)的设备,碰撞器检测一般使用Box Collider检测,只有检测8个面,节省资源。
* 碰撞器检测的最精细为Mesh Collider检测,这是根据模型的点和面来检测的,消耗CPU资源巨巨巨巨大。
* 如想高精度模拟,优先选择原模型最贴切的碰撞器类型,高精度模拟一般使用Sphere Collider检测,这是根据圆形的面数检测。这是系统自带最高精度的碰撞器。
* 实在需求需要高精度模拟,才使用Mesh Collider碰撞器。
* 使用Mesh Collider碰撞器时,勾上Convex可以优化模型点数和面数,从而尽量降低消耗的资源。
* Box Collider碰撞器可以设置碰撞器的中心点(x,y,z)和碰撞器的大小(x,y,z).
* Sphere Collider碰撞器可以设置碰撞器的中心点(x,y,z)和碰撞器的缩放大小(x,y,z).
*
* Rigidbody(刚体)组件的属性值
* · Mass-质量,描述物体的质量,多物体有Rigidbody组件的时候使用。
* · Drag-阻力,广泛意义上的阻力,当受力移动时物体受到的空气阻力。
* 0表示没有空气阻力,极大时可使物体停止运动,通常砖头0.001,羽毛设置为10
* · Angular Drag-角阻力:当受扭力旋转时物体受到的空气阻力。
* 0表示没有空气阻力,极大时可使物体停止运动
* · Use Gravity-使用重力:若激活,则物体受重力影响。
* · Is Kinematic-是否是运动学(霸体):若激活,该物体不再受物理引擎控制
* 而只能通过变换组件来操作。
*
* · Interpolate-插值:用于缓解刚体运动时的抖动。
* None-无--不应用插值
* Interpolate--内插值:基于上一帧的变换来平滑本帧变换。
* Extrapolate--外插值:基于下一帧的预估变换来平滑本帧变换。
*
* · Collision Detection-碰撞检测:碰撞检测模式。
* 快速移动的刚体在碰撞时有可能互相穿透,可以设置碰撞检测频率,
* 但频率越高对物理引擎性能影响越大。
*
* Discrete--不连续:不连续碰撞检测。适用于普通碰撞(默认模式)。
* Continuous--连续:连续碰撞检测。
* Continuous Dynamic--动态连续:连续动态碰撞检测,适用于高速物体。
*
* · Constraints-约束:对刚体运动的约束
* Freeze Position--冻结位置:刚体在世界中沿所选X,Y,Z轴的移动,将无效。
* Freeze Rotation--冻结旋转:刚体在世界中沿所选X,Y,Z轴的旋转,将无效。
*
* 碰撞条件
* · 两者具有碰撞组件(碰撞器组件)
* · 运动的物体具有刚体组件。
*
* 碰撞三阶段脚本周期,须有Collision类型的形参
* · 当进入碰撞时执行
* void OnCollisionEnter(Collision collOther)
* · 当碰撞体与刚体接触时每帧执行
* void OnCollisionStay(Collision collOther)
* · 当停止碰撞时执行
* void OnCollisionExit(Collision collOther)
*
* 碰撞器简介
* · 带有碰撞器组件,且Is Trigger属性被勾选的物体。
* · 现象:无碰撞效果
*
* · 注意:带有碰撞器组件,且Is Trigger属性被勾选的物体是触发器,
* 带有碰撞器组件,Is Trigger属性 没有 被勾选的物体是碰撞器!
*
* 触发条件
* · 两者具有碰撞器(Collider)组件
* · 其中之一带有刚体(Rigidbody)组件,(都带有刚体(Rigidbody)组件也算满足条件)
* · 其中之一勾选Is Trigger属性,(都勾选Is Trigger属性也会满足条件233)
*
* 触发三阶段
* · 当碰撞器(Collider)进入触发器时执行
* void OnTriggerEnter(Collider cldOther)
*
* · 当碰撞器(Collider)与触发器接触时每帧执行
* void OnTriggerStay(Collider cldOther)
*
* · 当停止触发时执行
* void OnTriggerExit(Collider cldOther)
*/
//当满足碰撞接触条件!!这个逻辑重点
//当碰撞接触第一帧执行以下脚本生命周期方法
private void OnCollisionEnter(Collision collision)
{
//事件参数类
//形参collision 获取对方的碰撞器组件,或者直接获取 对方 的组件collision.collider.GetComponent<?>
print("check--OnCollisionEnter: "+ collision.collider.name);
//碰撞器的参数可以获得碰撞点数组
print(collision.contacts.Length);
//获取第一个接触点
//ContactPoint CP = collision.contacts[0];
//获取第一个接触点的 世界 坐标
//print(CP.point);
//获取碰撞的所有接触点
int CPL = collision.contacts.Length;
for (int i = 0; i < CPL -1; i++)
{
print(collision.contacts.point);
}
//获取接触面法线(直白点说就是撞的方向)
Vector3 CNormal = collision.contacts[0].normal;
//collision.transform.position = new Vector3(0, 0, 0);
//获取对方的GameObject组件,并使用Object.Destroy销毁对方游戏物体
//Object.Destroy(collision.collider.gameObject);
}
//当满足触发条件!!
//当触发第一帧执行以下脚本生命周期方法
private void OnTriggerEnter(Collider colliderVar)
{
//形参colliderVar 就是对方的碰撞器组件,直接获取 对方 的组件colliderVar.GetComponent<?>
print("check--OnTriggerEnter: " + colliderVar.name);
}
/*
public void FixedUpdate()
{
//Time.frameCount 属性是查看当前过了多少帧帧
print(Time.frameCount + "--" + this.transform.position);
this.transform.Translate(0, 0, Time.deltaTime * movespeed);
}
*/
//注意:如果movespeed物体移动速度过快(一般大于200以上),碰撞检测方法(OnTriggerEnter、OnCollisionEnter)将失效
//解决方案:游戏开始时,使用射线检测
}
|