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

如何获取相机射线到零高度平面的正确长度?

解决Unity中射线到y=0平面的长度计算问题

问题描述

我想计算相机通过鼠标位置发射的射线到高度0平面的长度,相当于做一次平面射线检测,但不需要物理平面,只用数学计算。但我按自己计算的长度绘制的红色射线总是要么太长要么太短,找不到代码问题在哪。参考:蓝色射线是直接向下到y=0的,显示正常,目标位置有个球体在y=0处。

复现步骤:在Unity中,把以下代码添加到脚本并挂载到任意游戏对象:

private void Update()
{
    // Get the mouse position in screen space.
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

    Vector3 vectorFromMouse = ray.direction;

    // Get Angle
    float angle = Vector3.Angle(vectorFromMouse, Vector3.down);

    if (angle >= 90)
    {
        return;
    }

    float y = ray.origin.y;

    float c = y / Mathf.Cos(angle);
    float a = y * Mathf.Tan(angle);
    float c2 = Mathf.Sqrt(a * a + y * y);
    Debug.DrawRay(ray.origin, vectorFromMouse * c2, Color.red, 0.1f);
    Debug.DrawRay(ray.origin, Vector3.down * y, Color.blue, 0.1f);

    print($"{angle} | {y} | {c} | {c2}");
}

问题原因

你用角度和三角函数的方法绕了弯路,而且Vector3.Angle返回的是两个向量之间的最小夹角(0-180度),当射线方向不是正下方附近时,你假设的直角三角形模型和射线实际走向不匹配,导致计算出的长度出现偏差。

解决方案

直接利用射线的参数方程计算与y=0平面的交点,这是最准确高效的方法:
射线的参数方程为 射线起点 + 射线方向 * t,我们需要找到t使得该点的y坐标为0,解方程可得:
ray.origin.y + ray.direction.y * t = 0 → t = -ray.origin.y / ray.direction.y

需要提前判断两种无交点的情况:

  • 射线方向y分量≥0:射线向上或水平,永远到不了y=0平面
  • 计算出的t为负数:射线起点在y=0以下且向下发射,也不会到达目标平面

修正后的代码

private void Update()
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

    // 排除射线向上/水平的情况
    if (ray.direction.y >= 0)
    {
        return;
    }

    // 计算射线到y=0平面的距离参数t
    float t = -ray.origin.y / ray.direction.y;
    // 获取交点位置(可选,用于验证)
    Vector3 hitPoint = ray.GetPoint(t);
    
    // 绘制正确的红色射线到y=0平面
    Debug.DrawRay(ray.origin, ray.direction * t, Color.red, 0.1f);
    Debug.DrawRay(ray.origin, Vector3.down * ray.origin.y, Color.blue, 0.1f);

    print($"射线长度: {t} | 交点坐标: {hitPoint}");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:25:17