本文へスキップ

Godot タイルマップ 当たり判定 · アルファから自動作成

47枚のタイルに1枚ずつコリジョンを描くのは手間がかかり、1ピクセルずれるだけでキャラクターが継ぎ目に引っかかります。タイル作業画面は各タイルのアルファから形状を取り、ずれた点はドラッグで直せます。物理レイヤーはGodot自身が実行するインポートスクリプトが作ります。

Godot 4では、タイルの衝突はTileSetにあります。物理レイヤー(衝突レイヤーとマスク)を追加し、タイルごとに1つ以上の衝突ポリゴンを与えます。点の座標はタイルの中心から測ります。Nerulioはタイルごとにアルファからポリゴンを取り(外形、正確な矩形群、ボックス1つ)、点を動かせるようにし、インポートスクリプトが衝突レイヤー1・マスク1の物理レイヤー0を作り、各ポリゴンを半タイルずらして書き込みます。Godot 4.7.2で全ポリゴンを点単位で読み戻して確認しました。

タイルセットやオートタイルのシート(PNG)をドロップ
空のStudioを開く
ブラウザ内で処理し、ファイルはアップロードされません。
Studio のタイル作業画面:全タイルのアルファから衝突ポリゴンをトレースしたCC0のブロブ47タイルセット(16px)
CC0アセット(OpenGameArt)を開いた実際のStudio画面です。
書き出し先
  • Godot 4 TileSet検証済み· Godot 4.7.2
  • Tiled検証済み· Tiled 1.12.2
  • Unity 6 Rule Tile検証済み· Unity 6000.5.3f1 + 2D Tilemap Extras 8.0.3
  • LDtk一部検証· LDtk 1.5.3 schema + loader

物理レイヤー、ポリゴン、タイルの中心

TileSetには物理レイヤーのリストがあり、レイヤーごとに衝突レイヤー・衝突マスク・任意の物理マテリアルを持ちます(Godotのドキュメント:TileSetインスペクター › Physics Layers › Add Element)。レイヤーごとに1枚のタイルが複数のポリゴンを持てて(TileData.set_collision_polygon_points(layer, index, points))、それぞれ一方通行にもできます。TileMapLayerはcollision_enabledが有効(既定)なら、塗ったタイルを静的な衝突にします。

Nerulioは形状を描いたとおりに、タイルのピクセル単位・原点はタイル左上で保存します。Godotはタイルのポリゴンを中心から測るので、インポートスクリプトが全点からタイルサイズの半分を引きます。このずらしを忘れるツールでは、すべての形状が左上に半タイルずれます。

アルファの読み方は3通りです(アルファが0より大きければ不透明とみなします)。外形はピクセルの境界に沿って不透明な縁をなぞり、外側のループだけを残すので穴は埋まります。正確な矩形群は不透明なピクセルだけを数個の矩形で覆い、穴は開いたままです。ボックスは全体を1つの矩形で囲みます。長い外形は点が256個以下になるまで単純化します。

物理レイヤー
衝突レイヤー・マスク・マテリアルを持つTileSetの枠。タイルは枠ごとにポリゴンを持ちます。
衝突ポリゴン
タイル中心基準の点のリスト。内側全体がふさがった場所になります。
衝突レイヤー/マスク
タイルが属するレイヤーと検出するレイヤー。ボディのマスクにタイルのレイヤーが含まれていればぶつかります。
半タイルのずらし
左上基準のタイルピクセル −(幅 ÷ 2、高さ ÷ 2)= Godotの中心基準の座標。

例:64pxの地面タイル、ピクセルからGodotまで

64 × 64タイル、下の40pxが地面(ピクセル行24–63)
Nerulio、タイルのピクセル(原点は左上)   (0,24) (64,24) (64,64) (0,64)
半タイル = (32, 32)
Godot、タイル中心基準                     (-32,-8) (32,-8) (32,32) (-32,32)
インポート  TileData.set_collision_polygon_points(0, 0, points)   物理レイヤー0、ポリゴン0
TileSet     物理レイヤー0: collision_layer 1, collision_mask 1

