TilemapComponent
Read and paint tiles at runtime — destructible terrain, procedurally generated levels, reading what kind of ground a character is standing on. For building tilesets and painting by hand, see the Tilemaps guide.
public class DestructibleWall : GameEntity
{
private TilemapComponent? m_Map;
protected override void OnCreate()
{
m_Map = GetComponent<TilemapComponent>();
}
public void Explode(Vector2 worldPoint)
{
Vector2Int cell = m_Map!.WorldToCell(worldPoint);
m_Map.SetTile(cell, 0);
}
}Tile ids
A tile id is its index in the tileset plus one — 0 is reserved to mean "empty". The first tile in your sheet is id 1.
This catches everyone once
If you're computing ids from a known tileset index, add one yourself. Painting with an id you took straight from a zero-based loop paints the tile next door.
GetTile(int x, int y) / GetTile(Vector2Int cell)
The tile id in that cell, or 0 if empty. Returns uint.
if (m_Map.GetTile(5, 3) == IceTileId)
m_Map.SetTile(5, 3, 0);SetTile(int x, int y, uint tileId) / SetTile(Vector2Int cell, uint tileId)
Paints a cell. 0 erases it.
Only the affected part of the map is rebuilt — mesh and colliders both — so runtime edits are cheap enough to do while the game runs.
// Carve a tunnel.
for (int x = 0; x < 20; x++)
m_Map.SetTile(x, 4, 0);GetTileTag(int x, int y) / GetTileTag(Vector2Int cell)
The tag on whatever tile is in that cell, as a string. Tags are authored per-tile in the Tile Palette and mean nothing to the engine — they exist so your scripts can ask what kind of surface something is.
Vector2Int under = m_Map.WorldToCell(new Vector2(Translation.X, Translation.Y - 0.6f));
switch (m_Map.GetTileTag(under))
{
case "ice": m_Friction = 0.05f; break;
case "mud": m_Friction = 0.90f; break;
case "spike": TakeDamage(1); break;
default: m_Friction = 0.40f; break;
}WorldToCell(Vector2 worldPos)
Converts a world position to this map's cell coordinates. Returns a Vector2Int.
CellToWorld(Vector2Int cell)
The inverse — cell coordinates to a world position. Returns a Vector2.
// Place a pickup exactly on a tile.
Vector3 spot = new Vector3(m_Map.CellToWorld(cell).X, m_Map.CellToWorld(cell).Y, 0);Clear()
Wipes every painted tile on this map. There is no undo at runtime — this is for regenerating a procedural level, not for gameplay.
public void Regenerate(int seed)
{
m_Map!.Clear();
GenerateCave(seed);
}Example: a procedural cave
using JoystickEngine;
public class CaveGenerator : GameEntity
{
private const uint Rock = 1;
private TilemapComponent? m_Map;
protected override void OnCreate()
{
m_Map = GetComponent<TilemapComponent>();
Generate();
}
private void Generate()
{
m_Map!.Clear();
var rng = new System.Random(12345);
for (int x = 0; x < 64; x++)
{
for (int y = 0; y < 32; y++)
{
bool solid = rng.NextDouble() < 0.45;
m_Map.SetTile(x, y, solid ? Rock : 0);
}
}
}
}What isn't scriptable
The tileset, cell size, tint, and the collision settings (Generate Colliders, friction, restitution, density) are set in the Properties panel — there's no C# access in 0.1.0. Tile metadata (Solid and the tag) is authored in the Tile Palette; a script can read a tag but not change one.
See also
- Tilemaps guide — tilesets, painting, collision, Tiled import
- Physics2D — querying what a character is standing on
- 2D Physics — one-way platforms