Madmenyo - 3 years ago 161
C# Question

# Drawing a terrain mesh by script

I am trying to draw some terrain with scripting. However I get strange results and cannot seem to pinpoint the issue.

At the

`Start`
method I'm building my initial mesh.

``````    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();
``````

All I do to draw my mesh is
`Graphics.DrawMesh(terrain, Vector3.zero, Quaternion.identity, mat, 1);`
. Material(mat) is just a simple grid texture and seems to be working correctly. However Unity is deciding to not draw triangle couples at seemingly random.

The gizmo is at
`0, 0, 0`
and each run it renders the same shape. I need to be drawing a
`10 x 10`
shape. I am creating duplicate vertices because I need hard edges eventually.

The problem with the way you do it are your indices. The formula for "flattening" a 2D array is x + y * width (or x * height + y), not x * y.

IMO the best way to approach such issues is to manually calculate values that work and dont work as expected and see if you find a pattern.

In your case it seems (0|0) does not work, while (0|9) does work, lets see why.

So if we use x = 0 and y = 0, we get verts[0 * 0 * 6 + num] = 0 + num. Now we do it for x = 0, y = 9 and alas verts[0 * 9 * 6 + num] still is 0 + num. Since (0|9) is calculated later, the problem is that the verts, uvs, and triangles of (0|0) are overwritten by those values - the same is the problem for everything inbetween, like for example, 3 * 5 is the same as 5 * 3.

So to fix your code, the following should work.

``````    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();
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download