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

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));
            }
        }
    }
}

关键修正说明

  1. 坐标转换逻辑:新增了worldToHeightmapRatioX/Z,用来把世界坐标转换成GetHeight需要的高度图索引,确保高度采样准确。
  2. 修复Z轴缩放:移除了除以200的错误操作,直接使用计算出的世界Z坐标。
  3. 顶点数与地形精度匹配:用heightmapResolution作为顶点数,保证线条的精度和地形高度图一致,不会出现断层。
  4. 可选添加Z方向线条:补充了生成Z方向网格线的代码,让整个地形的网格更完整。

使用提示

  • 确保你的LineRenderer预制体已经设置好合适的材质、线条宽度等参数。
  • 可以通过调整xLineSpacing和zLineSpacing来控制网格线的密度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:46:48