@[TOC]物理引擎
四.物理引擎
1.碰撞体(Collider)
1.1 属性
Edit Collider:编辑碰撞体的大小Is Trigger:是否是触发器Material:物理材质Center:中心点位置Size:缩放比例Radius:半径…
1.2 碰撞体的作用
碰撞射线
1.3 回调方法
方法定义作用OnMouseEnter()鼠标进入碰撞体时触发一次OnMouseOver()鼠标在碰撞体内停留时持续触发,每帧一次OnMouseExit()鼠标离开碰撞体时触发一次OnMouseDown()鼠标在碰撞体范围内按下的时候触发一次OnMouseDrag()鼠标在拖拽的时候持续触发,每帧一次OnMouseUp()鼠标在抬起的时候触发一次OnMouseUpAsButton()鼠标在碰撞体范围内抬起的时候触发一次
1.4 获取范围内碰撞体
方法作用Physics.OverlapBox()获得立方体形范围内的所有碰撞体Physics.OverlapSphere()获得球体形范围内的所有碰撞体Physics.OverlapCapsule()获得胶囊体形范围内的所有碰撞体
1.5 碰撞
碰撞三要素碰撞双方都有Collider组件,并且不是Trigger至少有一方有rigidbody组件双方需要保持相对运动回调方法方法作用OnCollisionEnter(Collision collision)碰撞开始时触发一次OnCollisionStay(Collision collision)碰撞过程中持续触发,每帧一次OnCollisionExit(Collision collision)碰撞结束时触发一次
collision 是碰撞的信息
// 存有所有接触点的数组 Vector3 point = collision.contacts[0].point; // 获取到和哪一个碰撞体发生碰撞了 Collider c = collision.collider;
1.6 设置物理引擎相关参数
Edit -> Project Settings -> Physic
属性作用Gravity重力Default Material默认的物理材质Layer Collision Matrix层之间的碰撞矩阵,控制层之间是否能够碰撞
2.刚体(Rigibody)
完成逼真的物理效果的物理组件
2.1 属性
Mass:质量Drag:阻力Angular Drag:角阻力Use Gravity:使用重力Is Kinematic:开启动力学,不受任何力Interpolate:插值none:无interpolate:内插值extrapolage:外插值Collision Detection:碰撞检测模式Discrete:离散检测,精度不高,性能消耗低,检测不到极端情况Continuous:连续检测,提高检测精度,性能消耗大Continuous Dynamic:连续动态检测,提高检测精度,性能消耗大Constraints 约束
2.2 代码中的属性和方法
Inspector面板上显示的属性都可以用代码获取到
属性方法作用mass重量drag阻力angularDrag角阻力useGravity使用重力isKinematic开启动力学interpolation插值 RigidbodyInterpolation枚举collisionDetectionMode碰撞检测模式 CollisionDetectionMode枚举constraints约束 RigidbodyConstrains枚举velocity速度 Vector3类型(初速度)angularVelocity角速度 Vector3类型(初速度)AddForce(Vector3 force);给刚体添加一个力AddExplosionForce(float explosionForce, Vector3 explosionPosition, float explosionRadius)给刚体添加一个爆炸力(炸自己)。想别的刚体也受到爆炸力影响,需要给别的刚体也添加一个爆炸力
2.3 层检测与层屏蔽
// 已知cube1是第9层,cube2是第10层 // 层检测 LayerMask mask = 1 << 10 | 1 << 9; // 获取第9和10层 LayerMask mask = 1 << LayerMask.NameToLayer(“cube1”); // 获取第9层 LayerMask mask = GetMask(params stirng[] layerNames); // 层屏蔽 mask = ~mask; // 按位取反mask
3.触发(Trigger)
触发会用到Collider的IsTrigger
触发三要素两个物体都有碰撞体至少有一个带有刚体至少有一个是触发器触发的回调回调定义作用OnTriggerEnter(Collider collider)触发开始时触发一次OnTriggerStay(Collider collider)触发持续过程中,每帧调用OnTriggerExit(Collider collider)结束触发时触发一次
4.射线(Ray)
射线包含起点和方向,Unity中可以限定射线长度(Vector3的长度)有Collider的物体会被射线打中,碰撞体和触发器都能被触发系统提供了一个层叫Ignore Raycast,用于忽略射线// 生成射线 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); // 声明一个RaycastHit,用来存储射线打中的物体的信息,是一个结构体,值类型 RaycastHit hit; // 发射射线 // true:打中物体了 false:没有打中物体 bool result = Physics.Raycast(ray, out hit); if (result) { // 获取射线打中的物体 hit.collider; // 获取射线打中的坐标(世界坐标) hit.point; } // 发射一条射线,返回射线打中的所有物体 RaycastHit[] hits = Physics.RaycastAll(ray);
5.动态生成游戏物体
// 生成谁 public GameObject plane; // 在哪生成 // 旋转是什么 Instantiate(Object obj, Transform parent); // 游戏对象生成并绑定父物体 Instantiate(Object obj, Transform position, Quaternion q) // 在指定的位置position使用指定的旋转q生成游戏对象obj 代码读取 Resources 中的Prefab// 资源路径一定是 /Resources/ 或其子文件夹中,否则读取不到 // 示例中放在了 /Resources/Bullet/bullet1 GameObject _bulletPre; private void Start(){ // Load()的返回值是Object,所以要向下转型 _bulletPre = Resources.Load(“Bullet/bullet1”) as GameObject; // 使用泛型的返回值是 T 类型,可以不用转型 _bulletPre = Resources.Load(“Bullet/bullet1”); // 加载文件夹中所有的 T 类型资源 GameObject[] objs = Resources.LoadAll(“Bullet”); }