CharacterBody2Dはcollision_maskにレイヤー1が含まれているときだけこのタイルの上に立ちます。プロジェクトが別のレイヤー番号を使うなら、インポート後にTileSetの番号を変えてください。

できること

  • アルファの読み方は3通り。外形ポリゴンは不透明部分の縁をたどり、正確な矩形は不透明ピクセルだけを軸に沿った矩形で覆い、ボックスは全体を1つの矩形で囲みます。
  • 形状はタイルのピクセル単位で、整数にスナップ。点はドラッグで移動、辺をダブルクリックで追加、Alt+クリックで削除。1回の編集が1回の取り消し単位です。
  • 「すべてのタイルの形状を表示」でシート全体の当たり判定を重ねて表示。隣り合うタイルのすき間を書き出し前に見つけられます。
  • 書き出し時、手で直した形状はそのまま。触れていないタイルだけを、選んだ方式でアルファから作成。
  • nerulio_tileset_import.gdが物理レイヤーを1つ(コリジョンレイヤー1、マスク1)追加。Godotはタイルの中心から形状を測るので、半タイル分ずらして書き込みます。
  • Godot 4.7.2で作ったTileSetを読み戻し、全ポリゴンが点単位で一致:コーパスのブロブセットで49/49・48/48・47/47タイル、4地形のデュアルグリッドで80/80。

使い方

  1. タイルセットをドロップし、「このグリッドを使う」を押す。
  2. 配置を適用するか地形ビットを塗る(ビットのあるタイルだけが形状を持てます)。
  3. Cキーを押してタイルを選び、外形ポリゴン・正確な矩形・ボックスのどれかで作成し、ずれた点をドラッグで修正。
  4. 書き出し(Ctrl+E)でGodot 4を選び、未編集タイルに使う方式を決める。
  5. Godotでnerulio_tileset_import.gdをFile › Runで実行し、保存されたTileSetをTileMapLayerに設定。

出力されるファイル

衝突は書き出しのGodotファイルの中に入ります。

ファイル用途
nerulio-tileset.jsonphysicsLayers(衝突レイヤー1、マスク1、使った方式)と、タイルごとのcollision:タイルピクセル単位のポリゴン。
nerulio_tileset_import.gd物理レイヤーを追加し、各ポリゴンを半タイルずらして書き込みます。出力行にポリゴン数が出ます。
nerulio-tileset.tresスクリプト実行時にGodotが保存する、地形と衝突入りのTileSet。

衝突をGodotに取り込んで試す

  1. Nerulioの書き出しパネルでCollision (Godot)を外形ポリゴン、正確な矩形群、ボックス、編集した形状のみのいずれかにします。既定のNoneでは物理レイヤーがまったく書かれず、編集した形状も含まれません。
  2. PNG・JSON・スクリプトをプロジェクトのルートにコピーし、File › Runでスクリプトを実行して出力行を確認します(例:… 47 tiles, 188 peering bits, 47 collision polygons …)。
  3. TileMapLayerのTile Setプロパティにnerulio-tileset.tresを設定して塗ります。
  4. プレイヤーのボディのcollision_maskにレイヤー1を含めます(またはTileSetインスペクターで物理レイヤー0の衝突レイヤーをプロジェクトの番号に変えます)。
  5. Debug › Visible Collision Shapesを有効にしてシーンを実行すると、ゲーム実行中にタイルの上へ衝突形状が描かれます。
  6. 一方通行の足場や物理マテリアルは、TileSetエディターのSelectモードでタイルをクリックしてPhysics Layer 0セクションを編集します。そこでFを押すとタイル全体の矩形がすぐできます。

結果の確認

  • スクリプトの出力行の衝突ポリゴン数が想定どおりであること(ボックスとほとんどの外形はタイルごとに1つ)。
  • TileSetエディター › Selectモードでタイルをクリックすると、Physics Layer 0セクションに絵の上のポリゴンが表示されます。
  • Visible Collision Shapesを有効にすると、隣り合う地面タイルの上辺が1本の線につながり、正確な矩形群を使った隙間のあるタイルでは隙間が見えるはずです。
  • print($TileMapLayer.tile_set.get_physics_layer_collision_layer(0))が1を出力します。

