Some triangles are black on a mesh generated by script
Iam trying to generate a mesh in unity by script. Eventualy i want this to be a tilemap. Iam getting something strange with some triangles not rendering properly as you can see in this image: !
Before i added a material to it it was looking fine (solid pink color). All the triangles seem to be there too. I have only started making meshes by code since today so i cannot figure out what i did wrong here.
This is the code iam using currently (note UpdateMesh() is not being used atm):
 using UnityEngine;
 using System.Collections;
 
 [RequireComponent(typeof(MeshFilter))]
 [RequireComponent(typeof(MeshRenderer))]
 [RequireComponent(typeof(MeshCollider))]
 
 public class Tilemap : MonoBehaviour {
 
     public int size_x;
     public int size_y;
 
     public float TileSize;
 
     // Use this for initialization
     void Start () {
         BuildMesh ();
     }
 
     public void BuildMesh(){
 
         TileMapData map = new TileMapData (size_x, size_y);
 
         int numTiles = size_x * size_y;
         int numVerts = numTiles * 4;
 
         Vector3[] vertices = new Vector3[numVerts];
         Vector3[] normals = new Vector3[numVerts];
         Vector2[] uv = new Vector2[numVerts];
 
         int [] triangles = new int[numTiles * 6];
 
         int x, y;
         for (y = 0; y < size_y; y++){
             for (x = 0; x < size_x; x++){
                 Debug.Log(y*size_x+x);
                 vertices[(y*size_x+x)*4] = new Vector3(x*TileSize, y*TileSize,0);
                 vertices[(y*size_x+x)*4+1] = new Vector3(x*TileSize+TileSize, y*TileSize,0);
                 vertices[(y*size_x+x)*4+2] = new Vector3(x*TileSize+TileSize, y*TileSize+TileSize,0);
                 vertices[(y*size_x+x)*4+3] = new Vector3(x*TileSize, y*TileSize+TileSize,0);
 
                 uv[(y*size_x+x)*4] = new Vector2(0,0);
                 uv[(y*size_x+x)*4+1] = new Vector2(1,0);
                 uv[(y*size_x+x)*4+2] = new Vector2(1,1);
                 uv[(y*size_x+x)*4+3] = new Vector2(0,1);
 
                 normals[(y*size_x)*4] = new Vector3(0,0,-1);
                 normals[(y*size_x+x)*4+1] = new Vector3(0,0,-1);
                 normals[(y*size_x+x)*4+2] = new Vector3(0,0,-1);
                 normals[(y*size_x+x)*4+3] = new Vector3(0,0,-1);
 
             }
         }
         Debug.Log ("Done Verts!");
 
         for (y = 0; y < size_y; y++){
             for (x = 0; x < size_x; x++){
                 int squareindex = y*size_x+x;
                 int triOffset = squareindex*6;
                 Debug.Log(squareindex);
                 triangles[triOffset + 0] =  1+squareindex*4;
                 triangles[triOffset + 1] =  0+squareindex*4;
                 triangles[triOffset + 2] =  3+squareindex*4;
 
                 triangles[triOffset + 3] =  1+squareindex*4;
                 triangles[triOffset + 4] =  3+squareindex*4;
                 triangles[triOffset + 5] =  2+squareindex*4;
             }
         }
         Debug.Log ("Done Triangles!");
 
         Mesh mesh = new Mesh ();
         mesh.vertices = vertices;
         mesh.triangles = triangles;
         mesh.normals = normals;
         mesh.uv = uv;
 
         MeshFilter mesh_filter = GetComponent<MeshFilter> ();
         MeshCollider mesh_collider = GetComponent<MeshCollider> ();
 
         mesh_filter.mesh = mesh;
         mesh_collider.sharedMesh = mesh;
         Debug.Log ("Done Mesh!");
         //UpdateMesh ();
     }
 
     public void UpdateMesh(){
         Mesh meshtoupdate = GetComponent<MeshFilter> ().mesh;
         int uvoffset = 0;
         int vsize_x = size_x + 1;
         int vsize_y = size_y + 1;
         int numVerts = vsize_x * vsize_y;
         int x, y;
         Vector2[] uv = meshtoupdate.uv;
 
 
         for (y = 0; y < vsize_y-15; y++){
             for (x = 0; x < vsize_x-15; x++){
                 uv[uvoffset] = new Vector2(0.0f,0.0f);
                 uv[uvoffset+1] = new Vector2(0.0f,0f);
                 uv[uvoffset+2] = new Vector2(0.0f,0f);
                 uv[uvoffset+3] = new Vector2(0.0f,0f);
                 uvoffset += 4;
                 Debug.Log(uvoffset);
 
 
             }
         }
         meshtoupdate.uv = uv;
         Debug.Log("Done MeshUpdate!");
         Debug.Log(uv.Length);
     }
 
 }
 
              Answer by Statement · Oct 31, 2015 at 09:03 PM
