Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Random 2D tile engine question

Discussion in 'Scripting' started by SYNYSTER, Feb 13, 2012.

  1. SYNYSTER

    SYNYSTER

    Joined:
    Jul 13, 2011
    Posts:
    21
    Code (csharp):
    1. void Start () {
    2.     tiles[0] = grass;
    3.     tiles[1] = dirt;
    4.  
    5.     Generate(0,0,20,20);
    6. }
    7.  
    8. void Generate(int i, int j, int Width, int Height) {
    9.     width = Width;
    10.     height = Height;
    11.     for (i = 0; i < width; i++) {
    12.        for(j = 0; j < height; j++) {
    13.          clone = Instantiate(tiles[Random.Range(0,tiles.Length)],new Vector2(i*tileWidth, j*tileHeight),Quaternion.identity)as GameObject;
    14.        }
    15.     }  
    16. }
    Is this the way I should generate a random tile engine or is there a better way? How can I make is so I can edit the tiles and change their textures during runtime? Is there a way to lower say the amount of dirt that is generated so that there is more grass than dirt?
     
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    First, the Instantiate shouldn't be able to take a Vector2 in the second spot.

    As for creating something, you would need to hold an array of the tiles that you are using. I would also suggest holding an array of prefabs that you are planning to use also.

    So here is a complete rewrite of what you had using a List (array) to hold the prefabs. Even though your game appears 2d, you are still using a 3d environment, so you will need to keep track of things like that too.

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5.  
    6.  
    7. public class Tiles : MonoBehaviour {
    8.     public List<GameObject> prefabs = new List<GameObject>();
    9.     public int width = 20;
    10.     public int length = 20;
    11.     public float scale = 10.0f;
    12.     private List<GameObject> tiles;
    13.    
    14.    
    15.     public void Start () {
    16.         if(prefabs.Count == 0) return;
    17.        
    18.         tiles = new List<GameObject>();
    19.         for(var i=0; i<width * length; i++) tiles.Add(null);
    20.        
    21.         Generate();
    22.     }
    23.  
    24.     public void Generate() {
    25.         if(prefabs.Count == 0) return;
    26.         int i, j;
    27.         float x, y;
    28.         for (i = 0; i < length; i++) {
    29.             for(j = 0; j < width; j++) {
    30.                 SetTile(j, i, (int)Random.Range(0,prefabs.Count));
    31.             }
    32.         }  
    33.     }
    34.    
    35.     public void SetTile(int x, int y, int index){
    36.         if(index < 0 || index >= prefabs.Count) return;
    37.         x = (int)Mathf.Clamp(x, 0, width);
    38.         y = (int)Mathf.Clamp(y, 0, length);
    39.         int i = GetTileIndex(x,y);
    40.         if(tiles[i]) Destroy(tiles[i]);
    41.         tiles[i] = Instantiate(
    42.             prefabs[index],
    43.             GetTilePosition(x, y),
    44.             Quaternion.identity)as GameObject;
    45.     }
    46.    
    47.     public void SetTexture(int x, int y, Texture2D texture){
    48.         x = (int)Mathf.Clamp(x, 0, width);
    49.         y = (int)Mathf.Clamp(y, 0, length);
    50.         int i = GetTileIndex(x,y);
    51.         if(!tiles[i]) return;
    52.         if(!tiles[i].renderer) return;
    53.         tiles[i].renderer.material.mainTexture = texture;
    54.     }
    55.                
    56.     private int GetTileIndex(int x,int y){
    57.         return x + y * width;  
    58.     }
    59.    
    60.     private Vector3 GetTilePosition(int x, int y){
    61.         return new Vector3(x, 0, y) * scale;
    62.     }
    63.    
    64.     // used for getting a position on the board from a point
    65.     public Vector2 GetBoardPosition(Vector3 position){
    66.         return GetBoardPosition(position.x, position.z);
    67.     }
    68.     public Vector2 GetBoardPosition(float x, float y, float z){
    69.         return GetBoardPosition(x, z);
    70.     }
    71.     public Vector2 GetBoardPosition(float x, float y){
    72.         return new Vector2(Mathf.Floor(x / scale), Mathf.Floor(y / scale));
    73.     }
    74. }
    75.  
    76.  
    Feel free to use it, modify it. It needs many more things.

    As far as your second question. You could keep track of tile weights. Then when you do your random tiles, you add up all the weights and multiply a random number by that, then cycle through the prefabs, add up the weights until you find the one that is within that scale.

    grass: weight 3
    dirt: weight 1
    total: 4

    Random Number: 1
    associated tile: grass

    Random Number: 2
    associated tile: grass

    Random Number: 3
    associated tile: grass

    Random Number: 4
    associated tile: dirt
     
    Last edited: Feb 14, 2012
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,398
    Vector2 promotes to Vector3 (with 0 for z), so it's OK.

    --Eric
     
  4. SYNYSTER

    SYNYSTER

    Joined:
    Jul 13, 2011
    Posts:
    21
    Ok thanks I got it edited to work with my tiles. Would I be able to edit tiles at runtime with this script? A problem I was having with mine is that it wouldn't let me change anything at runtime. I want to be able to do something like click on a single tile and if its grass change the tile to dirt. I don't need code telling me exactly how to do it just a push in the right direction would be great. Like should I delete the tile that is there and instantiate a new dirt tile or should I just change the texture?
     
  5. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    Check out SetTile in my post. ;)
     
  6. SYNYSTER

    SYNYSTER

    Joined:
    Jul 13, 2011
    Posts:
    21
    Ok hmmm, thanks! I will figure it out
     
  7. mweldon

    mweldon

    Joined:
    Apr 19, 2010
    Posts:
    109
    Which creates cool bugs if you built your world with Y up like I did. :(