TileMapLayer + Navigationの制限
GodotのTileMap(Layer)はグリッドベースのオブジェクトを作成するのに便利な機能です。
経路探索を提供するNavigationにも対応しているのですが、残念ながらTileMapLayerに直接組み込まれているNavigationにはいくつかの制限があります。
制限の一つはAgentのサイズを考慮しないことで、Agentは壁に沿って移動しようとします。
TileMapLayerに衝突タイルを取り入れている場合、NavigationAgentはウエスト0cmのモデル体型という自認で移動しようとするので、結果壁に引っかかってしまいます。
これは主に仕様的な問題でNavigationはAgentが移動可能なエリアを作成する必要がありますが、TileMapLayerに組み込まれているNavigationはタイルごとに設定したNavigationPolygonをそのまま設置するため、Agentのサイズのように周囲のタイルに依存しているエリアの表現が出来ません。
グリッドに沿った規則的な動きがメインだったり、Navigationを利用するノードに物理的な相互作用が無いのであれば問題ありませんが、そうではない場合組み込みのTileMapNavigationが生成するシンプルすぎるメッシュは上手く使えないかもしれません。
また、StaticBody2DのようなTileMapとは別の障害物をNavigationに反映させるのも不便です。
対処法
4.3時点で見られる有効な対処法の一つはTileMapLayerの組み込みNavigationを無効化し、代わりにNavigaitionRegion2Dを使用することです。
これはTileMapLayerを含め、StaticBody2DやPolygon2Dなどの様々なジオメトリを考慮して
より高度に解析されたNavigationPolygonを作成してくれます。
注意点としてはNavigationRegion2Dを利用する場合、今のところNavigationのレイヤー0のみが対象になります。
また、画像ではSourceGeometryNodeをグループ指定にしていますが、デフォルトはRootNodeChildrenでここでのRootはNavigationPolygonの持ち主、NavigationRegion2Dノードを指します。
なのでこちらを使いたい場合はベイク対象のノードをNavigationRegion2D配下に移動する必要があります。
使用方法を大まかに説明するとTileSetで通行可能にしたいタイルをレイヤー0のNavigationで設定しNavigationRegion2Dを選択してベイクすれば、周囲の衝突オブジェクト(NavigationPolygonが設定されていないタイル、StaticBody2Dなどの衝突オブジェクト、タイルマップでの衝突タイル)やAgentのサイズ(NavigationPolygon.Agents.Radius)などを考慮して適切なNavigationPolygonを作成してくれます。
障害物オブジェクトの選択方法についてはNavigationPolygon.Geometry辺りのパラメータを調整します。
NavigationRegion2D自体の詳しい使い方は公式を参考にしてください
https://docs.godotengine.org/en/stable/tutorials/navigation/navigation_introduction_2d.html
例
1. TileMapLayer組み込みNavigation
2. TileMapLayer組み込みNavigation + 衝突あり
3. NavigationRegion2D + 衝突あり
1と3の例では目標に向かって移動出来ますが、
衝突が有り、幅が考慮されていない2の例ではAgentが最初の曲がり角に引っかかっています。
ついでに3ではStaticBody2DであるGodotアイコンも避けるようにメッシュが作成されています。
標準の機能を避けなければいけないというのは厄介ですが、ゲームの内容によっては標準の機能をでも問題ない可能性があります。
とはいえNavigationRegion2Dの方が汎用的で高度な機能を使える利点はあるのでそのへんは自身のプロジェクトの方向と相談してください。
参考
https://github.com/godotengine/godot/issues/69743
https://github.com/godotengine/godot/pull/70724
GodotのTileMapLayerとNavigationの間の問題についてもっと知りたい方はsmix8という方がかなり詳しいので追いかけてみるのも良いかもしれません。




