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
相关产品推荐
相关产品推荐

