Godot入門:NavigationAgent2Dの使い方と活用法

はじめに

これまでのPath2DやPathFollow2Dは、あらかじめ定義された固定のルートに沿って移動するノードでした。しかし、RPGやタワーディフェンス、アクションゲームなど、多くのゲームでは「敵がプレイヤーを追いかけたい」「障害物を避けながらゴールへ移動したい」など、動的な経路探索が必要になります。そうした場面で活躍するのがNavigationAgent2Dノードです。

NavigationAgent2Dは、ゲーム空間に配置された障害物を自動で検知し、最適なルートを計算してくれます。この記事では、NavigationAgent2Dの基本的な使い方、必要なセットアップ、そして実践的な活用法を詳しく解説します。

NavigationAgent2Dとは?

NavigationAgent2Dは、2D空間で「目的地までの最適なパスを計算する」ノードです。事前に定義されたルートではなく、シーン内のNavigationRegion2Dが定義した通行可能エリアを参考にして、動的に経路を算出します。AIの意思決定ロジックの中核となるノードです。

カーナビをイメージしてください。目的地を設定すると、カーナビは「次は右です」「次の交差点を左です」と、その時点での最善の経由地を教えてくれます。NavigationAgent2Dも同様に、目的地を設定すると「次に向かうべき位置」を毎フレーム教えてくれるのです。

継承ツリー:


NavigationAgent2D → Node

Node直下を継承しているため、Node2Dではなく、CharacterBody2DやRigidBody2Dなどの物理ボディの子として配置するのが一般的です。




NavigationAgent2Dの構成図
NavigationAgent2DはNavigationRegion2Dが定義したエリア内で最適なパスを計算し、次のターゲット位置を返す

このノードを使うべき場面

  • RPGの敵AIがプレイヤーを追いかける:敵が障害物を避けながら、常にプレイヤーへ向かう動作。
  • 障害物を避けながらゴールへ移動:ダンジョン内で敵がパトロールするが、壁には衝突しない。
  • 複数ユニットの経路計算:タワーディフェンスやRTSゲームで、多数のユニットが目的地に向かう場合。
  • タワーディフェンスの敵の移動:敵が決められた「通行可能エリア」内を自動でゴールに向かう。

別のノードが適切な場面:

  • 敵の移動ルートが完全に固定で、障害物を避ける必要がない場合はPath2D+PathFollow2Dで十分。
  • 単純な直線移動であればCharacterBody2Dのvelocityを直接操作する方がシンプル。
  • 物理演算(重力、衝突反応)を重視する場合はRigidBody2Dを推奨。

主なプロパティと機能

プロパティ・メソッド 役割
target_position Vector2 敵が向かうべき目的地を設定。毎フレーム更新して追いかけ機能を実現
path_desired_distance float パス上の先読み距離(デフォルト:1.0)。大きいほど先を見て計画
target_desired_distance float 目的地に到達したと見なす距離(デフォルト:1.0)
get_next_path_position() → Vector2 Vector2 現在向かうべき次の地点を返す。毎フレーム呼び出してそこへ移動
is_navigation_finished() → bool bool 目的地に到達したかどうかを返す
navigation_finished シグナル signal 目的地に到達したときに発火
velocity_computed シグナル signal 速度計算が完了したときに発火(高度な使用法)

GDScript コード例1:敵がプレイヤーを追いかける基本形


extends CharacterBody2D

@export var max_speed = 200
var navigation_agent: NavigationAgent2D
var player: Node2D

func _ready():
# 子ノードからNavigationAgent2Dを取得
navigation_agent = $NavigationAgent2D
player = get_tree().get_first_node_in_group("player")

func _process(delta):
if player == null:
return

# 毎フレーム目的地をプレイヤーの位置に更新
navigation_agent.target_position = player.global_position

# 次に向かうべき位置を取得
var next_pos = navigation_agent.get_next_path_position()

# 敵からその位置への方向を計算
var direction = (next_pos - global_position).normalized()

# velocityに反映して移動
velocity = direction * max_speed
move_and_slide()

GDScript コード例2:目的地到達時のコールバック処理


extends CharacterBody2D

@export var max_speed = 150
var navigation_agent: NavigationAgent2D

func _ready():
navigation_agent = $NavigationAgent2D

# シグナルに接続
navigation_agent.navigation_finished.connect(_on_navigation_finished)

# 初期目的地を設定
navigation_agent.target_position = Vector2(500, 500)

func _process(delta):
# 敵が到達していなければ移動
if not navigation_agent.is_navigation_finished():
var next_pos = navigation_agent.get_next_path_position()
var direction = (next_pos - global_position).normalized()
velocity = direction * max_speed
move_and_slide()

func _on_navigation_finished():
# 目的地に到達したときの処理(例:パトロール地点の更新)
print("目的地に到達しました")
velocity = Vector2.ZERO




NavigationAgent2Dの経路計算結果
NavigationAgent2Dが計算したパスと、毎フレーム返される次のターゲット位置。敵がこのターゲットに向かうことで、動的に経路追従する

もっと使いこなす:カスタマイズできるパラメータ

パラメータ・テクニック 変えると何が起きるか
path_desired_distance大きめに設定 先読みが増えて、より滑らかだが前もった経路計画になる。反応が遅れることも
target_desired_distanceを大きく 目的地に「近づいた」と判定される距離が広がる。厳密な到達判定が必要なければ調整
NavigationRegion2DのNavigationPolygonをエディタで編集 敵が通行可能なエリアを制限。「この部屋は敵が入ってこない」といった表現が可能
遅延フレーム処理で複数敵を分散実行 毎フレーム全敵の経路計算をすると重くなるので、敵ごとに計算フレームをずらす
velocity_computed シグナルを使用 高度な移動制御(加速度、減速)を実装。単なる速度設定より滑らかな動き

まとめ

NavigationAgent2Dは、2D空間における動的な経路探索を実現するノードです。NavigationRegion2Dと組み合わせることで、敵がプレイヤーを追いかけたり、複数ユニットが目的地に向かったりするAI機能を簡単に実装できます。get_next_path_position()とis_navigation_finished()を活用すれば、複雑なゲームロジックを効率的に構築できます。

  • NavigationAgent2Dはプレイヤーなど移動するキャラクターの子ノードとして配置
  • target_positionで毎フレーム目的地を更新し、動的な追跡を実現
  • NavigationRegion2Dとセットで使用し、障害物を避けた経路計算が可能

次回は、2D画面上でUIやHUDをカメラに固定するCanvasLayerについて詳しく解説します。HUD・スコア表示、ポーズメニューなど、ゲームの見た目を調整する重要なノードです。

シリーズ:Godot 4 ノード解説

この記事はGodot 4.xをもとに執筆しています。

コメント