『navigation_astar』 デモプロジェクトを読む #1

(注)解説記事ではなくただの私的メモです。

godot公式がリンクしてる2D用のデモプロジェクトを読んで勉強。
こちら(github)▶︎https://github.com/godotengine/godot-demo-projects/tree/master/2d


このなかから今回は「navigation_astar」というのを見てみました。
DL場所 ▶︎ githubGodot Asset Library

わからないところは公式のリファレンスとかyoutube動画、あとはchatGPTに聞いたりして確認してます。

↓こういう感じのやつ


●ファイル

●シーン

メインgame.tscnのみ。

●スクリプト

【character.gd】と【pathfind_astar.gd】

【character.gd】

〈メソッド〉
_ready
_process
_unhandled_input
_move_to
_change_state

【処理概要】
①クリックで移動目標地点を決定/ ②タイルマップを使って経路を計算 /③キャラクターが目標地点に向かって移動/ ④移動が完了すると停止

〈メモ〉
_ready
 シーンツリーにノードが追加され、すべての子ノードがロードされたあとに一度だけ実行される。_init( )よりも後、_process( ) や _physics_process( ) よりも前に実行。

_process
 スクリプトがアクティブである間に毎フレーム呼び出されるコールバック関数。ゲームオブジェクトの更新やリアルタイム動作に使われる。
    

enum State { IDLE, FOLLOW }
   ・列挙型enumを定義。キャラクターの状態 IDLE(待機) FOLLOW(移動)。

@onready
   ・godot4以降に導入されたアノテーション(コードの動作を変更したり、補助的な情報を与えたりするもの)。@onreadyをつけた変数は、ノードが準備完了(_ready()が実行されるタイミング)になったときに初期化される。
   ・godot3以前は「onready」が使われてて、4以降でプロジェクトを実行するとエラーになるので、昔のプロジェクトを実行するときは「@」を付け加える。

_click_position クリックした目的地
_path 移動経路
_next_point 現在の移動先

_unhandled_input(event)  クリック時の処理

_move_to(local_position) 移動処理
「Steering Behavior」というゲームアルゴリズムが使われている。キャラクターが環境に適応しながら滑らかに移動するためのアルゴリズム。単純な直線運動じゃなくリアルな動きを表現できる。
 Steering Behaiviorの特徴「物理的な慣性を考慮・ターゲットに向かって自然に移動・障害物を避ける/追跡する/回避するなどの動作」

1 目標地点に向かう理想の速度 desired_velocityを計算

var desired_velocity = (local_position - position).normalized() * speed

  ・(local_position - position) 現在位置から目標位置への方向ベクトル
  ・.normalized()  ベクトルを単位ベクトル(長さ1)にする
  ・ * speed  目標の速度(speed = 200.0)を掛ける

2 現在の速度 _velocityとの差分(ステアリング)を求める

var steering = desired_velocity - _velocity

  ・_velocity はいまの移動速度
  ・desired_velocity - _velocityで「どのくらい方向を修正すべきか(=ステアリング)を求める
  ・いきなり目標速度にするのではなく、徐々に変化させるための計算

3 ステアリングを考慮して _velocity を更新

_velocity += steering / MASS

  ・MASS(質量)を調整することで、急激な加速や方向転換を防ぐ
  ・キャラクターの動きがスムーズになり、慣性が生まれる

4 位置を更新

position += _velocity * get_process_delta_time()
  
  ・_velocityにget_process_delta_time( ) (フレームごとの時間差)を掛けてフレームレートに依存しない移動を実現


5 キャラクターの向きを更新

rotation = _velocity.angle()

  ・移動方向にキャラクターの向きを合わせる

6 目標地点に到達したか確認

return position.distance_to(local_position) < ARRIVE_DISTANCE

  ・目標地点に十分近づいたら移動をとめる


_change_state(new_state) 状態の変更






【pathfind_astar.gd】


〈メソッド〉
_ready
_draw
round_local_position
is_point_walkable
clear_path
find_path

【処理概要】
① AStarGrid2D初期化、障害物設定/ ②経路計算/③キャラクターが通る道を視覚的に描画(航跡エフェクト)/④クリックで新しい経路を計算しキャラクターを移動

〈メモ〉
・character.gd(キャラクターの移動制御)と連携して、経路の計算をするスクリプト。

AStarGrid2Dというgodot4で実装されたクラスを使用。
・AStarGrid2DはA*アルゴリズム(→wiki)というグラフ探索アルゴリズムを使用した、グリッドベースの経路探索を行うためのクラス。
・2Dタイルマップやグリッドベースのゲームで、最適なルート計算をするのに便利。
・NavigationAgent2Dとの違い


  ・グリッド移動が必要なら AStarGrid2D
  ・より自由な移動なら   NavigationAganet2D

【処理詳細】
1 enum Tile{ OBSTACLE, START_POINT, END_POINT }

 TileMap上のタイル識別に使用

   Tile.OBSTACLE   障害物
   Tile.START_POINT 経路の開始地点
   Tile.END_POINT  経路の終点

2 定数の定義
3 変数初期化
4 _ready() astar(経路探索)の初期化

5 _draw() 経路を描画
_pathに探索済みの経路があれば線(draw_line)と円(draw_circle)を描画。経路を視覚的に確認できるようにする。

6 round_localposition( ) 

local_positonをタイルの中心に丸める(ローカル座標を最も近いグリッド位置にスナップする)
タイル単位で正確な移動ができるようにする
→キャラクターやオブジェクトの座標をマス目に揃えることで、綺麗に配置できる。

7 is_point_walkable( ) 指定位置が歩行可能かを判定
クリックした位置が経路探索エリア内 (is_in_boundsv()) であり、かつ
not _astar.is_point_solid(map_position)(通行可能)なら true を返す

8 clear_path( ) 経路をクリア
_path をクリア
タイルマップから 開始地点 (_start_point) と 終点 (_end_point) を削除
queue_redraw() で _draw() を再実行し、経路の描画を消す

9 find_path(): astarで経路探索
clear_path() で既存の経路を削除
開始地点 (_start_point) と 終点 (_end_point) を設定
astarを使って _path に経路を計算
_path が 空でなければ
開始地点と終点を TileMap に表示
queue_redraw() → _draw() を呼び出し 経路を描画
_path を duplicate() でコピーして返す(参照ではなく新しい配列を返す)


解説動画(あとで見る)

●AStarGrid2D

●Steering Behavior

Steering Behaviorの種類
このプロジェクトでは「Arrive(到達)」を実装してるけど、ほかに種類があるらしい。

Seek(追従) 目標地点に向かって一直線に進む
Flee(逃走) 目標地点から遠ざかる
Arrive(到達) 目標地点に近づくにつれて減速する
Pursue(予測追従) 相手の未来の位置を予測して追いかける
Evade(予測回避) 相手の未来の位置を予測して逃げる
Wander(ランダム移動) ランダムな方向に移動し続ける
Obstacle Avoidance(障害物回避) 障害物を避けながら進む

参考になりそうな記事(あとで読む)

【Godot】AStar2Dを使用した経路探索の実装方法

Search by Article Tags

Monthly Archive

  • 2025

Search by Exclusive Perks

Search Articles