通过脚本绘制地形网格

时间:2017-09-29 20:19:31

标签: c# unity3d unity5 mesh

我正在尝试使用脚本绘制一些地形。但是我得到了奇怪的结果,似乎无法确定问题。

Start方法中,我正在构建我的初始网格。

    Vector3[] verts = new Vector3[mapWidth * mapHeight * 6];
    Vector2[] uvs = new Vector2[mapWidth * mapHeight * 6];
    int[] triangles = new int[mapWidth * mapHeight * 6];

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            verts[x * y * 6 + 0] = new Vector3(x, 0, y);
            verts[x * y * 6 + 1] = new Vector3(x + 1, 0, y);
            verts[x * y * 6 + 2] = new Vector3(x + 1, 0, y + 1);

            verts[x * y * 6 + 3] = new Vector3(x, 0, y);
            verts[x * y * 6 + 4] = new Vector3(x + 1, 0, y + 1);
            verts[x * y * 6 + 5] = new Vector3(x, 0, y + 1);

            uvs[x * y * 6 + 0] = new Vector2(0, 0);
            uvs[x * y * 6 + 1] = new Vector2(1, 0);
            uvs[x * y * 6 + 2] = new Vector2(1, 1);

            uvs[x * y * 6 + 3] = new Vector2(0, 0);
            uvs[x * y * 6 + 4] = new Vector2(1, 1);
            uvs[x * y * 6 + 5] = new Vector2(0, 1);

            for (int t = 0; t < 6; t++)
            {
                triangles[x * y * 6 + t] = x * y * 6 + 5 - t;
            }
        }
    }

    terrain.vertices = verts;
    terrain.uv = uvs;
    terrain.triangles = triangles;
    terrain.RecalculateNormals();

我绘制网格的所有工作都是Graphics.DrawMesh(terrain, Vector3.zero, Quaternion.identity, mat, 1);。材质(垫)只是一个简单的网格纹理,似乎工作正常。然而,Unity决定不以看似随机的方式绘制三角形情侣。

enter image description here

Gizmo位于0, 0, 0,每次运行它都会呈现相同的形状。我需要绘制10 x 10形状。我正在创建重复的顶点,因为我最终需要硬边。

1 个答案:

答案 0 :(得分:2)

你这样做的问题是你的指数。 “展平”2D阵列的公式是x + y *宽度(或x *高度+ y),而不是x * y。

IMO解决此类问题的最佳方法是手动计算有效且无法按预期工作的值,看看是否找到了模式。

在你的情况下似乎(0 | 0)不起作用,而(0 | 9)确实有效,让我们看看原因。

因此,如果我们使用x = 0和y = 0,我们得到顶点[0 * 0 * 6 + num] = 0 + num。现在我们为x = 0,y = 9而做,而alas verts [0 * 9 * 6 + num]仍为0 + num。由于稍后计算(0 | 9),问题是(0 | 0)的顶点,uvs和三角形被这些值覆盖 - 同样是中间的所有内容的问题,例如,3 * 5是与5 * 3相同。

因此,为了修复您的代码,以下内容应该有效。

    Vector3[] verts = new Vector3[mapWidth * mapHeight * 6];
    Vector2[] uvs = new Vector2[mapWidth * mapHeight * 6];
    int[] triangles = new int[mapWidth * mapHeight * 6];

    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {

            int tileIndex = x + y * width;

            verts[tileIndex * 6 + 0] = new Vector3(x, 0, y);
            verts[tileIndex * 6 + 1] = new Vector3(x + 1, 0, y);
            verts[tileIndex * 6 + 2] = new Vector3(x + 1, 0, y + 1);

            verts[tileIndex * 6 + 3] = new Vector3(x, 0, y);
            verts[tileIndex * 6 + 4] = new Vector3(x + 1, 0, y + 1);
            verts[tileIndex * 6 + 5] = new Vector3(x, 0, y + 1);

            uvs[tileIndex * 6 + 0] = new Vector2(0, 0);
            uvs[tileIndex * 6 + 1] = new Vector2(1, 0);
            uvs[tileIndex * 6 + 2] = new Vector2(1, 1);

            uvs[tileIndex * 6 + 3] = new Vector2(0, 0);
            uvs[tileIndex * 6 + 4] = new Vector2(1, 1);
            uvs[tileIndex * 6 + 5] = new Vector2(0, 1);

            for (int t = 0; t < 6; t++) {
                triangles[tileIndex * 6 + t] = tileIndex * 6 + 5 - t;
            }
        }
    }

    terrain.vertices = verts;
    terrain.uv = uvs;
    terrain.triangles = triangles;
    terrain.RecalculateNormals();