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

Unity3D射线仅X-Z轴反射实现问题求助

实现射线仅在X-Z平面反射(Y轴不影响反射逻辑)

要让射线只在X-Z平面内反射,核心是完全剥离Y轴对反射计算的干扰——常规的Vector3.Reflect会默认使用法线的全分量计算,导致反射方向带Y轴偏移,我们需要手动处理入射方向和碰撞法线的X-Z分量,再完成反射计算。

问题分析

你之前的尝试仅修改了射线原点的Y值,却没有处理反射逻辑中最关键的入射方向和碰撞法线的Y分量,还错误地用transform.forward替代了当前射线的方向,这才导致效果不符合预期。

修正后的代码

if (Physics.Raycast(ray.origin, ray.direction, out hit, remainingLength))
{
    lineRenderer.positionCount += 1;
    lineRenderer.SetPosition(lineRenderer.positionCount - 1, hit.point);
    remainingLength -= Vector3.Distance(ray.origin, hit.point);

    // 1. 提取入射方向的X-Z分量,剥离Y轴影响并归一化
    Vector3 dirXZ = new Vector3(ray.direction.x, 0f, ray.direction.z).normalized;
    
    // 2. 提取碰撞法线的X-Z分量,剥离Y轴影响
    Vector3 normalXZ = new Vector3(hit.normal.x, 0f, hit.normal.z);
    // 处理法线完全垂直于X-Z平面的情况(比如地面),避免零向量报错
    if (normalXZ.magnitude < 0.001f)
    {
        normalXZ = -dirXZ;
    }
    else
    {
        normalXZ = normalXZ.normalized;
    }

    // 3. 在X-Z平面内计算反射方向
    Vector3 reflectedDirXZ = Vector3.Reflect(dirXZ, normalXZ);
    
    // 4. 保留原入射方向的Y分量(或根据需求设置为固定高度/碰撞点Y值)
    Vector3 finalReflectedDir = new Vector3(reflectedDirXZ.x, ray.direction.y, reflectedDirXZ.z);

    // 5. 构建新的反射射线
    ray = new Ray(hit.point, finalReflectedDir);

    if (hit.collider.tag == "Totem")
    {
        break;
    }
}

关键逻辑说明

  • 步骤1和2:把入射方向、碰撞法线的Y分量强制设为0,确保反射计算只在X-Z平面进行。
  • 步骤3:用处理后的平面内方向和法线计算反射,得到纯X-Z平面的反射方向。
  • 步骤4:保留原入射方向的Y分量,让Y轴仅作为高度调整,不参与反射逻辑(如果需要固定高度,也可以直接设为hit.point.y或其他固定值)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:05:51