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

相关推荐
心前阳光5 小时前
Unity WebGL文本输入
unity·游戏引擎·webgl
天涯过客TYGK6 小时前
unity A星寻路
unity·游戏引擎
KhalilRuan6 小时前
Unity Demo——3D平台跳跃游戏笔记
笔记·游戏·unity·游戏引擎
ttod_qzstudio1 天前
Unity中使用EzySlice实现模型切割与UV控制完全指南
unity
南無忘码至尊1 天前
Unity 实现与 Ollama API 交互的实时流式响应处理
unity·游戏引擎·交互
平行云1 天前
如何实现UE程序大并发多集群的像素流部署
unity·ue5·图形渲染
向宇it2 天前
【unity小技巧】在 Unity 中将 2D 精灵添加到 3D 游戏中,并实现阴影投射效果,实现类《八分旅人》《饥荒》等等的2.5D游戏效果
游戏·3d·unity·编辑器·游戏引擎·材质
向宇it2 天前
Unity Universal Render Pipeline/Lit光照材质介绍
游戏·unity·c#·游戏引擎·材质
__water3 天前
RHA《Unity兼容AndroidStudio打Apk包》
android·unity·jdk·游戏引擎·sdk·打包·androidstudio
两水先木示3 天前
【Unity3D】微信小游戏适配安全区域或胶囊控件(圆圈按钮)水平高度一致方案
unity·微信小游戏·安全区域·ui适配·胶囊控件·safearea