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

Unity中如何使Gizmos线条碰撞器网格与地面平行?

让网格平行地面的调整方案与优化思路

你的核心问题在于当前是从屏幕空间计算顶点偏移,导致网格的方向完全依赖相机视角,自然无法和地面保持平行。要解决这个问题,我们需要切换到世界空间,基于地面平面的坐标系来计算顶点位置。

核心问题拆解

当前代码通过WorldToScreenPoint把球体坐标转成屏幕坐标,再基于屏幕空间的垂直方向(Vector3.Cross(v1, Vector3.forward))偏移顶点,最后转回世界空间。这种方式生成的网格会跟着相机的视角倾斜,完全和地面平面脱节。

具体调整步骤

假设你的地面是Y轴向上的平面(通常Unity默认地面Y=0),我们可以直接在世界空间中计算平行于地面的偏移方向:

  1. 计算两个球体中心的水平连线向量(忽略Y轴高度,确保在地面平面内)
  2. 生成该连线在地面上的垂直偏移方向
  3. 基于这个方向偏移两个球体的中心,得到四个顶点,同时固定所有顶点的Y值为地面高度(或者你想要的高度)

修改后的代码如下:

Vector3 p1 = sphere1.transform.position;
Vector3 p2 = sphere2.transform.position;
float groundY = 0f; // 这里替换成你的地面实际Y高度,比如如果地面是一个物体,就取ground.transform.position.y

// 步骤1:计算两球中心的水平连线(忽略Y轴)
Vector3 horizontalLine = new Vector3(p2.x - p1.x, 0, p2.z - p1.z).normalized;
// 步骤2:计算地面上垂直于连线的偏移方向
Vector3 offsetDir = Vector3.Cross(horizontalLine, Vector3.up).normalized;
// 步骤3:设置偏移距离(你原来的6f*3可以根据需求调整)
float offsetDistance = 6f * 3f;

// 生成四个顶点,固定Y为地面高度
List<Vector3> listVerts = new List<Vector3>();
// 下方两个顶点(偏移方向的负方向)
listVerts.Add(new Vector3(p1.x - offsetDir.x * offsetDistance, groundY, p1.z - offsetDir.z * offsetDistance));
listVerts.Add(new Vector3(p2.x - offsetDir.x * offsetDistance, groundY, p2.z - offsetDir.z * offsetDistance));
// 上方两个顶点(偏移方向的正方向)
listVerts.Add(new Vector3(p2.x + offsetDir.x * offsetDistance, groundY, p2.z + offsetDir.z * offsetDistance));
listVerts.Add(new Vector3(p1.x + offsetDir.x * offsetDistance, groundY, p1.z + offsetDir.z * offsetDistance));

更优的顶点获取思路

上面的方法已经脱离了相机依赖,完全基于世界空间和地面平面计算,是更稳定的方案。如果你的地面不是Y轴向上的,只需要把Vector3.up替换成地面的法向量即可(比如ground.transform.up)。

另外,如果你希望网格贴合球体的底部而不是地面,只需要把groundY替换成Mathf.Min(p1.y - sphere1Radius, p2.y - sphere2Radius),确保网格不会穿入球体。

最后,关于RayCast检测的问题,现在网格平行地面后,只要把它分配到指定Layer,RayCast就能稳定检测到整个表面了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:23:21