# Unity 2D Tile Generation

Hey guys. First post.

I’ve been following along with this tutorial, parts one and two specifically (I didn’t go into the 3D stuff because I’m not making a voxel-based game).

I need some help with “GenTerrain” and “BuildMesh”, because in his tutorial, Alexandros is generating based on math formulas and I wish to generate from 4D array or vector data. For example, an XYAB array where X and Y are the two-dimensional coordinates and A and B are tile coordinates on the texture. In the tutorial, he selects what tile it is from a Vector2.

I’m not trying to ask anyone to write me code here, I just need a push in the right direction and maybe a link or two to some tutorials or videos, or any advice you think would be useful.

Here is Alexandros’s final code, and my code so far, it differs a little bit from the tutorial because, again, I wasn’t planning on building a voxel game:

Alexandros’s Code

My Code:

``````using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TileEngine : MonoBehaviour {

public List<Vector3> newVertices = new List<Vector3>();
public List<Vector3> colVertices = new List<Vector3>();
public List<Vector2> newUV = new List<Vector2>();
public List<int> newTriangles = new List<int>();
public List<int> colTriangles = new List<int>();
public byte[,] blocks;

private Mesh mesh;
private MeshCollider col;
private int squareCount;
private int colCount;
private float tUnit = 0.50f;

private Vector2 tGrassland = new Vector2 (0, 1);
private Vector2 tForest = new Vector2 (1, 1);
private Vector2 tMountain = new Vector2 (0, 0);
private Vector2 tHills = new Vector2 (1, 0);

void Start () {

mesh = GetComponent<MeshFilter> ().mesh;
col = GetComponent<MeshCollider> ();

GenTerrain ();
BuildMesh ();
UpdateMesh ();

}

void Update () {

}

void GenTerrain () {

blocks = new byte [10, 10];

}

void BuildMesh () {

}

void ColliderTriangles () {

colTriangles.Add (colCount * 4);
colTriangles.Add ((colCount * 4) + 1);
colTriangles.Add ((colCount * 4) + 3);
colTriangles.Add ((colCount * 4) + 1);
colTriangles.Add ((colCount * 4) + 2);
colTriangles.Add ((colCount * 4) + 3);

}

void GenCollider(int x, int y){

colVertices.Add (new Vector3 (x, y, 1));
colVertices.Add (new Vector3 (x + 1, y, 1));
colVertices.Add (new Vector3 (x + 1, y, 0));
colVertices.Add (new Vector3 (x, y, 0));

ColliderTriangles ();
colCount++;

colVertices.Add (new Vector3 (x, y - 1, 0));
colVertices.Add (new Vector3 (x + 1, y - 1, 0));
colVertices.Add (new Vector3 (x + 1, y - 1, 1));
colVertices.Add (new Vector3 (x, y - 1, 1));

ColliderTriangles ();
colCount++;

colVertices.Add (new Vector3 (x, y - 1, 1));
colVertices.Add (new Vector3 (x, y, 1));
colVertices.Add (new Vector3 (x, y, 0));
colVertices.Add (new Vector3 (x, y - 1, 0));

ColliderTriangles ();
colCount++;

colVertices.Add (new Vector3 (x + 1, y, 1));
colVertices.Add (new Vector3 (x + 1, y - 1, 1));
colVertices.Add (new Vector3 (x + 1, y - 1, 0));
colVertices.Add (new Vector3 (x + 1, y, 0));

ColliderTriangles ();
colCount++;

}

void GenSquare(int x, int y, Vector2 texture){

newVertices.Add (new Vector3 (x, y, 0));
newVertices.Add (new Vector3 (x + 1, y, 0));
newVertices.Add (new Vector3 (x + 1, y - 1, 0));
newVertices.Add (new Vector3 (x, y - 1, 0));

newUV.Add (new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
newUV.Add (new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
newUV.Add (new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
newUV.Add (new Vector2 (tUnit * texture.x, tUnit * texture.y));

squareCount++;

}

void UpdateMesh () {

mesh.Clear ();
mesh.vertices = newVertices.ToArray ();
mesh.triangles = newTriangles.ToArray ();
mesh.uv = newUV.ToArray ();
mesh.Optimize ();
mesh.RecalculateNormals ();

newVertices.Clear ();
newTriangles.Clear ();
newUV.Clear ();
squareCount = 0;

Mesh newMesh = new Mesh ();
newMesh.vertices = colVertices.ToArray ();
newMesh.triangles = colTriangles.ToArray ();
col.sharedMesh = newMesh;

colVertices.Clear ();
colTriangles.Clear ();
colCount = 0;

}
}
``````

Specifically, Alexandros’s GenTerrain and BuildMesh are as follows:
(This is not what I want to do, I want to gen from an array and not a math formula)

``````void GenTerrain(){
blocks=new byte[10,10];
for(int px=0;px<blocks.GetLength(0);px++){
for(int py=0;py<blocks.GetLength(1);py++){
if(py==5){
blocks[px,py]=2;
} else if(py<5){
blocks[px,py]=1;
}
if(px==5){
blocks[px,py]=0;
}
}
}
}
void BuildMesh(){
for(int px=0;px<blocks.GetLength(0);px++){
for(int py=0;py<blocks.GetLength(1);py++){
if(blocks[px,py]!=0){
GenCollider(px,py);
if(blocks[px,py]==1){
GenSquare(px,py,tStone);
} else if(blocks[px,py]==2){
GenSquare(px,py,tGrass);
}
}
}
}
}
``````

Where is your array created, whats inside it?

It’s not created yet in the example script because I’m asking how it would be done in general. What I want to do is create maybe a Vector2 and fill it with data to generate the map from.

I think what I want to do is something like this, but I have no idea how to script it as I’m new to C# and programming.

``````void BuildMesh(){
GenSquare(px,py,*********);
px++
}

if(px==127){
GenSquare(px,py,*********);
px=0
py++
}
``````

The idea here is to generate a square at 0,0 where ********* is where I somehow pull information on what texture goes there from an array of texture data I defined earlier such as

tGrassland
tGrassland
tHills
tMountain

so it would generate a Grassland at 0,0 and 1,0 then hills at 2,0 then mountains at 3,0 and then keep on moving until 127,0 where it would set “px” back to 0 and give py +1 and do it all over again.

Say you have a multidimensional array of Vector2 with the same dimensions as your map, you could just populate this with the texture data. Then just feed GenSquare values from it using the same tile coordinates, something like:

``````// Create map
Vector2[,] tileTextureCoords = new Vector2[mapSizeX, mapSizeY];
// Assign variables
tileTextureCoords[13,37] = tGrassland;
tileTextureCoords[3,14] = tHills;

// And when generating the squares:
GenSquare(px, py, tileTextureCoords[px, py]);
``````

This sounds exactly like what I want to do, thank you so much.

Okay, I still can’t figure out how to do this.
I can’t figure out where Vector2[,] tileTextureCoords = new Vector2[mapSizeX, mapSizeY]; goes.
I can’t figure out how to generate tiles with it.
Now my script has 5 errors.

``````    void GenTerrain(){

blocks = new byte[2, 2];

}

void BuildMesh(){

Vector2[,] textCoords = new Vector2[2,2];

textCoords [0, 0] = tGrassland;
textCoords [1, 0] = tGrassland;
textCoords [0, 1] = tForest;
textCoords [1, 1] = tForest;

for (int px=0; px<blocks.GetLength (0); px++) {
for (int py=0; py<blocks.GetLength (0); py++){

GenSquare (px,py,textCoords[px,py]);
px++;

if (px==1){

GenSquare (px,py,textCoords[px,py]);
py++;
px=0;

}
}
}
}
``````

Have you gotten any further?
If I’m reading your code corrrectly this evening, you have some infinite loops going on.
You shouldn’t need anything else in the for loops than:

``````  for (int px=0; px<blocks.GetLength (0); px++) {
for (int py=0; py<blocks.GetLength (0); py++){
GenSquare (px,py,textCoords[px,py]);
}
}
``````