2Dゲームでマップを作るとき、スプライトを1枚ずつ並べていくのはとても大変・・・そんなときに使いたいのがTilemap!お絵かきソフトのようにマス目を塗るだけでマップが作れます。この記事は以前書いた基本編を、Unity6.3 LTSの画面に合わせて書き直しました。タイルパレットの作成から、塗り方、当たり判定、スクリプトでタイルを置く方法までまとめてご紹介します!

Tilemapでどんなことが出来る?
- グリッド(マス目)にスプライトを塗るように配置出来る
- グリッドの形を選べる
- Rectangle:四角。一番よく使う
- Hexagonal:六角形(Point Top/Flat Top)
- Isometric:ひし形のクォータービュー(Isometric/Isometric Z as Y)
- 塗ったタイルにまとめて当たり判定を付けられる
- Rule Tileを使うと、隣のタイルに合わせて自動で形が変わる道や地面が作れる
今回は基礎中の基礎、Rectangle(四角)のTilemapを使います。
プロジェクトの確認
- Unityのバージョンは6.3 LTS
- テンプレートは2D(Universal 2D)
- 2D Tilemap Editorと2D Tilemap Extrasは最初から入っています
- タイル用の画像(今回は16×16ピクセルのタイルを横8×縦4に並べた画像を使います)
- 手元にない人はAsset Storeで「tileset」と検索すると、無料のものがたくさん見つかります
タイルの画像を準備しよう
スプライトの設定
タイル用の画像をAssetsにドラッグ&ドロップして、インスペクターで下記のように設定します。
- Texture Type:Sprite (2D and UI)
- Sprite Mode:Multiple(1枚の画像に複数のタイルが並んでいる場合)
- Pixels Per Unit:タイル1枚のピクセル数(16×16なら16)
- Filter Mode:Point (no filter)
- Compression:None
最後にApplyを押します。

Pixels Per Unitはタイル1枚のピクセル数と同じにしておくと、タイル1枚がちょうど1マス(1ユニット)の大きさになります。
スライムPixels Per Unitがタイルのサイズと合っていないと、タイルとタイルの間に隙間が出来たり、重なったりします・・・ドット絵ならFilter ModeをPointにするのも忘れずに
Sprite Editorでタイルを切り分ける
1枚の画像にタイルが並んでいる場合は、Sprite Editorで1マスずつに切り分けます。
- インスペクターのOpen Sprite Editorを押す
- 左上のSliceを開く
- Type:Grid By Cell Size
- Pixel Size:X 16 / Y 16
- Sliceボタンを押す
- 右上のApplyを押す


切り分けたスプライトには、tileset_0、tileset_1・・・のように左上から順番に名前が付きます。
Sliceボタンを押しただけでは、まだ保存されていません。右上のApplyを押すのを忘れると、Sprite Editorを閉じたときに切り分けが元に戻ってしまいます。
タイルパレットを作ろう
タイルパレットは、塗るときに使う「絵の具のパレット」のようなものです。
- Window>2D>Tile Paletteでタイルパレットウインドを開く
- タイルが並ぶところのすぐ上のプルダウンから、Create New Tile Paletteを選択
- Name:MapPalette
- Grid:Rectangle
- Createを押して、保存するフォルダを選ぶ(Assets/Tilemap/Palettesなど)


パレットが出来たら、切り分けたスプライトをタイルパレットウインドにドラッグ&ドロップします。タイルアセットの保存先を聞かれるので、Assets/Tilemap/Tilesなどのフォルダを選べばOKです。


シーンにTilemapを置いて塗るッ!
Tilemapを追加
- GameObject>2D Object>Tilemap>Rectangularを選択
- HierarchyにGridと、その子どものTilemapが作られる
Gridがマス目のサイズを、Tilemapが塗ったタイルの情報を持っています。
タイルを塗る
- タイルパレットウインドの塗り先のプルダウン(Active Target)がTilemapになっていることを確認
- パレットの中から塗りたいタイルをクリックして選択
- Sceneビューでクリックやドラッグをすると、タイルが塗られる
下図のように塗れたら成功!


ドラッグするだけで地面が広がっていくので、マップ作りがかなり楽しくなります。広い範囲はBox Fillでまとめて塗ると早いです。
よく使うツールとショートカット
タイルパレットウインドの上に並んでいるツールは、ショートカットで切り替えられます。覚えておくと作業がかなり楽になります。


- Select(S):範囲を選択
- Move(M):選択した範囲を移動
- Paint(B):1マスずつ塗る
- Box Fill(U):四角い範囲をまとめて塗る
- Pick(I):Sceneビューのタイルを拾って、そのタイルで塗れるようにする
- Erase(D):消しゴム
- Flood Fill(G):囲まれた範囲を塗りつぶす
- 塗る前に「[」「]」キーでタイルを回転
個人的に一番使うのはPick(I)です。Sceneビューで同じタイルを塗りたいとき、パレットから探し直さなくて済みます。
レイヤーを分けて重ねよう
地面・装飾・壁のように、Tilemapを分けておくと後から編集しやすくなります。当たり判定を付けたいのは壁だけ、ということも多いです。
- Hierarchyで、Gridの中のTilemapを複製して名前を付ける
- Ground:地面
- Decoration:草や花などの飾り
- Wall:壁
- それぞれのTilemap RendererのOrder in Layerを設定
- Ground:0
- Decoration:1
- Wall:2
- 塗るときは、タイルパレットウインドの塗り先のプルダウンで塗り先を切り替える


