You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MonoGame中Ray与Rectangle碰撞检测功能异常求助

MonoGame射线与矩形碰撞检测异常问题

我在MonoGame中参考教程实现游戏碰撞检测算法时,遇到了射线(Ray)与矩形(Rectangle)碰撞检测的异常问题:

  • 当射线起点为(1,1)、方向随鼠标移动时,检测功能正常
  • 但将射线起点移至(100,1)附近时,返回的接触点虽位于矩形上,却完全不在射线轨迹上;且当射线沿矩形放置时,无法检测到碰撞

以下是碰撞检测的核心代码:

public static bool RayVsRect(Vector2 rayOrigin, Vector2 rayDirection, Rectangle rect,
            out Vector2 contactPoint, out Vector2 contactNormal, out float tHitNear)
{
    contactPoint = Vector2.Zero;
    contactNormal = Vector2.Zero;
    tHitNear = 0;

    if (rayDirection.X == 0) rayDirection.X = float.Epsilon;
    if (rayDirection.Y == 0) rayDirection.Y = float.Epsilon;

    Vector2 tNear;
    Vector2 tFar;

    tNear = (rect.Location.ToVector2() - rayOrigin) / rayDirection;
    tFar = (rect.Location.ToVector2() + rect.Size.ToVector2() - rayOrigin) / rayDirection;

    if (tNear.X > tFar.X) Ray2D.Swap(ref tNear.X, ref tFar.X);
    if (tNear.Y > tFar.Y) Ray2D.Swap(ref tNear.Y, ref tFar.Y);

    if (tNear.X > tFar.Y || tNear.Y > tFar.X) return false;

    tHitNear = MathF.Max(tNear.X, tNear.Y);
    float tHitFar = MathF.Min(tFar.X, tFar.Y);

    if (tHitFar < 0 || tHitNear > 1) return false;

    contactPoint = rayOrigin + tHitNear * rayDirection;

    Debug.WriteLine($"Origin: {rayOrigin}, Direction: {rayDirection}, Point: {contactPoint}");

    if (tNear.X > tNear.Y)
    {
        if (rayDirection.X < 0)
            contactNormal = Vector2.UnitX;
        else
            contactNormal = -Vector2.UnitX;
    }
    else if (tNear.X < tNear.Y)
    {
        if (rayDirection.Y < 0)
            contactNormal = Vector2.UnitY;
        else
            contactNormal = -Vector2.UnitY;
    }

    return true;
}

我推测问题可能源于C#与教程所用C++的差异,比如处理除以0时,教程中得到无穷大而我这里得到NaN,因此添加了将rayDirection的X/Y设为float.Epsilon的处理,但未解决问题。即使忽略该问题,碰撞检测也仅在部分方向正常,部分方向完全失效。两次测试中射线均朝X、Y正方向指向矩形,但结果截然不同。

内容的提问来源于stack exchange,提问作者SaloCh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:40:28