Normals were not written properly.
 normals[(y*size_x)*4] = new Vector3(0,0,-1);
 
               Should be
 normals[(y*size_x+x)*4] = new Vector3(0, 0, -1);
 
               I also cleaned it up a little bit to make it less prone for errors and provide a simplified mesh for PhysX.
 using UnityEngine;
 
 [RequireComponent(typeof(MeshFilter))]
 [RequireComponent(typeof(MeshRenderer))]
 [RequireComponent(typeof(MeshCollider))]
 public class Tilemap : MonoBehaviour
 {
     public int size_x;
     public int size_y;
     public float TileSize;
 
     void Start()
     {
         BuildMesh();
     }
 
     public void BuildMesh()
     {
         MeshFilter mesh_filter = GetComponent<MeshFilter>();
         mesh_filter.sharedMesh = CreateGfxMesh();
         MeshCollider mesh_collider = GetComponent<MeshCollider>();
         mesh_collider.sharedMesh = CreateSimplePhysxMesh();
     }
 
     Mesh CreateGfxMesh()
     {
         int numTiles = size_x * size_y;
         int numVerts = numTiles * 4;
         int numTris = numTiles * 6;
         Vector3[] vertices = new Vector3[numVerts];
         Vector3[] normals = new Vector3[numVerts];
         Vector2[] uv = new Vector2[numVerts];
         int[] triangles = new int[numTris];
 
         for (int y = 0; y < size_y; y++)
         {
             for (int x = 0; x < size_x; x++)
             {
                 int tileIndex = y * size_x + x;
                 int tileTriangleIndex = tileIndex * 6;
                 int tileVertexIndex = tileIndex * 4;
 
                 // Tile vertex corner positions
                 // xAyA -- xByA
                 // |         |
                 // |         |
                 // |         |
                 // xAyB -- xByB
                 float xA = x * TileSize;
                 float yA = y * TileSize;
                 float xB = xA + TileSize;
                 float yB = yA + TileSize;
 
                 vertices[tileVertexIndex + 0] = new Vector3(xA, yA, 0);
                 vertices[tileVertexIndex + 1] = new Vector3(xB, yA, 0);
                 vertices[tileVertexIndex + 2] = new Vector3(xB, yB, 0);
                 vertices[tileVertexIndex + 3] = new Vector3(xA, yB, 0);
 
                 uv[tileVertexIndex + 0] = new Vector2(0, 0);
                 uv[tileVertexIndex + 1] = new Vector2(1, 0);
                 uv[tileVertexIndex + 2] = new Vector2(1, 1);
                 uv[tileVertexIndex + 3] = new Vector2(0, 1);
 
                 normals[tileVertexIndex + 0] = new Vector3(0, 0, -1);
                 normals[tileVertexIndex + 1] = new Vector3(0, 0, -1);
                 normals[tileVertexIndex + 2] = new Vector3(0, 0, -1);
                 normals[tileVertexIndex + 3] = new Vector3(0, 0, -1);
 
                 triangles[tileTriangleIndex + 0] = 1 + tileVertexIndex;
                 triangles[tileTriangleIndex + 1] = 0 + tileVertexIndex;
                 triangles[tileTriangleIndex + 2] = 3 + tileVertexIndex;
 
                 triangles[tileTriangleIndex + 3] = 1 + tileVertexIndex;
                 triangles[tileTriangleIndex + 4] = 3 + tileVertexIndex;
                 triangles[tileTriangleIndex + 5] = 2 + tileVertexIndex;
             }
         }
 
         Mesh mesh = new Mesh();
         mesh.vertices = vertices;
         mesh.normals = normals;
         mesh.uv = uv;
         mesh.triangles = triangles;
         return mesh;
     }
 
     Mesh CreateSimplePhysxMesh()
     {
         // Create a simple quad, it'll be faster for baking mesh for physx.
         // For a 32x32 test, shaves 10 ms off (5x speedup).
         Vector3[] vertices = new Vector3[4];
         Vector3[] normals = new Vector3[4];
         int[] triangles = new int[6];
 
         float w = size_x * TileSize;
         float h = size_y * TileSize;
 
         vertices[0] = new Vector3(0, 0, 0);
         vertices[1] = new Vector3(w, 0, 0);
         vertices[2] = new Vector3(w, h, 0);
         vertices[3] = new Vector3(0, h, 0);
 
         normals[0] = new Vector3(0, 0, -1);
         normals[1] = new Vector3(0, 0, -1);
         normals[2] = new Vector3(0, 0, -1);
         normals[3] = new Vector3(0, 0, -1);
 
         triangles[0] = 1;
         triangles[1] = 0;
         triangles[2] = 3;
         triangles[3] = 1;
         triangles[4] = 3;
         triangles[5] = 2;
 
         Mesh mesh = new Mesh();
         mesh.vertices = vertices;
         mesh.normals = normals;
         mesh.triangles = triangles;
         return mesh;
     }
 }
 
              Thanks man. $$anonymous$$ade a kinda simple error it seems but just couldnt find it
Thanks again!
I suggest you keep a pair of debugging shaders handy if you are going to procedurally generate meshes :) One that displays UV and one that displays Normals could be useful for tracking down issues.
You can use Tutorial/Display Normals for viewing normals and make a copy of that, set name "Tutorial/Display UV" or something and set o.color = fixed3(v.texcoord.x, v.texcoord.y, 0); ins$$anonymous$$d of o.color = v.normal * 0.5 + 0.5;.
Updated the script by removing redundant secondary loop and giving the collider a simplified mesh.
Never worked with shaders before but that does seem very handy for debugging purposes.
Your answer