Skip to content

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.

csharp
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 one0 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.

csharp
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.

csharp
// 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.

csharp
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.

csharp
// 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.

csharp
public void Regenerate(int seed)
{
    m_Map!.Clear();
    GenerateCave(seed);
}

Example: a procedural cave

csharp
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