Unity2D - 2D平面内的碰撞检测判断

常用的碰撞检测有三种。

基础碰撞检测

第一种就是最基础的碰撞检测,两个碰撞体之间碰撞,会自动触发碰撞检测方法

cs 复制代码
private void OnCollisionEnter2D(Collision2D other) {
    // 开始碰撞
}

private void OnCollisionStay2D(Collision2D other) {
    // 碰撞过程中
}

private void OnCollisionExit2D(Collision2D other) {
    // 碰撞结束
}

如果碰撞双方有任意一个勾选Is Trigger 或碰撞双方均勾选Is Trigger,那么就不会执行上面的碰撞检测,而是执行OnTriggerEnter2D/Stay2D/Exit2D;

射线检测

对于上面的基础碰撞检测,只能满足一些简单的功能,复杂一点的检测,就不太好处理(但并不是不能处理)。

比如我们要做一款消逝的光芒2D版游戏,人物在跑酷过程中,会从一个屋顶跳跃到另一个屋顶,由于屋顶和屋顶之间的距离比较远,人物在跳跃时,很可能要经历下面这个阶段:跳过去,并在下落的过程中抓住屋檐,随后攀爬上去。我们希望,在人物下落的过程中,如果距离屋檐比较近,且按下空格键,也视为抓住了屋檐。

这个时候,如果仅凭借基础碰撞,就必须要求人物和屋檐发生碰撞,这样的判断过于严苛。当然我们也可以通过另一种方式实现。在人物原本的碰撞体外面,再添加更大的一层碰撞体,并勾选这个更大碰撞体为触发器。当触发器和屋檐发生碰撞检测并执行OnTriggerEnter2D/Stay2D/Exit2D方法时,就视为人物抓住了屋檐。

这种时候,选用射线检测不失为一种更好的方式。

射线检测很好理解,就是从物体上发射一条射线,被射线射中就说明发生了碰撞。

cs 复制代码
/**
 * origin    第一个参数是需要检测碰撞的对象,在消逝的光芒2D中,第一个参数就是玩家的位置
 * direction 第二个参数是射线的方向,比如检测玩家的正前方
 * distance  第三个参数是射线的长度
 * layerMask 第四个参数是射线会检测玩家和哪一层的碰撞
 */
public static RaycastHit2D Raycast(
    Vector2 origin,
    Vector2 direction,
    float distance,
    int layerMask
);

这里的距离要根据是实际情况来决定,比如设置的太短,碰撞双方就必须很近才会触发碰撞;如果设置的太长,有可能会出现玩家距离屋檐很远却可以攀到屋檐上

下面是一个实际的代码举例

cs 复制代码
RaycastHit2D collisionCheck = Physics2D.Raycast(
    capsuleCollider.bounds.center, 
    Vector2.left, 
    capsuleCollider.bounds.size.x / 2 + radius / 2, 
    LayerMask.GetMask("Ground")
);

上面这段代码的第一个参数是某个变量名为capsuleCollider的碰撞体中心,这行代码正在检测相对于这个中心的碰撞。第二个参数表明射线方向朝左。第三个参数表明射线的长度是capsuleCollider.bounds.size.x / 2 + radius / 2。这行代码的计算结果表示,以碰撞体中心为端点,以Vector2.left为射线,长度在[0, capsuleCollider.bounds.size.x / 2 + radius / 2]范围内,且属于Ground层(第四个参数)的其他物体会与当前物体发生碰撞检测

范围检测

除了射线检测,还有一种很像射线检测的方式,就是范围检测,它比射线检测还要灵活,可以在平面内的任意一个位置进行碰撞检测。

cs 复制代码
/**
 * point        平面内的点
 * radius       以point点为圆心的半径
 * layerMask    检测玩家和哪一层的碰撞
 */
public static Collider2D OverlapCircle(Vector2 point, float radius, int layerMask);

仍然以上面为例

cs 复制代码
Collider2D c = Physics2D.OverlapCircle(
    new Vector2(
        capsuleCollider.bounds.center.x - capsuleCollider.bounds.size.x / 2,
        capsuleCollider.bounds.center.y
    ), 
    0.1F, 
    LayerMask.GetMask("Ground")
);

第一个参数是一个Vector2,用来表示平面内的点;第二个参数是0.1F,表示以第一个参数为圆心的半径;属于Ground层(第三个参数)的其他物体会与当前物体发生碰撞检测

相关推荐
千年奇葩9 小时前
Unity性能优化之:利用CUDA加速Unity实现大规模并行计算。从环境搭建到实战案例
c++·人工智能·unity·游戏引擎·cuda
17岁的勇气12 小时前
Unity Shader unity文档学习笔记(二十二):雪地几种实现方式(1. 2D贴花式 2.3D曲面细分并且实现顶点偏移)
笔记·学习·unity·shader
科技快报1 天前
引入实时 3D 渲染技术,地平线与 Unity 开启车载交互空间化时代
3d·unity·交互
爱吃小胖橘1 天前
高效对象池设计:提升Unity性能的关键
开发语言·unity·c#·游戏引擎
沉默的记录者1 天前
unity 2021反向遮罩的毛边
unity·游戏引擎
沧海归城1 天前
Unity_Canvas_Canvas Scaler画布缩放器。
unity·游戏引擎
一只一只2 天前
Unity 3D笔记(进阶部分)——《B站阿发你好》
笔记·3d·unity·游戏引擎
yi碗汤园2 天前
【一文了解】八大排序-冒泡排序、选择排序
开发语言·前端·算法·unity·c#·1024程序员节
qq_205279052 天前
unity PS 给图片换透明底图,去除白色底图
unity
向宇it2 天前
【推荐100个unity插件】unity易于使用模块化设计的天空、体积云和天气系统——Enviro 3
游戏·3d·unity·c#·游戏引擎