前言
在Unity2D中,有多个Collider组件可用于进行碰撞检测和物体交互。以下是一些常用的Collider组件及其功能介绍:
- Box Collider 2D(盒碰撞器):创建一个矩形的碰撞器,可以通过设置大小属性来定义碰撞器的宽度和高度。
- Circle Collider 2D(圆形碰撞器):创建一个圆形的碰撞器,可以通过设置半径属性来定义圆的大小。
- Polygon Collider 2D(多边形碰撞器):创建一个自定义形状的碰撞器,可以通过添加多边形的顶点来定义一个复杂的碰撞形状。
- Edge Collider 2D(边缘碰撞器):创建一个由一系列直线段组成的碰撞器,用于定义边缘、墙壁或地图的碰撞形状。
- Capsule Collider 2D(胶囊碰撞器):创建一个胶囊形状的碰撞器,可以通过设置半径和高度属性来定义胶囊的大小。
- Composite Collider 2D(复合碰撞器):用于合并多个碰撞器为单个碰撞器,可以优化性能,尤其在大型地图等情况下。
以上是Unity2D中常用的Collider组件,每个碰撞器都有其特定的用途和适用场景。选择适当的碰撞器类型取决于你的需求,例如对象的形状、精确性要求和性能要求等。要在对象上添加Collider组件,可以通过Unity编辑器的组件面板或使用代码进行手动添加。碰撞器通常与刚体(Rigidbody)组件一起使用,以实现物体之间的物理交互和碰撞检测。
碰撞的检测方法
在Unity中,碰撞检测是指在场景中检测物体之间是否发生碰撞的过程。Unity提供了多种方式来进行碰撞检测:
刚体碰撞检测:通过给物体添加刚体组件(Rigidbody),可以启用物体之间的物理交互和碰撞检测。
当两个带有刚体组件的物体发生碰撞时,Unity会自动进行碰撞检测,并触发相应的碰撞事件(如OnCollisionEnter、OnCollisionStay、OnCollisionExit等),供开发者处理。
Trigger触发器:Trigger是一种特殊的碰撞器(如Collider组件的isTrigger属性设为true),用于检测物体之间的接触,而不需要物体发生物理交互。
当一个物体与Trigger碰撞器接触时,会触发相应的事件(如OnTriggerEnter、OnTriggerStay、OnTriggerExit等),供开发者处理。
物理射线检测:使用物理射线(Physics.Raycast、Physics2D.Raycast)可以发射一条射线来检测是否与场景中的物体发生碰撞。根据射线与物体的交点,可以进行进一步的处理。
Overlap检测:使用Overlap系列函数(如Physics.CheckSphere、Physics.OverlapBox、Physics2D.OverlapCircle等)可以检测特定形状的区域内是否存在物体。这些函数可以返回与指定区域重叠的物体列表,供开发者进一步处理。
物理材质和碰撞层:通过为物体设置不同的物理材质和碰撞层,可以控制物体之间的碰撞检测和行为。物理材质可以影响碰撞的摩擦力、弹性等属性,碰撞层可以决定哪些物体会发生碰撞。
无论使用哪种碰撞检测方式,都需要在物体上添加对应的碰撞器组件(如Box Collider、Circle Collider等),以及处理相应的碰撞事件。开发者可以在碰撞事件中编写自定义的逻辑,例如触发特定的游戏事件、修改物体属性等。
使用触发器
1 | private void OnTriggerEnter2D(Collider2D col) |
在Unity中,2D触发器(Trigger)有以下几个相关的方法:
- OnTriggerEnter2D(Collider2D other):
- 作用:当有物体的碰撞器进入触发器时被调用。
- 参数:other是进入触发器的碰撞器。
- OnTriggerStay2D(Collider2D other):
- 作用:当有物体的碰撞器停留在触发器内时被调用(每一帧调用)。
- 参数:other是停留在触发器内的碰撞器。
- OnTriggerExit2D(Collider2D other):
- 作用:当有物体的碰撞器离开触发器时被调用。
- 参数:other是离开触发器的碰撞器。
刚性碰撞检测
Unity中有多种方法可以进行碰撞检测。
以下是一些常用的方法及示例:
OnCollisionEnter(Collision2D collision)
当物体首次接触到其他物体时触发该方法。
1 | void OnCollisionEnter2D(Collision2D collision) |
OnCollisionStay2D(Collision2D collision)
当物体与其他物体持续接触时触发该方法。
1 | void OnCollisionStay2D(Collision2D collision) |
OnCollisionExit2D(Collision2D collision)
当物体与其他物体分离时触发该方法。
1 | void OnCollisionExit2D(Collision2D collision) |
射线检测
使用射线检测两个点之间的碰撞情况。
1 | // 创建一个从 transform.position 开始的射线 |
周围检测
检测指定位置周围的碰撞体。
1 | Collider2D[] colliders = Physics2D.OverlapCircleAll( |
设置layer
下面的写法和上面实现了同样的逻辑。
1 | Collider2D[] colliders = Physics2D.OverlapCircleAll( |
根据名称获取layerMask
1 | int layerMask |
单个Layer
1 | int layerMask = 1 << LayerMask.NameToLayer("Enemy"); |
设置多个Layer
1 | int layerMask = 0; |
刚体(Rigid Body 2D)
不同于 3D 刚体,2D 刚体具有以下三种类型:
Dynamic
物体会受到力的影响移动和旋转。
Kinematic
不受力的影响,只能通过代码让其动起来。
能和 Dynamic 2D 刚体产生碰撞,但是不会动,只会进入碰撞检测函数,因此没有质量、摩擦系数等属性。
性能消耗较低,主要是使用代码处理移动和旋转。
Static
完全不动的需要检测碰撞的对象,相当于时无限质量不可移动的对象,性能消耗最小,只能和 Dynamic 2D 刚体碰撞。
和它类似的有只加碰撞器而不加刚体的物体,它们会和刚体物体产生碰撞,但是自己不会动。
总结:
Dynamic 动态刚体:受力的作用,要动要碰撞的对象。
Kinematic 运动学刚体:通过刚体 API 移动的对象,不受力的作用,可以和Dynamic碰撞。
Static 静态刚体:不动不受力作用的静态物体,可以和Dynamic碰撞。
Unity2D碰撞和触发
这里主要说2D游戏的碰撞和触发,和3D是不太一样的。
碰撞的生效条件
碰撞三要素:
- 碰撞发生在两个2D物体之间,两个物体设置了相互可碰撞(Layer Collision Matrix)。
- 碰撞双方都有碰撞体(都不能勾选触发器)。
- 发生碰撞的双方,至少一个是刚体(Rigidbody),另一个是刚体或运动学刚体,不能都是运动学刚体。
响应的事件
- OnCollisionEnter2D(Collision2D collision) 开始碰撞
- OnCollisionStay2D(Collision2D collision) 碰撞中
- OnCollisionExit2D(Collision2D collision) 碰撞分离
注意
方法都是带有2D,不带2D的是3D的碰撞事件不会被触发。
Edit
=> Project Settings...
只有勾选了可碰撞关系的才会碰撞。
触发的生效条件
触发的条件很宽松,有些是我们以为不能触发的实际也能触发的。
发生在两个2D物体之间,两个物体即使设置了不能碰撞也能触发。
双方其中一方设置了触发器,双方都会产生触发回调(即使没有设置为触发器的一方也能产生触发回调),不能双方都没有设置触发器。
即使双方都是运动学刚体也能触发。
响应的事件
- OnTriggerEnter2D(Collider2D col) 开始触发
- OnTriggerExit2D(Collider2D col) 触发中
- OnTriggerStay2D(Collider2D col) 触发分离
这样也是可以触发的