Search Unity

Building a TileMap at runtime

Discussion in '2D' started by OccularMalice, Feb 24, 2018.

  1. OccularMalice

    OccularMalice

    Joined:
    Sep 8, 2014
    Posts:
    169
    Hi guys,

    I have a few hundred tiles that I created from sprites in a palette. I'm trying to figure out how to load these at runtime and apply them to a TileMap using C# for a 2D map.

    So something like this codewise:

    Code (CSharp):
    1.  
    2. for(x=0; x<200; x++) {
    3.   for(y=0; y<200; y++) {
    4.     map.SetTile(new Vector3Int(x, y, 0), GetTileForMap(world[x,y]));
    5.   }
    6. }
    7.  
    8. Tile GetTIleForMap(int tileType)
    9. {
    10.   // fetch a tile asset named "tiles_" + tileType
    11.   return tile;
    12. }
    13.  
    The map is a reference to my TileMap in the scene.
    world is a 2D array holding the type of ground at that x, y location (grass, water, etc.) built from a spritesheet of tiles that was used to generate the tile palette.

    All tile assets (created when I dragged my spritesheet into the palette) are "tile_x.asset" files in a folder under Assets/Tiles.

    I thought I could use Resource.Load on this but since they're not in a resources folder I can't do that. Otherwise I could do something like Resource.Load<Tile>("tiles_" + tileType) right? (only loading it once so I don't load the same tile asset over and over again). That would require me to move all the tile.asset files into a resources folder. Or is there something I'm missing like a way to reference a tile asset in the palette using it's x, y value or index?

    Thanks
     
  2. aflesher

    aflesher

    Joined:
    Dec 12, 2013
    Posts:
    28
    I solved this by creating a prefab that has a script that keeps references to all the different tiles I use on a given level. I just drag on the different tiles to the correct TileBase property in the Inspector for this prefab. This prefab gets instantiated on each level before I start call SetTile. Mine looks something like this.

    Code (CSharp):
    1. public class ThemeResources : MonoBehaviour
    2. {
    3.     [Header("Slopes")]
    4.     public TileBase slopeLeftA;
    5.     public TileBase slopeLeftB;
    6.     public TileBase slopeRightB;
    7.     public TileBase slopeRightA;
    8.  
    9.     public TileBase angleLeft;
    10.     public TileBase angleRight;
    11.  
    12.     [Header("Bounds")]
    13.     public TileBase[] blocks;
    14. }
    You could just add a public function to this class to access the different tiles like this:

    Code (CSharp):
    1. TileBase GetTileForMap(int tileType)
    2. {
    3.   return blocks[tileType];
    4. }
    I found this gave me a lot of flexibility to write custom functions that for things like grabbing random blocks.