Tile Grid Issues with Separate Vertices

I’m trying to create a tile grid with separate vertices. I’ve sort of got it working but there’s a number of issues that I can’t seem to figure out. This is the image I’m using for the spritemap:

16781-tileset.png

And here’s the results in game (code is below):

16780-capture.png

As you can see there are some odd artefacts, the sprites are the wrong way up and there’s a bit missing from one side of the sprite. It’s driving me a bit crazy and it’s probably something really obvious that I’m doing wrong but I can’t see it.

Any help would be much appreciated. Also if I’m going about this completely the wrong way, some pointers as to a better way would be nice too :slight_smile: This is going to be used in a tile based tactical game, similar to XCom.

public void BuildMesh() {
	
	int numTiles = size_x * size_z;
	int numTris = numTiles * 2;
	
	int vsize_x = (sharedVertices ? size_x + 1 : size_x * 2);
	int vsize_z = (sharedVertices ? size_z + 1 : size_z * 2);
	int numVerts =  vsize_x * vsize_z;
	
	// Generate the mesh data
	Vector3[] vertices = new Vector3[ numVerts ];
	Vector3[] normals = new Vector3[ numVerts ];
	Vector2[] uv = new Vector2[ numVerts ];
	
	int[] triangles = new int[ numTris * 3 ];

	int x, z, vertIndex;
	if (sharedVertices) {
		for(z=0; z < vsize_z; z++) {
			for(x=0; x < vsize_x; x++) {
				vertIndex = z * vsize_x + x;
				vertices[ vertIndex ] = new Vector3( x*tileSize, 0, z*tileSize );
				normals[ vertIndex ] = Vector3.up;
				uv[ vertIndex ] = new Vector2( (float)x / size_x, (float)z / size_z );
			}
		}
	} else {
		vertIndex = 0;
		for(z=0; z < (size_z * 2); z++) {
			for(x=0; x < size_x; x++) {			
				
				var newZ = Mathf.Ceil((float)z / 2 );
				int uvY = SpriteSheet.height - ((z % 2) * SpriteHeight);
				
				vertices[ vertIndex ] = new Vector3( x*tileSize, 0, newZ * tileSize );
				normals[ vertIndex ] = Vector3.up;
				//uv[ vertIndex ] = new Vector2( (float)x / size_x, newZ / size_z );
                uv[vertIndex] = new Vector2(0, (decimal)uvY / (decimal)SpriteSheet.height);
				vertIndex++;
				
				vertices[ vertIndex ] = new Vector3( (x+1)*tileSize, 0, newZ * tileSize );
				normals[ vertIndex ] = Vector3.up;
				//uv[ vertIndex ] = new Vector2( ((float)x+1f) / size_x, newZ / size_z );	
                uv[vertIndex] = new Vector2((decimal)SpriteWidth / (decimal)SpriteSheet.width, (decimal)uvY / (decimal)SpriteSheet.height);
				vertIndex++;
			}
		}	
	}
	Debug.Log ("Done Verts!");
	
	for(z=0; z < size_z; z++) {
		for(x=0; x < size_x; x++) {
			int squareIndex = z * size_x + x;
			int triOffset = squareIndex * 6;
			
			int topLeft, bottomLeft;
			if (sharedVertices) {
				topLeft = z * vsize_x + x;
				bottomLeft = z * vsize_x + x + vsize_x;
			} else {
				topLeft = (2 * x) + (z*2 * vsize_x);
				bottomLeft = (2 * x) + (((z *2) +1)* vsize_x);
			}
			
			triangles[triOffset + 0] = topLeft    + 0;
			triangles[triOffset + 1] = topLeft 	  + 1;
			triangles[triOffset + 2] = bottomLeft + 0;
			
			triangles[triOffset + 3] = bottomLeft + 0;
			triangles[triOffset + 4] = topLeft	  + 1;
			triangles[triOffset + 5] = bottomleft + 1;
		}
	}
	
	
	
	Debug.Log ("Done Triangles!");
	
	// Create a new Mesh and populate with the data
	Mesh mesh = new Mesh();
	mesh.vertices = vertices;
	mesh.triangles = triangles;
	mesh.normals = normals;
	mesh.uv = uv;
	
	// Assign our mesh to our filter/renderer/collider
	MeshFilter mesh_filter = GetComponent<MeshFilter>();
	MeshRenderer mesh_renderer = GetComponent<MeshRenderer>();
	MeshCollider mesh_collider = GetComponent<MeshCollider>();
	
	mesh_filter.mesh = mesh;
	mesh_collider.sharedMesh = mesh;
	Debug.Log ("Done Mesh!");
}

I ended up simplifying a lot of my code and now it looks like this:

16812-tilemap.png

With the code below:

public void BuildMesh() {
		// Create a new Mesh and populate with the data
		Mesh mesh = new Mesh();
		
		var vertices = new List<Vector3>();
		var normals = new List<Vector3>();
		var uvs = new List<Vector2>();
		var triangles = new List<int>();
		
		for (int z = 0; z < size_z; z++){
			for (int x = 0; x < size_x; x++){
				AddGridSquare(z, x, vertices, normals, uvs, triangles);
			}
		}
		
		mesh.vertices = vertices.ToArray();
		mesh.triangles = triangles.ToArray();
		mesh.normals = normals.ToArray();
		mesh.uv = uvs.ToArray();
		
		MeshFilter mesh_filter = GetComponent<MeshFilter>();
		MeshRenderer mesh_renderer = GetComponent<MeshRenderer>();
		MeshCollider mesh_collider = GetComponent<MeshCollider>();
		
		mesh_filter.mesh = mesh;
		mesh_collider.sharedMesh = mesh;
	}
	
	private void AddGridSquare(int col, int row, List<Vector3> verts, List<Vector3> norms, List<Vector2> uvs, List<int> tris) {
		
		int topLeft = verts.Count;
		verts.Add(new Vector3(row*tileSize, 0, (col+1)*tileSize));	
		verts.Add(new Vector3((row+1)*tileSize, 0, (col+1)*tileSize));		
		
		int bottomLeft = verts.Count;
		verts.Add(new Vector3(row*tileSize, 0, col*tileSize));	
		verts.Add(new Vector3((row+1)*tileSize, 0, col*tileSize));
		
		uvs.Add(new Vector2(0,(float)SpriteSize / (float)SpriteSheet.height));
		uvs.Add(new Vector2((float)SpriteSize / (float)SpriteSheet.width,(float)SpriteSize / (float)SpriteSheet.height));
		uvs.Add(new Vector2(0,0));
		uvs.Add(new Vector2((float)SpriteSize / (float)SpriteSheet.width,0));
		
		norms.Add(Vector3.up);
		norms.Add(Vector3.up);
		norms.Add(Vector3.up);
		norms.Add(Vector3.up);
		
		tris.Add(topLeft    + 0);
		tris.Add(topLeft	+ 1);
		tris.Add(bottomLeft + 0);
		
		tris.Add(topLeft	+ 1);
		tris.Add(bottomLeft	+ 1);
		tris.Add(bottomLeft + 0);
	}