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

Unity中Physics.Raycast始终返回false问题求助

问题:Physics.Raycast始终返回false

你当前的代码存在多处核心逻辑错误,即使对象挂载了碰撞体也会导致射线检测完全失效:

核心错误原因
  • Raycast参数传参完全错误:Physics.Raycast的第二个参数要求传入世界空间下的射线方向向量,你直接传入了target.transform.position(目标的世界坐标点)。这个参数只有当射线起点cannon.position刚好在世界原点(0,0,0)时方向才会正确,只要cannon不在世界原点,射线方向会完全偏移,根本不可能指向目标。
  • 层掩码定义了但未生效:你声明了layerMask变量,但是调用Physics.Raycast时没有传入这个参数,层过滤逻辑完全不生效。另外你当前的掩码逻辑是忽略第8层所有碰撞体,需要确认第8层不是玩家/敌人所在的层,否则会直接过滤掉检测目标。
  • 自身碰撞体干扰:如果作为射线起点的cannon位置在自身挂载的BoxCollider/MeshCollider包围盒内部,射线发射后第一个命中的会是自己的碰撞体,无法检测到远处目标。
  • 碰撞体配置异常:
    • 如果碰撞体勾选了Is Trigger,默认情况下射线不会检测触发器碰撞体
    • 非凸的MeshCollider和非运动学Rigidbody搭配时碰撞检测会失效
    • Physics面板的层碰撞矩阵如果取消了对应层的碰撞勾选,射线也会忽略对应层的碰撞体
  • 调试逻辑错误:你只在射线命中时才绘制Debug线,根本看不到射线实际的发射方向,无法定位偏移问题。

修复方案
  • 修正射线方向计算:方向必须是从起点指向目标的向量,即target.transform.position - cannon.position,同时传入你定义的range作为射线最大距离,避免不必要的远距离检测。
  • 把layerMask传入Raycast参数,确认层逻辑正确:如果要忽略自身碰撞体,把自身对象放到单独的层,在掩码中排除该层即可。
  • 调整cannon的位置,把它挪到自身碰撞体的包围盒外侧,避免射线起点埋在自身碰撞体里。
  • 检查碰撞体配置:取消不必要的Is Trigger勾选,非运动学刚体挂载的MeshCollider必须勾选Convex,确认Physics面板中对应层的碰撞检测是开启状态。
  • 调整调试逻辑,不管射线是否命中都绘制调试线,方便在Scene窗口观察射线方向。

修正后的核心代码参考
void FixedUpdate()
{
    if(gameObject.GetComponent<EnemyController>()){
        checkIfTurn = gameObject.GetComponent<EnemyController>().isTurn;
    }else if(gameObject.GetComponent<PlayerController>()){
        checkIfTurn = gameObject.GetComponent<PlayerController>().isTurn;
    }   

    // 计算正确的射线方向:起点指向目标
    Vector3 rayDir = (target.transform.position - cannon.position).normalized;
    // 传入方向、距离、层掩码,指定检测触发器规则
    bool isHit = Physics.Raycast(cannon.position, rayDir, out hit, range, layerMask, QueryTriggerInteraction.UseGlobal);
    
    // 调试线:命中就画到命中点,没命中就画到最大射程位置
    Debug.DrawLine(cannon.position, isHit ? hit.point : cannon.position + rayDir * range, isHit ? Color.red : Color.white, 2.5f);
    
    if (isHit){
        Debug.Log("Hit tag " +  hit.collider.tag + " Target Tag " + target.tag + " Has Shoot " + hasShoot + " is my turn " + checkIfTurn);
        if( hit.collider.tag == target.tag  && !hasShoot && checkIfTurn ) {
            clone = Instantiate(bullet, cannon.position, gameObject.transform.rotation);
            clone.transform.SetParent(gameObject.transform);
            hasShoot = true;
        }
    }
}

注意:如果你的第8层是玩家/敌人所在层,把layerMask = ~layerMask这行逻辑删掉,或者把自身对象放到IgnoreRaycast层,避免过滤掉检测目标。


内容的提问来源于stack exchange,提问作者Jorge Criado ros

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 07:09:18