塗り先を切り替え忘れると、飾りの花を地面のTilemapに塗ってしまいます。塗る前にプルダウンの名前を見るクセを付けておきましょう。
当たり判定を付けよう
壁のTilemapに当たり判定を付けます。
- WallのTilemapにTilemap Collider 2Dを追加
- 同じオブジェクトにComposite Collider 2Dを追加
- Rigidbody 2Dも自動で追加される
- Rigidbody 2DのBody Type:Static
- Tilemap Collider 2DのComposite Operation:Merge


Composite Collider 2Dを使うと、1マスずつバラバラだった当たり判定が1つにまとまります。



まとめておくと、壁のつなぎ目でプレイヤーが引っかかりにくくなるよ!
- 古いバージョンの記事では「Used By Composite」にチェックを入れる手順になっています
- Unity6.3ではComposite Operationのプルダウンに変わっていて、Mergeを選ぶのが同じ意味です
- Body TypeをStaticにしないと、再生したときに壁が下に落ちていきます
スクリプトでタイルを置いたり消したりする
ゲーム中にタイルを置いたり、そのマスにタイルがあるか調べたり出来ます。ここではクリックしたマスにタイルを置く・消すスクリプトを作ってみましょう。InputSystemはUnity6でInputSystemを使うチュートリアルで作ったInputSystem_Actionsを使っています。
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Tilemaps;
public class TileClicker : MonoBehaviour
{
[SerializeField] private Tilemap tilemap;
[SerializeField] private TileBase tile;
private InputSystem_Actions inputActions;
private void Awake()
{
inputActions = new InputSystem_Actions();
}
private void OnEnable()
{
inputActions.Enable();
}
private void OnDisable()
{
inputActions.Disable();
}
private void Update()
{
if (!inputActions.Player.Attack.WasPressedThisFrame())
{
return;
}
Vector3 worldPosition = Camera.main.ScreenToWorldPoint(Mouse.current.position.ReadValue());
Vector3Int cell = tilemap.WorldToCell(worldPosition);
// カメラのZ座標が入ってしまうので、Tilemapと同じ0にそろえる
cell.z = 0;
// タイルがあれば消して、なければ置く
tilemap.SetTile(cell, tilemap.HasTile(cell) ? null : tile);
}
}
空のゲームオブジェクトに追加して、インスペクターで下記を設定します。
- Tilemap:タイルを置きたいTilemap(今回はDecoration)
- Tile:置きたいタイルアセット(今回はキノコのtileset_15)
- タイルパレットにドラッグしたときに作られたものです
スクリプトのポイントをいくつか補足
- WorldToCellでワールド座標をマス目の座標に変換
- Tilemapの位置はVector3Intのマス目で扱います
- SetTileでタイルを置く・消す
- nullを渡すと、そのマスのタイルが消えます
- HasTileでタイルがあるか調べる
- 同じ仕組みで「このマスは壁か?」のような判定も作れます
- クリックはPlayer.Attackで受け取る
- 初期状態のInputSystem_Actionsでは、Attackにマウスの左ボタンが割り当てられています
再生して左クリックで、タイルが置けたり消えたりすれば成功!


- 何もないマスをクリックすると、キノコのタイルが置かれる
- 置いたマスをもう一度クリックすると、タイルが消える
- 塗っておいた地面や壁のタイルは、Decorationとは別のTilemapなので消えない
Tilemapは「マス目の座標でタイルを出し入れする仕組み」と覚えておくと、ステージの自動生成やパズルゲームにもそのまま使えます。
うまくいかないときは
| 症状 | 確認するところ |
|---|---|
| タイルの間に線や隙間が出る | Pixels Per Unitがタイルのサイズと同じか。Filter ModeがPointか。それでも出る場合はSprite AtlasやPixel Perfect Cameraを使う |
| タイルが大きすぎる・小さすぎる | Pixels Per Unit |
| 塗れない | タイルパレットウインドの塗り先のプルダウン。Paintツールが選ばれているか |
| 当たり判定が効かない | プレイヤー側にもRigidbody 2DとCollider 2Dが付いているか。Composite OperationがMergeか |
| スクリプトで置いたタイルが見えない | cell.zを0にしているか。Tilemapに設定したのが見えているTilemapか |
Gameビューを縮小して表示していると、タイルのつなぎ目にうっすら線が見えることがあります。Scale(倍率)を1xにしたり、ビルドして確認すると消える場合は、表示の縮小によるものなので気にしなくて大丈夫です。
次のステップ
- 道や地面の縁を自動でつなげたい人はTilemapを自動で並べたり、形によって切り替わるタイルの作り方
- Unity6.3の2D(Universal 2D)テンプレートには2D Tilemap Extrasが最初から入っているので、記事内のGitでの導入は不要です
- クォータービューのマップを作りたい人はIsometric Tilemapで作った地形の裏周りができるようにする
今後のゲーム制作の記事でも、2Dのマップは基本Tilemapで作っていく予定です。



マップ作りを始めると、気づいたら何時間も経ってる・・・



楽しくなってきたら成功のサインだね!作ったマップはぜひSNSで見せてね!

コメント