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层(第三个参数)的其他物体会与当前物体发生碰撞检测

相关推荐
NIKITAshao9 小时前
Unity URP Volume组件详解(笔记)
unity·游戏引擎
lingxiao1688811 小时前
WebApi详解+Unity注入--下篇:Unity注入
unity·c#·wpf
世洋Blog12 小时前
面经-CPU、内存、GPU的性能优化
unity·性能优化
lingxiao1688814 小时前
WebApi详解+Unity注入--中篇:.net core的WebAPI
unity·c#·.netcore
weixin_4239950017 小时前
unity 处理图片:截图,下载,保存
java·unity·游戏引擎
呆呆敲代码的小Y20 小时前
【Unity实战篇】| 游戏轮播图效果,多种实现思路及完整教程
游戏·unity·游戏引擎·实战·游戏开发·轮播图·u3d
示申○言舌1 天前
Unity高性能参数差异化URP Shader圆角圆环UI进度条
ui·unity·游戏引擎·圆环进度条·参数差异化·材质参数独立·圆角圆环
一只一只1 天前
Unity之协程
unity·游戏引擎·协程·coroutine·startcoroutine
NIKITAshao2 天前
Unity 跨项目稳定迁移资源
unity·游戏引擎
sindyra2 天前
Unity资源内存管理与释放
unity·游戏引擎·资源管理·资源释放·内存释放