Set and Get Tile data in an STETilemap from script
You can set or get tile data using the methods in the STETilemap component: SetTileData, SetTile, GetTileData and GetTile.
The difference between Tile and TileData is that TileData uses raw tile data stored in an unsigned int containing the tile flags (flip horizontal, flip vertical, rotate 90º), the brush id and the tile id. You can see more details in the tutorial Understanding TileData.
GetTile returns the Tile instance stored in the tileset used by the tilemap.
So, to call any of these methods, you first need a reference to an STETilemap.
Getting the STETilemap reference to work with
// Gets the gameObject with the name "tilemapName"
GameObject tilemapObj = GameObject.Find("tilemapName");
// Gets the STETilemap component from that gameObject
STETilemap tilemap = tilemapObj.GetComponent<STETilemap>();
Setting a tile at some position in the tilemap
The tilemaps are boundless and will grow their boundaries when necessary.
SetTile and SetTileData set a tile at a position. There are two versions of these methods.
One uses a Vector2 position. This sets the tile in the cell under the local position relative to the tilemap. You can use it, for example, to change the tile under the player’s position:
// playerTransform is a reference to the player transform
tilemap.SetTileData(playerTransform.position, 45); // sets the tile with id 45 in the cell under the player position
// Use this if the tilemap transform has changed its position, rotation or scale
tilemap.SetTileData(tilemap.transform.InverseTransformPoint(playerTransform.position), 45);
The other version uses two integers, gridX and gridY, to set or get the tile at a specific cell. gridX is the column and gridY the row.
After modifying a tilemap, you need to call UpdateMesh (to mark it to be updated during the next update) or UpdateMeshImmediate (to update it immediately).
Here are some examples of setting tiles:
// Set a tile at grid position (20, -5) with an empty tileId (-1) and a brushId of 5.
tilemap.SetTile(20, -5, -1, 5);
// The same using SetTileData. The brushId is shifted 16 bits to the left, because the first
// 16 bits store the tileId. Here tileId is 0, but it doesn't matter because the brush will
// change the tile after the tilemap updates.
tilemap.SetTileData(20, -5, (5 << 16));
// Set a tile at position (2f, 5f) — not the grid position (2, 5) — local to the tilemap, and apply flags
tilemap.SetTile(new Vector2(2f, 5f), 8, -1, eTileFlags.FlipH | eTileFlags.FlipV);
// And using SetTileData...
tilemap.SetTileData(new Vector2(2f, 5f), (8 << 16) | (uint)(eTileFlags.FlipH | eTileFlags.FlipV) << 28);
// Erase the tile at grid position (-4, 9); the tileData will be -1 (0xFFFFFFFF)
tilemap.Erase(-4, 9);
// Always remember to call this to update the tilemap mesh and see the changes
tilemap.UpdateMesh();
Getting a tile at some position in the tilemap
Now that you know how to set a tile, getting one works almost the same, returning the tile data at a (local or grid) position.
GetTile returns a reference to the Tile instance in the tileset used by the tilemap. To get the brush, use GetTileData and then tileset.FindBrush(brushId). Let’s see some examples:
// Get the tileData at grid position -4, -8
uint tileData = tilemap.GetTileData(-4, -8);
// Get the tileId, the brushId and the flags from tileData
int tileId = Tileset.GetTileIdFromTileData(tileData);
int brushId = Tileset.GetBrushIdFromTileData(tileData);
bool flipHorizontal = (tileData & Tileset.k_TileFlag_FlipH) != 0;
bool flipVertical = (tileData & Tileset.k_TileFlag_FlipV) != 0;
bool rot90 = (tileData & Tileset.k_TileFlag_Rot90) != 0;
eTileFlags tileFlags = (eTileFlags)(Tileset.GetTileFlagsFromTileData(tileData) << 28);
// Get the Tile or TilesetBrush object
Tile tile = tilemap.GetTile(-4, -8); // directly from the tilemap
tile = tilemap.Tileset.GetTile(tileId); // from the tileset, by tileId
TilesetBrush brush = tilemap.Tileset.FindBrush(brushId);
Some uses of the Tile object are to check whether it has colliders (for path finding, for example) or to read a custom parameter like typeOfMaterial or isWall:
// true if the tile is not null and has any collider set on it
bool hasCollider = tile != null && tile.collData.type != eTileCollider.None;
// -1 if the tile is null, otherwise the value of the "typeOfMaterial" parameter (or -1 if not set)
int typeOfMaterial = tile == null ? -1 : tile.paramContainer.GetIntParam("typeOfMaterial", -1);
// false if the tile is null, otherwise the value of the "isWall" parameter (or false if not set)
bool isWall = tile == null ? false : tile.paramContainer.GetBoolParam("isWall", false);
// When will the tile be null?
// It will be null if the tileId is -1, because the tile was not set or it was set to empty
// (e.g. tilemap.Erase(-4, -8)).