Skip to content

Tilemaps

Build levels out of a grid of reusable tiles — terrain, platforms, walls, decoration — and get collision for the solid parts without placing a single collider by hand.

Tilesets and tilemaps

What it is
Tileset (.jtileset)One image sliced into a grid of numbered tiles, plus what each tile means
Tilemap (a component)A grid in your scene that paints tiles from a tileset

One tileset, many tilemaps — the same terrain set used by every level in your game.

Making a tileset

Placeholder: the Tile Palette panel, showing a tileset's tiles in a grid with the paint tools above

Open the Tile Palette panel (Windows → Panels → 2D → Tile Palette) and press New…. In the dialog:

  1. Drag a .png or .jpg from the Content Browser into the texture slot.
  2. Set Tile size — the width and height of one tile in the image, in pixels.
  3. Set Spacing and Margin if your image has gaps between tiles or a border around the outside. Most exported tile sheets need 0 for both.
  4. Press Create and choose where to save the .jtileset.

The panel now shows every tile in the sheet as a grid you can click.

Shortcut from a Tilemap

If you drag a raw image straight onto a Tilemap component's tileset slot, the editor offers to run this same New Tileset flow for you.

Painting a level

  1. Add a tilemap. Right-click blank space in the Scene Hierarchy and pick 2D → Tilemap, or add the component to an existing entity with Add Component → 2D → Tilemap.
  2. Assign the tileset in the Properties panel.
  3. Pick a tile in the Tile Palette by clicking it. Drag across several to pick a multi-tile stamp.
  4. Choose a tool and paint in the viewport.
ToolWhat it does
BrushPaint the selected tile. Brush size widens the stroke
EraseClear cells back to empty
RectDrag out a rectangle and fill it
FillFlood-fill a contiguous area
PickClick a painted cell to make that tile the current selection
OffLeave paint mode, so viewport clicks select entities again as usual

Painting is a deliberate mode — you turn it on to paint and off to go back to normal editing, so you can't scatter tiles across a level by clicking around in it.

Paint strokes are undoable with Ctrl+Z.

Cell Size is world units, tile size is pixels

The tileset's Tile size says how to slice the image. The tilemap component's Cell Size says how big a tile is in the world. They're independent — that's how a 16-pixel tile set and a 32-pixel tile set can share the same grid.

Collision

Collision comes from the tiles themselves.

  1. Mark tiles as solid. Select a single tile in the Tile Palette and tick Solid. Do that for walls, floors and platforms; leave decoration unticked.
  2. Turn on colliders. On the Tilemap component, enable Generate Colliders.

That's it. Solid tiles now stop physics bodies. The engine merges runs of adjacent solid tiles into larger rectangles rather than making one collider per tile, which keeps the physics cost down and — more visibly — stops characters catching on the seams between neighbouring tiles.

Friction, Restitution and Density on the Tilemap component apply to all of it. Colliders rebuild automatically when you change tiles at runtime.

Tile tags

Alongside Solid, each tile can carry a Tag — a short piece of text like ice, lava or spikes. Tags mean nothing to the engine; they exist so your scripts can ask what kind of ground something is standing on.

One-way platforms

Jumping up through a platform and landing on it from above is a Box Collider 2D feature, not a tile one — put a separate entity with a one-way box collider where you want that behaviour. Scripts can let a character drop through with IgnoreOneWayPlatforms. See 2D Physics.

Layers

Use several tilemap entities rather than trying to layer within one — a background map, a terrain map, a foreground map. Each is an ordinary entity, so its sorting order in the Properties panel controls what draws in front of what, exactly like sprites.

Only the terrain layer usually wants Generate Colliders on.

Changing tiles from a script

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);            // 0 clears the cell
    }
}
MemberWhat it does
GetTile(x, y) / GetTile(cell)The tile id in a cell. 0 means empty
SetTile(x, y, id) / SetTile(cell, id)Paint a cell. 0 erases it
GetTileTag(x, y) / GetTileTag(cell)The tag on whatever's in that cell
WorldToCell(worldPos)World position → cell coordinates
CellToWorld(cell)Cell coordinates → world position
Clear()Wipe every painted tile

Tile ids are one-based

A tile id is its index in the tileset plus one, because 0 is reserved to mean "empty". The first tile in your sheet is id 1. If you're building ids from a known index, add one yourself.

Combining the two, you can read the ground under a character:

csharp
Vector2Int under = m_Map.WorldToCell(new Vector2(Translation.X, Translation.Y - 0.6f));
if (m_Map.GetTileTag(under) == "ice")
    m_Friction = 0.05f;

Changing tiles rebuilds only the affected part of the map, so runtime edits — destructible terrain, a procedurally generated cave — are cheap enough to do while the game runs.

Importing from Tiled

Maps and tilesets authored in Tiled can be imported directly — .tmx maps and .tsx tilesets. Features Joystick doesn't have an equivalent for are skipped with a message saying exactly what was dropped, rather than silently.

Keeping large maps fast

  • Only visible chunks are drawn, so map size costs you memory rather than frame time.
  • Tiles batch into very few draw calls because they all come from one atlas.
  • Turn Generate Colliders off on decorative layers — collision is the expensive half.
  • Bigger tiles are cheaper than smaller ones for the same area covered.

See also

  • 2D Physics — collision, triggers, one-way platforms, and queries
  • Scenes — organising levels
  • Performance — measuring what a big map actually costs