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

相关推荐
3D霸霸1 小时前
Unity渲染管线 Global Volume 及 Post-processing
unity·游戏引擎
benben0445 小时前
Unity3D仿星露谷物语开发66之NPC存档
游戏·ui·unity·c#·游戏引擎
龚子亦21 小时前
【数字人开发】Unity+百度智能云平台实现短语音文本识别功能
百度·unity·游戏引擎
神码编程1 天前
【Unity】MiniGame编辑器小游戏(二)扫雷【Minesweeper】
unity·编辑器·扫雷
RocketJ2 天前
推荐使用的Unity插件(行为树Behavior )
unity·游戏引擎
Tatalaluola2 天前
【Quest开发】初始项目环境配置
unity·游戏引擎·vr
future14122 天前
FairyGUI学习
学习·游戏·ui·unity
点量云实时渲染-小芹3 天前
UE/Unity/Webgl云渲染推流网址,如何与外部网页嵌套和交互?
unity·webgl·webgl云渲染网页交互·点量云流
ynxw3 天前
Unity AR 实现模型交互
android·unity·ar·交互