Unity地形网格线绘制问题:线顶点高度与地形不匹配排查
问题分析与修正方案
嘿,我来帮你揪出代码里的问题!你的思路是对的,但在地形坐标转换和GetHeight的用法上踩了几个小坑:
核心错误点
TerrainData.GetHeight参数误用:这个方法接受的是高度图的网格索引(范围是0到heightmapResolution - 1),不是世界坐标的X/Z值。你直接传入世界坐标i,会导致索引完全不匹配地形的高度采样点,自然高度就错了。- Z轴坐标被错误缩放:代码里把计算好的Z轴世界坐标除以200,这会让线条在Z方向缩得非常短,完全偏离地形实际范围。
- LineRenderer顶点数逻辑不匹配:用
detailResolution作为顶点数不合理,应该根据我们的采样步长或者地形的高度图分辨率来确定顶点数量,保证线条能覆盖整个地形Z轴范围。
修正后的完整代码
using UnityEngine; public class RasterScript : MonoBehaviour { private TerrainCollider terrainCollider; private TerrainData terrainData; public LineRenderer lineRendererPrefab; // 可以自定义网格线的X轴间隔 public float xLineSpacing = 2f; void Start() { terrainCollider = GetComponent<TerrainCollider>(); terrainData = terrainCollider.terrainData; // 获取地形的世界范围 float terrainWorldWidth = terrainData.size.x; float terrainWorldDepth = terrainData.size.z; // 高度图的分辨率(用来转换世界坐标到网格索引) int heightmapRes = terrainData.heightmapResolution; float worldToHeightmapRatioX = (heightmapRes - 1) / terrainWorldWidth; float worldToHeightmapRatioZ = (heightmapRes - 1) / terrainWorldDepth; // 生成X方向的网格线(沿Z轴延伸) for (float worldX = 0; worldX <= terrainWorldWidth; worldX += xLineSpacing) { LineRenderer line = Instantiate(lineRendererPrefab, transform); // 计算这条线需要的顶点数:按高度图分辨率采样,保证精度匹配地形 int vertexCount = heightmapRes; line.positionCount = vertexCount; for (int zIndex = 0; zIndex < vertexCount; zIndex++) { // 把高度图Z索引转换成世界坐标 float worldZ = (float)zIndex / (heightmapRes - 1) * terrainWorldDepth; // 把世界坐标转换成高度图索引,用来获取正确的地形高度 int heightmapX = Mathf.RoundToInt(worldX * worldToHeightmapRatioX); int heightmapZ = zIndex; float terrainHeight = terrainData.GetHeight(heightmapX, heightmapZ); // 设置线条顶点的世界坐标 line.SetPosition(zIndex, new Vector3(worldX, terrainHeight, worldZ)); } } // 可选:添加Z方向的网格线(沿X轴延伸),让网格更完整 float zLineSpacing = xLineSpacing; for (float worldZ = 0; worldZ <= terrainWorldDepth; worldZ += zLineSpacing) { LineRenderer line = Instantiate(lineRendererPrefab, transform); int vertexCount = heightmapRes; line.positionCount = vertexCount; for (int xIndex = 0; xIndex < vertexCount; xIndex++) { float worldX = (float)xIndex / (heightmapRes - 1) * terrainWorldWidth; int heightmapX = xIndex; int heightmapZ = Mathf.RoundToInt(worldZ * worldToHeightmapRatioZ); float terrainHeight = terrainData.GetHeight(heightmapX, heightmapZ); line.SetPosition(xIndex, new Vector3(worldX, terrainHeight, worldZ)); } } } }
关键修正说明
- 坐标转换逻辑:新增了
worldToHeightmapRatioX/Z,用来把世界坐标转换成GetHeight需要的高度图索引,确保高度采样准确。 - 修复Z轴缩放:移除了除以200的错误操作,直接使用计算出的世界Z坐标。
- 顶点数与地形精度匹配:用
heightmapResolution作为顶点数,保证线条的精度和地形高度图一致,不会出现断层。 - 可选添加Z方向线条:补充了生成Z方向网格线的代码,让整个地形的网格更完整。
使用提示
- 确保你的LineRenderer预制体已经设置好合适的材质、线条宽度等参数。
- 可以通过调整
xLineSpacing和zLineSpacing来控制网格线的密度。
内容的提问来源于stack exchange,提问作者sUBFUSC
相关产品推荐
相关产品推荐