方式ごとにGodotへ入るもの

方式書き出される形状穴向いているタイル
外形ポリゴンピクセルの境界をたどった外側の輪郭。不透明な塊ごとに1ポリゴン埋まる(外側の輪郭のみ)坂、丸い段差、不規則な岩
正確な矩形合わせると不透明ピクセルとぴったり一致する、軸に沿った数個の矩形開いたまますき間のあるタイル、L字、切り欠きのある足場
ボックス透明でないピクセル全体を囲む矩形1つ埋まる全面ブロック、木箱、軽い物理
編集した形状のみ手で直したポリゴンだけ。ほかのタイルは形状なし描いたとおり一部のタイルだけ当たればよいとき
なし物理レイヤーを作らない—装飾用のタイルセット

完全に不透明なタイルは、ボックスと正確な矩形ではタイルサイズの正方形1つになります。長い輪郭は、1タイルあたり256点以下になるまで簡略化されます。

トラブルシューティング

症状考えられる原因確認方法対処
TileSetに物理レイヤーがない書き出しでCollision (Godot)をNoneのままにした出力行の0 collision polygons衝突の方式を選んで書き出し直す
キャラクターがタイルをすり抜けて落ちるボディのマスクにレイヤー1がない、またはレイヤーのcollision_enabledがオフボディとTileMapLayerのインスペクターマスクにレイヤー1を加えるか、TileSetの物理レイヤーをプロジェクトのレイヤーにする
形状が左上に半タイルずれる左上基準の座標をずらさずに書くツールから来たポリゴンVisible Collision Shapesずらしを行うNerulioのスクリプトで取り込み直す
穴のあるタイルが全部ふさがる外形は外側のループだけを残すTileSetエディターのタイルのポリゴンそのセットは正確な矩形群にするか、そのタイルの点を直す
キャラクターがタイルの継ぎ目に引っかかる隣のポリゴンの高さが1ピクセル違うVisible Collision Shapesで継ぎ目を拡大全面タイルはボックスか正確な矩形群にするか、Studioの衝突ツール(C)で点の高さをそろえる
一部のタイルに形状がない地形ビットのあるタイルだけを書き出し、アルファがすべて0だと形状はできないStudioではビットのないタイルが暗く表示されるそのタイルにビットを塗るか、Godotで手で形状を描く

ほかの方法

方法こんなときに向いています
GodotのTileSetエディターでポリゴンを描く(Fで全体の矩形、点の追加・削除、タイルプロパティペイントで1つの形状を多数のタイルへ)全面ブロックと少しの坂だけのとき。ツールは要りませんが、形状は1つずつ手で置きます。
タイルではなくスプライトの衝突:衝突ポリゴンジェネレーター形状がTileSetのタイルではなく、キャラクターや小物のものであるとき。
ColliderをGridにしたUnityのRule Tile:UnityのRule Tile対象がUnityのとき。Nerulioで取ったポリゴンはGodot向けにだけ書かれます。

エンジン別の書き出しと検証方法

「検証済み」は、実際のCC0アセットから書き出したファイルを本物のエンジン・ツールで読み込み、元データと比較したという意味です。読み込んでいない形式はそのように表示します。

書き出し先ファイル検証
Godot 4 TileSetPNG · nerulio-tileset.json · nerulio_tileset_import.gd検証済み Godot 4.7.2同梱のインポートスクリプトが地形ピアリングビット付きのTileSetを作成。set_cells_terrain_connectで塗ったマップが、9つのコーパスシートの全セルでStudioのプレビューと一致。
Tiled.tsx Wang set · sample.tmx検証済み Tiled 1.12.2Tiled自身の読み込みで全Wang IDが記述どおりに読まれ、サンプルマップはピクセル単位で一致。地形ブラシ自体は操作していません。
Unity 6 Rule Tilenerulio-ruletile.json · Editor/NerulioRuleTileImporter.cs検証済み Unity 6000.5.3f1 + 2D Tilemap Extras 8.0.3ブロブ・辺タイルセット:塗ったTilemapの全セルが予測どおりのスプライト。角/デュアルグリッドはUnityへ書き出しません。
LDtk.ldtk (1.5.3) · rules · sample level一部検証 LDtk 1.5.3 schema + loaderLDtkのJSONスキーマと公式ローダーで受理され、ルールを再実行すると書き出したタイルと一致。LDtkアプリでは未確認。

