手册:接触判定与射线检测(RayCast)

这个手册将详细讲解对象的墙体判定(CollisionShape2D)与瓦片以及其他对象的墙体判定之间的接触相关细节设置。

墙体判定的接触判定概要与射线检测(RayCast)

ACTION GAME MAKER 的墙体判定会根据对象的墙体判定(CollisionShape2D)大小生成一个矩形的判定生成区域,并从该区域的四条边向外发射用于判定的法线(称为 Ray)来进行检测。
Ray 可以理解为以固定间隔发射的、不可见的判定“子弹”。当这些“子弹”接触到其他墙体判定或瓦片时,就会被判定为“命中”。这一过程称为射线检测(RayCast)

关于射线检测的设置

射线检测是可以在条件 「与对象墙体判定接触」「与瓦片接触」「与坡属性瓦片接触」 中配置的参数。

射线数量(ray_number):

可用整数进行设置。射线数量表示判定生成区域每一条边上发射的射线数
射线会根据边长等间距排列
例如,当一条边长为 24 pixel 时:

  • 射线数量为 3 时,每 12 pixel 生成一条判定;
  • 射线数量为 4 时,每 8 pixel 生成一条判定。

射线越多,判定越可靠,但也可能带来更高的处理负载,请注意性能影响。

判定方式(detect_method):

可从 Any(任意一个)All(全部) 两种方式中选择。

  • Any:只要生成的射线中有一条接触成功,就判定为“已接触”。
  • All:只有当所有射线都接触成功时,才判定为“已接触”。
    如下图所示,当只与角部接触时:
  • Any 会判定为“接触中”;
  • All 会判定为“未接触”。

射线长度(ray_length):

可用 float 值指定,表示射线会发射到多远的像素距离
换句话说,就是指定相隔多少 pixel 以内仍判定为接触

主要需要在判定上下移动的升降台等对象时进行调整。
例如向下移动的升降台会按“升降台移动 → 角色跟随移动”的顺序处理,因此会出现一瞬间角色与台子略微分离的情况。此时如果射线过短,就可能被判定为“未接触”。

另一方面,如果射线设置得过长,又会出现明明已经分离却仍被判定为接触的问题。
因此通常应根据 GameObject > CharacterBody2D > Floor > Snap Length(吸附距离) 的长度,以及所使用升降台对象的速度来进行调整。

射线偏移(ray_offset):

可用 float 值指定,用于设置射线生成时从角落向内偏移多少像素
如前所述,判定生成区域一定是矩形,但碰撞形状可能是胶囊、多边形或多个碰撞组合等,不一定是矩形
通过偏移可以让射线检测更贴近实际的碰撞形状。

偏移值表示从每条边两端向内的 pixel 数
也就是说,当一条边长为 24 pixel 且发射 3 条射线时,会如下图所示:

坐标空间(coord_space):

这是用于设置以哪种坐标空间为基准来判断接触方向的选项。
主要用于对象在旋转状态下发生接触时,决定应如何判定方向。

例如:一个旋转 180°、上下颠倒的对象接触地面时,
接触方向应该算作“下”还是“上”?
根据你的需求,答案会不同。
如果要判定“撞到头了”,就需要判定为“上”;
如果只是想判定着地,那么判定为“下”更合适。
此外也存在“对象本身不旋转,只有碰撞体旋转”的情况。

该设置可从 GlobalLocal is Game ObjectLocal is Collision 三种模式中选择。
下面用两张图来说明:

① 游戏对象本身旋转 45° 并与地面接触时

② 游戏对象保持不动,仅碰撞体旋转 90° 并与地面接触时

  1. Global(全局坐标:以整个游戏场景的坐标为准)
    以游戏对象原点与接触对象原点的全局坐标进行方向判定。
    完全不考虑旋转,因此在图①与图②中都会判定为“下”发生接触。

  2. Local is Game Object(以游戏对象的本地坐标为准)
    以游戏对象的本地坐标进行方向判定。
    也就是说,只考虑游戏对象自身的旋转

    • 图①中判定为“右”和“下”发生接触;
    • 图②中判定为“下”发生接触。
  3. Local is Collision(以墙体判定/碰撞体的本地坐标为准)
    以碰撞体的本地坐标进行方向判定。
    也就是说,只考虑碰撞体自身的旋转

    • 图①中判定为“右”和“下”发生接触;
    • 图②中判定为“右”发生接触。

这是一个稍微有点难理解的概念,但只要掌握后,你就能做出符合自己预期的精确判定。

「いいね!」 2