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

Unity基于Physics.Raycast的寻路系统检测结果不一致问题

核心问题排查与修复

1. 最关键错误:Physics.Raycast 参数使用错误

Unity内置Physics.Raycast的第二个参数要求传入射线方向向量,你当前代码直接传入了目标点的坐标值,导致射线方向完全不符合预期,仅在坐标值刚好和方向值匹配时才能正常检测,这是你单侧射线穿透的核心原因。

2. 次要错误:坐标体系混用

生成候选点、调用射线检测时混用transform.localPosition和transform.position,如果当前物体存在父物体位移,会直接导致候选点位置、射线起点/终点坐标不匹配。

3. 可选优化:避免射线起点卡在碰撞体内

如果射线起点刚好处于碰撞体内部,Unity默认会忽略该碰撞体的检测,可增加微小偏移避免漏检。


修正后代码

射线检测函数修正

// Check if enemy can see player without any obstructions
bool CanSeeDestination(Vector3 startingPoint, Vector3 destination)
{
    // 计算从起点指向终点的方向向量
    Vector3 direction = destination - startingPoint;
    // 检测距离取两点实际距离,避免多余检测
    float detectDistance = direction.magnitude;
    // 起点微小偏移,避免卡在碰撞体内导致漏检
    Vector3 rayOrigin = startingPoint + direction.normalized * 0.1f;

    if(Physics.Raycast(rayOrigin, direction.normalized, detectDistance, layerMask))
    {
        Debug.DrawLine(startingPoint, destination, Color.red);
        return false;
    } 
    else
    {
        Debug.DrawLine(startingPoint, destination, Color.green);
        return true;
    }
}

寻路逻辑坐标统一修正

将所有transform.localPosition替换为transform.position,统一使用世界坐标:

// 生成候选点时用世界坐标
surroundingPoints.Add(new Vector3(transform.position.x + offsetI, stepOverHeight.y, transform.position.z + offsetK));

// 调用射线检测时用世界坐标作为起点
if(CanSeeDestination(transform.position, surroundingPoints[m]) && CanSeeDestination(surroundingPoints[m], player.transform.position))

额外排查项

  • 确认障碍物的层级未被你配置的层掩码排除(你当前排除的是第3层玩家层,确保障碍物不在该层)
  • 确认障碍物碰撞体的Y轴范围和射线的Y坐标(stepOverHeight.y)匹配,避免射线刚好从碰撞体上下方穿过
  • 如果障碍物使用了触发器碰撞体,可在项目物理设置中开启Queries Hit Triggers,或者在射线参数中增加QueryTriggerInteraction.Ignore明确配置触发器检测规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 05:39:01