検証の根拠

タイルコーパスでピクセルだけから配置を判定:ブロブ47テンプレート4つとWangテンプレート2つは高信頼度、実在の64px洞窟タイルセットは中信頼度で全タイルのビットが正解。Godot 4.7.2は全テストセルをStudioの予測どおりに塗りました(ブロブセットごとに485/485、4地形のデュアルグリッド251/251)。Tiled 1.12.2は全Wang IDを読み戻し、Unity 6000.5はブロブ・辺セットの塗った全セルで一致。

制限

  • 物理レイヤーは1つ、単純なポリゴンのみ:一方通行、追加レイヤー、物理マテリアルは後でGodotで設定します。
  • 穴が正確になるのは正確な矩形群だけです。
  • 地形ビットのないタイルは、書き出しで衝突を持ちません。
  • Tiledの地形ブラシ、LDtkアプリ、Godotエディターでの塗りは操作していません。検証はエンジンの読み込み機能とset_cells_terrain_connectで行いました。
  • Unityへはブロブ・辺タイルセットのみ。地形が複数あると、互いにつながらないRule Tileが複数になります。
  • アイソメトリック・六角タイル、アニメーションタイル、オクルージョン・ナビゲーションレイヤーは対象外です。
  • 既知の配置なしでビットを提案するには基準となる「塗りつぶし」タイルが必要です。辺だけの道テンプレートでは、そのタイルを選ぶまで推定を誤ることがあります。

バージョンと出典

Godot 4.7.2で、保存したTileSetを読み戻して確認しました。半タイルのずらしの後、全ポリゴンが点単位で一致しました。コーパスのブロブセットで49/49、48/48、47/47タイル、辺・角のテンプレートで16/16、4地形のデュアルグリッドパックで80/80。エディターの手順はGodot 4.7の公式ドキュメントに基づきます。

参照した公式ドキュメント

よくある質問

キャラクターが床をすり抜けます。物理レイヤーは入っていますか?

インポートスクリプトは、形状を持つタイルが1枚でもあるときだけ物理レイヤーを追加し、コリジョンレイヤー1・マスク1に設定します。キャラクター側のコリジョンマスクにレイヤー1が含まれているか確認してください。別の番号を使うプロジェクトなら、インポート後にTileSetで変更します。

穴のあるタイルが、穴まで埋まった当たり判定になります

外形ポリゴンは外側の輪郭だけを残し、Godotはポリゴンの内側をすべて固体として扱うため、穴が埋まります。正確な矩形は不透明ピクセルだけを覆うので、穴は開いたままです。

すり抜け床やタイルごとのレイヤーもここで設定できますか?

いいえ。書き出すのは物理レイヤー1つとポリゴンだけです。一方通行の当たり判定、追加のレイヤー、物理マテリアルは、インポート後にGodotのTileSetエディターで設定してください。

UnityのタイルマップやTiled、LDtkにも当たり判定は入りますか?

いいえ、当たり判定はGodot向けだけです。UnityのRule Tile、Tiled、LDtkの書き出しにはタイルとルールだけが入り、形状は入りません。Unity側でのタイルの当たり判定は確認していません。

無料ですか?アカウントは必要ですか?

このページの機能はすべて無料で、アカウントなしで使えます。透かしや制限された書き出しはありません。

スプライトはアップロードされますか?

いいえ。Studioはこのブラウザのタブ内でデコード・パック・書き出しを行います。プロジェクトはブラウザ(IndexedDB)に自動保存され、.nerulioファイルとして保存できます。

Asepriteやエンジンのプラグインは必要ですか?

いいえ。.asepriteファイルはブラウザで読み書きします。エンジン別のバンドルには必要なものが入っています(Godotはインポート設定とシーン、UnityとGodotのタイルセットは小さなエディタースクリプト)。