如何获取相机射线到零高度平面的正确长度?
解决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
相关产品推荐
相关产品推荐

