This isn’t properly a unity related question but more of general programming one, but I don’t know any other place to ask so I’ll do here if everyone is ok with it.
I’m trying to calculate uv maps for a procedural generated mesh, I have all the code in place to generate the quads and everything, is not a problem. My problem is to calculate each quad uv based on an integer that is used to pick a portion of an atlas texture.
The texture for this test is a 128x128 pixel texture, each tile is 16 pixel, so in total 64 tiles (from 0 to 63). Now please take a look at the following picture:
You can see how I build the quads and how the texture is structured. I generate the meshes from an array of ints, all the 0s are not processed and so skipped, this is my actual code of the mesh generation:
using UnityEngine;
using System.Collections.Generic;
public class UDTestWorld {
static private List<Vector3> verts = new List<Vector3>(); //List of vertices needed for the mesh
static private List<Vector2> uvs = new List<Vector2>(); //List of uvs needed for the mesh
static private List<int> tris = new List<int>(); //List of triangles needed for the mesh
static private int tWidth = 128;
static private int tHeight = 128;
static private float tSize = 16;
// Template map
private static int[] worldMap = new int[]
{
0,0,2,1,2,0,0,0,
0,0,2,9,2,2,0,0,
2,2,2,9,9,2,2,0,
2,9,9,9,9,9,2,0,
2,9,9,9,9,9,2,0,
2,2,2,2,9,2,2,0,
0,2,9,9,9,2,0,0,
0,2,9,9,9,2,2,2,
0,2,2,9,9,9,9,2,
0,0,2,2,2,2,2,2
};
static private NMPoint2 size = new NMPoint2(8,10);
// Build the entire map
static public void CreateWorldMesh (Transform parent) {
Vector3 p = Vector3.zero;
CreateCellMesh(worldMap, p, parent);
}
// Build geometry of each cell
static private void CreateCellMesh (int[] cell, Vector3 pos, Transform parent) {
verts.Clear (); uvs.Clear (); tris.Clear ();
GameObject o = new GameObject ("EX_CELL");
Mesh mesh = new Mesh ();
if (!o.GetComponent<MeshFilter> ())
o.AddComponent<MeshFilter> ();
mesh = o.GetComponent<MeshFilter> ().mesh;
Vector3 p = Vector3.zero;
int i = 0;
for(int x = 0; x < size.x; x++) {
for(int y = 0; y < size.y; y++) {
p = new Vector3(x * 1 + .5f,-y * 1 - .5f, 0);
if(cell[x + y * size.x] != 0) {
verts.Add (new Vector3(-0.5f + p.x, -0.5f + p.y, p.z));
verts.Add (new Vector3(-0.5f + p.x, 0.5f + p.y, p.z));
verts.Add (new Vector3 (0.5f + p.x, 0.5f + p.y, p.z));
verts.Add (new Vector3( 0.5f + p.x, -0.5f + p.y, p.z));
Vector4 uvo = new Vector4(
((worldMap[x + y * size.x] - 1) * tSize) / tWidth,
((worldMap[x + y * size.x] - 1) * tSize) / tHeight,
tSize / tWidth,
tSize / tHeight
);
//Temp UV
uvs.Add (new Vector2 (0.0f, 1f - 0.125f )); //0, 0
uvs.Add (new Vector2 (0.0f, 1f )); //0, 1
uvs.Add (new Vector2 (0.0f + 0.125f, 1f)); //1, 1
uvs.Add (new Vector2 (0.0f + 0.125f, 1f - 0.125f)); //1, 0
tris.Add (i + 1);
tris.Add (i + 3);
tris.Add (i);
tris.Add (i + 3);
tris.Add (i + 1);
tris.Add (i + 2);
i += 4;
}
}
}
Vector3[] vertices = verts.ToArray ();
Vector2[] uv = uvs.ToArray ();
int[] triangles = tris.ToArray ();
mesh.vertices = vertices;
mesh.uv = uv;
mesh.triangles = triangles;
if (!o.GetComponent<MeshRenderer> ())
o.AddComponent<MeshRenderer> ();
MeshRenderer mr = o.GetComponent<MeshRenderer> ();
mr.castShadows = mr.receiveShadows = false;
mesh.RecalculateBounds ();
o.transform.parent = parent;
o.transform.localPosition = pos;
}
}
The NMPoint2 is a custom struct with just 2 ints, is used primarly for szes and movement, nothing fancy, treath is as x and y. As you can see before the mesh start building I make sure that all values of 0 are not took in account for the mesh creation, after that I calculate a simple offset for the uv, taking the integer from the worldMap array as base number of uv space calculation. Because I skip the 0s the offset is calculated with a -1 as I still want to use the first tile of the texture.
Now my problem is to get the dynamic uv calculation to take in account rows too, I tried a lot of calculations resulting in a fail everytime, for example if in the array there is a 9 I would like to use the tile at 9 in the picture.
For the moment I only posted a temp uv calculation that will return always the first tile (indexed as 0 in the pic), I can get trough the offset all the tiles from the first row, my problem is to get dynamically also the other rows. Any help is appreciated I’m really going nuts with this.
I know that uv is 0,0 Bottom left and 1,1 TopRight thats where the problem comes I guess.