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

Unity中动态网格计算三角形索引异常问题排查

问题分析与解决方案

你遇到的Mesh渲染异常(最后一列半区域无法显示),核心问题是三角形顶点索引的计算逻辑错误,导致部分三角形指向了错误的顶点位置,甚至超出了顶点数组的有效范围。

错误原因详解

在生成三角形索引的循环中,你使用了 x * Map.HEIGHT + y 来计算顶点索引,但实际上:

  • 顶点数组的结构是:每个x坐标对应 Map.HEIGHT + 1 个顶点(因为y从0到Map.HEIGHT,共Map.HEIGHT+1个值)
  • 正确的顶点索引公式应该是 x * (Map.HEIGHT + 1) + y,而不是用 Map.HEIGHT 作为乘数

原代码中用 Map.HEIGHT 计算索引,会让每一行的顶点索引偏移错误,当x值较大时(比如接近Map.WIDTH),索引会指向不属于当前行的顶点,甚至超出数组范围,最终导致部分区域无法正确生成三角形网格。

修正后的代码

void GenerateMesh() { 
    mesh = GetComponent<MeshFilter>().mesh; 
    mesh.Clear(); 

    Vector3[] vertices = new Vector3[(Map.WIDTH + 1) * (Map.HEIGHT + 1)]; 
    int nextIndex = 0; 
    for (int x = 0; x <= Map.WIDTH; x++) { 
        for (int y = 0; y <= Map.HEIGHT; y++) { 
            vertices[nextIndex] = new Vector3(x * Square.SIZE, 0, y * Square.SIZE); 
            nextIndex++; 
        } 
    } 

    int[] triangles = new int[6 * Map.WIDTH * Map.HEIGHT]; 
    nextIndex = 0; 
    for (int x = 0; x < Map.WIDTH; x++) { 
        for (int y = 0; y < Map.HEIGHT; y++) { 
            // 修正顶点索引的计算方式,使用Map.HEIGHT + 1作为每行顶点数
            int currentIndex = x * (Map.HEIGHT + 1) + y;
            int rightIndex = (x + 1) * (Map.HEIGHT + 1) + y;
            int topIndex = x * (Map.HEIGHT + 1) + y + 1;
            int topRightIndex = (x + 1) * (Map.HEIGHT + 1) + y + 1;

            // 第一个三角形:左下 -> 左上 -> 右上
            triangles[nextIndex] = currentIndex; 
            triangles[nextIndex + 1] = topIndex; 
            triangles[nextIndex + 2] = topRightIndex; 
            nextIndex += 3; 

            // 第二个三角形:左下 -> 右上 -> 右下
            triangles[nextIndex] = currentIndex; 
            triangles[nextIndex + 1] = topRightIndex; 
            triangles[nextIndex + 2] = rightIndex; 
            nextIndex += 3; 
        } 
    } 

    mesh.vertices = vertices; 
    mesh.triangles = triangles; 
    // 建议添加这两行,确保Mesh的法线和UV正确生成,避免后续渲染问题
    mesh.RecalculateNormals();
    mesh.RecalculateBounds();
}

额外优化建议

  • 添加 mesh.RecalculateNormals() 和 mesh.RecalculateBounds(),可以确保Mesh的光照计算正确,并且避免相机视锥体剔除错误
  • 可以提前计算 Map.HEIGHT + 1 为一个变量,减少重复计算,提升代码可读性和性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:51:55