Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Unity 2D Tile Generation

Discussion in 'Scripting' started by Sketchward, Mar 30, 2015.

  1. Sketchward

    Sketchward

    Joined:
    Mar 30, 2015
    Posts:
    6
    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:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class TileEngine : MonoBehaviour {
    6.  
    7.     public List<Vector3> newVertices = new List<Vector3>();
    8.     public List<Vector3> colVertices = new List<Vector3>();
    9.     public List<Vector2> newUV = new List<Vector2>();
    10.     public List<int> newTriangles = new List<int>();
    11.     public List<int> colTriangles = new List<int>();
    12.     public byte[,] blocks;
    13.  
    14.     private Mesh mesh;
    15.     private MeshCollider col;
    16.     private int squareCount;
    17.     private int colCount;
    18.     private float tUnit = 0.50f;
    19.  
    20.     private Vector2 tGrassland = new Vector2 (0, 1);
    21.     private Vector2 tForest = new Vector2 (1, 1);
    22.     private Vector2 tMountain = new Vector2 (0, 0);
    23.     private Vector2 tHills = new Vector2 (1, 0);
    24.  
    25.     void Start () {
    26.  
    27.         mesh = GetComponent<MeshFilter> ().mesh;
    28.         col = GetComponent<MeshCollider> ();
    29.  
    30.         GenTerrain ();
    31.         BuildMesh ();
    32.         UpdateMesh ();
    33.  
    34.     }
    35.  
    36.     void Update () {
    37.  
    38.     }
    39.  
    40.     void GenTerrain () {
    41.  
    42.         blocks = new byte [10, 10];
    43.  
    44.     }
    45.  
    46.     void BuildMesh () {
    47.  
    48.     }
    49.  
    50.     void ColliderTriangles () {
    51.  
    52.         colTriangles.Add (colCount * 4);
    53.         colTriangles.Add ((colCount * 4) + 1);
    54.         colTriangles.Add ((colCount * 4) + 3);
    55.         colTriangles.Add ((colCount * 4) + 1);
    56.         colTriangles.Add ((colCount * 4) + 2);
    57.         colTriangles.Add ((colCount * 4) + 3);
    58.  
    59.     }
    60.  
    61.     void GenCollider(int x, int y){
    62.  
    63.         colVertices.Add (new Vector3 (x, y, 1));
    64.         colVertices.Add (new Vector3 (x + 1, y, 1));
    65.         colVertices.Add (new Vector3 (x + 1, y, 0));
    66.         colVertices.Add (new Vector3 (x, y, 0));
    67.  
    68.         ColliderTriangles ();
    69.         colCount++;
    70.  
    71.         colVertices.Add (new Vector3 (x, y - 1, 0));
    72.         colVertices.Add (new Vector3 (x + 1, y - 1, 0));
    73.         colVertices.Add (new Vector3 (x + 1, y - 1, 1));
    74.         colVertices.Add (new Vector3 (x, y - 1, 1));
    75.  
    76.         ColliderTriangles ();
    77.         colCount++;
    78.  
    79.         colVertices.Add (new Vector3 (x, y - 1, 1));
    80.         colVertices.Add (new Vector3 (x, y, 1));
    81.         colVertices.Add (new Vector3 (x, y, 0));
    82.         colVertices.Add (new Vector3 (x, y - 1, 0));
    83.  
    84.         ColliderTriangles ();
    85.         colCount++;
    86.  
    87.         colVertices.Add (new Vector3 (x + 1, y, 1));
    88.         colVertices.Add (new Vector3 (x + 1, y - 1, 1));
    89.         colVertices.Add (new Vector3 (x + 1, y - 1, 0));
    90.         colVertices.Add (new Vector3 (x + 1, y, 0));
    91.  
    92.         ColliderTriangles ();
    93.         colCount++;
    94.  
    95.     }
    96.  
    97.     void GenSquare(int x, int y, Vector2 texture){
    98.  
    99.         newVertices.Add (new Vector3 (x, y, 0));
    100.         newVertices.Add (new Vector3 (x + 1, y, 0));
    101.         newVertices.Add (new Vector3 (x + 1, y - 1, 0));
    102.         newVertices.Add (new Vector3 (x, y - 1, 0));
    103.  
    104.         newTriangles.Add (squareCount*4);
    105.         newTriangles.Add ((squareCount*4)+1);
    106.         newTriangles.Add ((squareCount*4)+3);
    107.         newTriangles.Add ((squareCount*4)+1);
    108.         newTriangles.Add ((squareCount*4)+2);
    109.         newTriangles.Add ((squareCount*4)+3);
    110.  
    111.         newUV.Add (new Vector2 (tUnit * texture.x, tUnit * texture.y + tUnit));
    112.         newUV.Add (new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y + tUnit));
    113.         newUV.Add (new Vector2 (tUnit * texture.x + tUnit, tUnit * texture.y));
    114.         newUV.Add (new Vector2 (tUnit * texture.x, tUnit * texture.y));
    115.  
    116.         squareCount++;
    117.  
    118.     }
    119.  
    120.     void UpdateMesh () {
    121.  
    122.         mesh.Clear ();
    123.         mesh.vertices = newVertices.ToArray ();
    124.         mesh.triangles = newTriangles.ToArray ();
    125.         mesh.uv = newUV.ToArray ();
    126.         mesh.Optimize ();
    127.         mesh.RecalculateNormals ();
    128.  
    129.         newVertices.Clear ();
    130.         newTriangles.Clear ();
    131.         newUV.Clear ();
    132.         squareCount = 0;
    133.  
    134.         Mesh newMesh = new Mesh ();
    135.         newMesh.vertices = colVertices.ToArray ();
    136.         newMesh.triangles = colTriangles.ToArray ();
    137.         col.sharedMesh = newMesh;
    138.  
    139.         colVertices.Clear ();
    140.         colTriangles.Clear ();
    141.         colCount = 0;
    142.  
    143.         }
    144. }
     
    Last edited: Mar 31, 2015
  2. Sketchward

    Sketchward

    Joined:
    Mar 30, 2015
    Posts:
    6
    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)

    Code (csharp):
    1. void GenTerrain(){
    2. blocks=new byte[10,10];
    3. for(int px=0;px<blocks.GetLength(0);px++){
    4. for(int py=0;py<blocks.GetLength(1);py++){
    5. if(py==5){
    6. blocks[px,py]=2;
    7. } else if(py<5){
    8. blocks[px,py]=1;
    9. }
    10. if(px==5){
    11. blocks[px,py]=0;
    12. }
    13. }
    14. }
    15. }
    16. void BuildMesh(){
    17. for(int px=0;px<blocks.GetLength(0);px++){
    18. for(int py=0;py<blocks.GetLength(1);py++){
    19. if(blocks[px,py]!=0){
    20. GenCollider(px,py);
    21. if(blocks[px,py]==1){
    22. GenSquare(px,py,tStone);
    23. } else if(blocks[px,py]==2){
    24. GenSquare(px,py,tGrass);
    25. }
    26. }
    27. }
    28. }
    29. }
     
  3. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,350
    Where is your array created, whats inside it?
     
  4. Sketchward

    Sketchward

    Joined:
    Mar 30, 2015
    Posts:
    6
    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.
     
    Last edited: Mar 31, 2015
  5. Sketchward

    Sketchward

    Joined:
    Mar 30, 2015
    Posts:
    6
    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.

    Code (csharp):
    1. void BuildMesh(){
    2. GenSquare(px,py,*********);
    3. px++
    4. }
    5.  
    6. if(px==127){
    7. GenSquare(px,py,*********);
    8. px=0
    9. py++
    10. }
    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.
     
  6. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    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:
    Code (csharp):
    1.  
    2. // Create map
    3. Vector2[,] tileTextureCoords = new Vector2[mapSizeX, mapSizeY];
    4. // Assign variables
    5. tileTextureCoords[13,37] = tGrassland;
    6. tileTextureCoords[3,14] = tHills;
    7.  
    8. // And when generating the squares:
    9. GenSquare(px, py, tileTextureCoords[px, py]);
    10.  
     
  7. Sketchward

    Sketchward

    Joined:
    Mar 30, 2015
    Posts:
    6
    This sounds exactly like what I want to do, thank you so much.
     
  8. Sketchward

    Sketchward

    Joined:
    Mar 30, 2015
    Posts:
    6
    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. :oops:

    Code (csharp):
    1.     void GenTerrain(){
    2.  
    3.         blocks = new byte[2, 2];
    4.  
    5.     }
    6.  
    7.     void BuildMesh(){
    8.  
    9.         Vector2[,] textCoords = new Vector2[2,2];
    10.  
    11.         textCoords [0, 0] = tGrassland;
    12.         textCoords [1, 0] = tGrassland;
    13.         textCoords [0, 1] = tForest;
    14.         textCoords [1, 1] = tForest;
    15.  
    16.         for (int px=0; px<blocks.GetLength (0); px++) {
    17.             for (int py=0; py<blocks.GetLength (0); py++){
    18.  
    19.                 GenSquare (px,py,textCoords[px,py]);
    20.                 px++;
    21.                
    22.                 if (px==1){
    23.                    
    24.                     GenSquare (px,py,textCoords[px,py]);
    25.                     py++;
    26.                     px=0;
    27.  
    28.                 }
    29.             }
    30.         }
    31.     }
     
  9. ThermalFusion

    ThermalFusion

    Joined:
    May 1, 2011
    Posts:
    906
    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:
    Code (csharp):
    1.   for (int px=0; px<blocks.GetLength (0); px++) {
    2.     for (int py=0; py<blocks.GetLength (0); py++){
    3.         GenSquare (px,py,textCoords[px,py]);
    4.     }
    5. }