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

Unity单个Mesh顶点数是否有限制?岛屿网格生成异常求助

Unity单个Mesh顶点数限制导致多层岛屿仅渲染前两层的问题解决

我在Unity中通过遍历网格Cell,用顶点构建立方体并合并到单个Mesh生成岛屿。代码如下:

void DrawTerrainMesh(Cell[,,] grid){
        Mesh mesh = new(); 
        List<Vector3> vertices  = new List<Vector3>(); 
        List<int> triangles = new List<int>(); 
        
        for (int z = 0; z < z_size; z++) {
            for (int y = 0; y < size; y++) {
                for (int x = 0; x < size; x++) {
                    Cell cell = grid[x, y, z];
                    if (cell == null)
                        continue;
                    if (cell.cellType == Cell.CellType.Earth) {
                        // Calculate the positions of the 8 vertices
                        Vector3[] cubeVertices = new Vector3[8];
                        for (int i = 0; i < 2; i++) {
                            float xv = i == 0 ? 0.5f : -0.5f;
                            for (int j = 0; j < 2; j++) {
                                float yv = j == 0 ? 0.5f : -0.5f;
                                for (int k = 0; k < 2; k++) {
                                    float zv = k == 0 ? 0.5f : -0.5f;
                                    Vector3 vertex = new Vector3(xv + x - size/2, zv + z,yv + y - size/2);
                                    cubeVertices[i * 4 + j * 2 + k] = vertex;
                                }
                            }
                        }
                
                        AddTriangles(vertices, triangles, cubeVertices[0], cubeVertices[2], cubeVertices[4], cubeVertices[6]); // Top
                        AddTriangles(vertices, triangles, cubeVertices[0], cubeVertices[1], cubeVertices[2], cubeVertices[3]); // left 
                        AddTriangles(vertices, triangles, cubeVertices[2], cubeVertices[3], cubeVertices[6], cubeVertices[7]); // back  
                        AddTriangles(vertices, triangles, cubeVertices[3], cubeVertices[1], cubeVertices[7], cubeVertices[5]); // Bottom
                        AddTriangles(vertices, triangles, cubeVertices[4], cubeVertices[6], cubeVertices[5], cubeVertices[7]); // right
                        AddTriangles(vertices, triangles, cubeVertices[0], cubeVertices[4], cubeVertices[1], cubeVertices[5]); // front */
                    }
                }
            }
        }

        mesh.vertices = vertices.ToArray(); 
        mesh.triangles = triangles.ToArray(); 
        mesh.RecalculateNormals(); 
        print(mesh.vertices.Length);
        MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>(); 
        meshFilter.mesh = mesh; 

        MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>(); 

    }

当前岛屿本该有多层结构,但仅渲染出前两层;但只绘制立方体顶面时,所有层都能正常显示。我猜测是Unity对单个Mesh的顶点数有限制,想确认这个猜测是否正确,以及该怎么解决?


你的猜测完全正确,Unity的Mesh确实存在顶点数限制:默认情况下大多数平台使用16位索引,单个Mesh的顶点数上限是65535。当顶点数超过这个值时,超出部分会被截断,导致渲染异常,这就是你只看到前两层的原因。

只渲染顶面时,每个立方体仅添加4个顶点,总顶点数远低于上限,所以能正常显示;而渲染完整立方体时,你的代码每个立方体重复添加24个顶点(6个面,每个面4个顶点),很快就会突破65535的限制。

解决方法

1. 启用32位索引(快速解决)

Unity支持切换到32位索引,将顶点数上限提升到4294967295,完全满足大多数场景需求。只需在设置Mesh的triangles之前添加一行代码:

mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

修改后的关键代码片段:

mesh.vertices = vertices.ToArray(); 
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; // 新增这行
mesh.triangles = triangles.ToArray(); 
mesh.RecalculateNormals(); 

2. 优化顶点共享(长期优化)

你的代码当前每个立方体都重复添加相同位置的顶点,造成大量冗余。可以通过共享顶点来大幅减少顶点总数,比如用字典记录已添加的顶点位置和对应的索引,复用已有顶点:

// 新增字典记录顶点索引
Dictionary<Vector3, int> vertexIndexMap = new Dictionary<Vector3, int>();

// 获取顶点索引,已存在则复用,不存在则添加
int GetVertexIndex(Vector3 vertex) {
    if (vertexIndexMap.TryGetValue(vertex, out int index)) {
        return index;
    }
    vertices.Add(vertex);
    index = vertices.Count - 1;
    vertexIndexMap.Add(vertex, index);
    return index;
}

// 修改AddTriangles方法,使用索引而非直接添加顶点
void AddTriangles(List<int> triangles, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4) {
    int idx1 = GetVertexIndex(v1);
    int idx2 = GetVertexIndex(v2);
    int idx3 = GetVertexIndex(v3);
    int idx4 = GetVertexIndex(v4);
    
    // 添加两个三角形
    triangles.Add(idx1);
    triangles.Add(idx2);
    triangles.Add(idx3);
    
    triangles.Add(idx1);
    triangles.Add(idx3);
    triangles.Add(idx4);
}

这样相邻立方体共享的顶点只会被添加一次,顶点总数会大幅降低,同时也能避免顶点数超限的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:45:05