[スクリプトライブラリ] Baz 移動エージェントの動作

BazNavAgentMovement

GameObject向けのパスファインディングAI移動。Godotの組み込みNavigationAgent2Dを使用しており、敵が壁にぶつかるのではなく、壁を迂回して経路を計算します。6つの動作モード、1つのノード、手動の状態管理コード不要。

ダウンロード:
v1.2 (AGM 2.0.0+):
baz_nav_agent_movement.gd (72.3 KB)

  • 実行中に速度変化を追従します。 以前のスクリプトは敵が動き始めた際に速度を一度だけ読み取っていましたが、現在は毎フレームオブジェクトの移動速度変数(MoveAndJumpSettingsにフォールバック)から読み取るようになり、アクションやスクリプトで変更した値がすぐに反映されます。
  • 加速時のイージングが改善されました。 加速度を有効にすると、急激な切り替えではなく、設定された加速度と減速度に基づいて新しい速度へとスムーズに移行します。
  • 状態の「Horizontal Speed Multiplier」は読み取られません。 代わりに移動速度変数を変更してください。

v1.1 (AGM 2.0.0+):
baz_nav_agent_movement.gd (70.5 KB)

  • AGMaker 2.0で進行方向に合わせて向きが変わります。 バージョン2.0では、スクリプト由来の移動に対してMovementの向きの追従が停止し、敵はデフォルトの向き(サイドビューの場合は常に右向き)のまま固定されていました。このスクリプトではオブジェクト自体を回転させるようになりました。
  • セットアップの変更は不要です。 Movementの設定にあるAnimation Facing Directionを「左」に設定したまま使用でき、パトロール待機中など停止している際も最後の向きを保持します。
  • アップグレードはファイルの入れ替えだけです。 baz_nav_agent_movement.gd をこの新しいバージョンに置き換えてください。既存のノードやビジュアルスクリプトはそのまま維持されます。

v1.0 (Pre AGM 2.0.0):
baz_nav_agent_movement.gd (68.4 KB)

機能概要

NavigationAgent2Dを使用して、敵をターゲットまでパスファインディングします。

  • Patrol(巡回) — ウェイポイント間をLoopまたはPing-Pong順で移動
  • Chase(追跡) — オブジェクト、グループ、または名前付きノードに向かって経路を計算
  • Flee(逃走) — プロブ方向を用いて脅威から遠ざかるように経路を計算
  • Random Walk(ランダムウォーク) — 開始位置を中心とした半径内で彷徨う
  • Set Direction(方向指定) — 一定の角度で移動し、障害物を迂回する
  • Move To Point(地点へ移動) — 座標、オブジェクト、グループ、または名前付きノードへの単発移動

ビジュアルスクリプトの状態から1回の呼び出しでゲーム中に動作モードを切り替えることができます。速度、加速度、減速度はエンティティの既存のMoveAndJumpSettingsから読み取られます。

GameObjectのナビゲーションノードのセットアップ

  1. 敵のGameObject(またはArea2DGameObject)シーンを開きます。Node2D を子として追加し、baz_nav_agent_movement.gd をアタッチします。

  2. 敵のルートノードの下にBazNavAgentMovementと兄弟関係となる NavigationAgent2D を追加します。初期設定のままで問題ありません。

  3. BazNavAgentMovementノードを選択し、インスペクタドロップダウンから Behavior Mode(動作モード) を選択します。インスペクタには選択したモードに関連するフィールドのみが表示されます。フィールド上にカーソルを合わせるとツールチップが表示されます。

Behavior Mode 機能
Patrol ウェイポイントリストをLoopまたはPing-Pong順で循環
Chase 最も近い有効なターゲットへ経路を計算
Flee 最も近い脅威から遠ざかるように経路を計算
Random Walk 開始位置の半径内からランダムな目的地を選択
Set Direction 一定の角度で移動し、障害物を迂回
Move To Point 座標、ノード、またはグループメンバーへの単発移動

ビジュアルスクリプトでのBazNavAgentMovementの使用法

敵のビジュアルスクリプトでAI状態を選択し、InvokeScript アクションを追加します:

  • Target Node: BazNavAgentMovement
  • Target Method: apply_movement
  • Invoke Timing: OnStateUpdate

これだけでランタイムの配線は完了です。apply_movement() は初回呼び出し時に自動初期化され、物理ティックごとに選択された動作を実行します。

GameSceneのNavigationRegion2DおよびNavigationPolygonのセットアップ

  1. 敵が存在するゲームシーンを開きます。NavigationRegion2D を追加し、NavigationPolygonリソースを割り当てて、歩行可能な領域を描画します。

  2. 衝突としてカウントしたいTileMapLayerやStaticBody2DをNavigationRegion2Dの子として配置し、エディタツールバーで Bake NavigationPolygon を押します。ベイクされたナビメッシュがないと、敵は移動しません。

  1. コーナー周辺により広い半径で経路を作成する必要がある場合は、NavigationPolygonリソースの Radius プロパティを調整できます。ただし、再ベイクする必要があります!

アクション

メソッド 呼び出すタイミング
apply_movement() アクティブなAI状態のすべての物理ティック(OnStateUpdate)。基本使用に必須。
reset_movement() 移動を停止し、次のapply_movement()呼び出し時に再初期化します。明示的なリセットが必要な場合にのみ使用します。apply_movement()が呼び出されなくなれば、移動は自動的に停止するためです。
switch_to_patrol() パトロール状態のOnStateEnter。ウェイポイント0からサイクルを再開します。
switch_to_chase() 追跡状態のOnStateEnter。最も近い有効なターゲットを取得します。
switch_to_flee() 逃走状態のOnStateEnter。最も近い脅威を取得します。
switch_to_random_walk() 彷徨い状態のOnStateEnter。
switch_to_set_direction() 固定方向状態のOnStateEnter。
switch_to_move_to_point() 単発移動状態のOnStateEnter。構成されたソースから目的地を固定します。
return_to_start() スポーン位置へ経路を計算して戻ります。
return_to_nearest_patrol() 最も近いウェイポイントへ経路を計算し、そこから巡回を再開します。

条件

ビジュアルスクリプトの遷移条件スロット(ScriptConditionEvaluator)で使用します:

メソッド Trueになる条件
is_at_destination() エンティティが現在のターゲットに到達した場合
is_moving() エンティティの速度が0でない場合
has_completed_patrol() 完全なLoopまたはPing-Pongサイクルが終了した場合
is_at_start() エンティティがスポーン位置に戻った場合(8px以内)
is_returning() return_to_startまたはreturn_to_nearest_patrolの移動処理中である場合
is_patrol_paused() 巡回がアクティブで、エンティティがウェイポイントで待機している場合
is_patrol_at_last_waypoint() 巡回がアクティブで、エンティティが最終ウェイポイントにいる、またはそこへ向かっている場合
is_chase_has_target() 追跡がアクティブで、有効なターゲットがロックされている場合

ヒント

  • まずナビメッシュをベイクしてください。 NavigationRegion2Dが見つからないかベイクされていないことが、何も動かない最も一般的な原因です。エディタの [Debug] > [Visible Navigation] を使用して、メッシュが想定通りに表示されていることを確認してください。
  • 速度はMoveAndJumpSettingsから取得します。 加速度が選択されている場合でも、それに応じて追随します。
  • Debug Enabled をオンにすると、初期化、ターゲット更新、モード切替、到着イベントなどがOutputに出力されます。リリースビルド時はオフにしてください。
  • ゲーム中のモード切替で速度はリセットされません。 加速度/減速度のランプ処理は切替間で継続されます。完全に停止させたい場合は、最初にreset_movement()を呼び出してください。
  • Set Directionは「ニンジンを使った道付け」のようなパスファインディングを行います。 ターゲットを前方128px先に投影してそこに経路を計算するため、右方向に進む敵でも壁を迂回し続け、永久に進行方向から逸脱することはありません。
  • エンティティあたり1ノードです。 同じエンティティに2つのBazNavAgentMovementノードがあると、毎フレーム速度を奪い合います。
「いいね!」 6

まさに必要なものですが、うまくいかずにいます。完全なデモ例を示していただけますか?大変ありがとうございます!

フォーラムへようこそ、@xinyn さん!

順調に進めば、今週中にその使い方の動画チュートリアルを作成する予定です。それまでにおかしいところや、うまく動かない部分を共有していただければ、お手伝いできるかもしれませんよ?

スクリプトの使い方とナビゲーション領域の設定方法(このスレッドの最上部にあります)に関する動画を制作しました。お役に立てれば幸いです!

この動画、すごく役立ちました!今ではゾンビも設定通りに動くようになり、本当に感謝しています!もし今後何か問題があれば、また報告に来ます。重ねてお礼申し上げます!

「いいね!」 1

また別の問題に遭遇しました:ゾンビは設定通りに移動・巡回、あるいは追跡できるようになりましたが、その過程でゾンビは常に同じ方向を向いたままになり、移動方向に合わせて向きが変わらなくなってしまいました :sweat_smile:

多くの試行錯誤をしましたが、この問題は解決できませんでした…

私が思いつく唯一の原因は以下の通りです:

  1. アニメーションが複数の方向に対して設定されていない
  2. 移動先のステートが「Facing Type」として「Movement」を使用していない

これらを試してもまだ動作しない場合、プロジェクトを zip ファイルにまとめて pgmmv-support@gotchagotcha.jp まで送信してください。なぜこのようなことが起こっているのか調査いたします。

返信ありがとうございます。上記で言及された理由1および2については確認しましたが、問題なさそうです。これらの設定が原因ではないと思われます。

デモ動画「Navigation Agent Movement - Action Game Maker Godot」でも同様の問題が発生していることに気づきました。ゾンビは設定通りに移動しますが、移動中は常に下方向を向いており、移動方向を向いていません。

ゾンビのアニメーションは、私の方で適当に設定してしまいました。アイドルのアニメーションは下方向の1方向しかないので、その状態でアイドルアニメーションを使用すると、キャラクターは下を向いたままになります。


Baz さん、ありがとうございます。私の問題は解決しました。根気強くお手伝いいただき、本当に感謝しています~

「いいね!」 1

こんにちは。スクリプトをバージョン2.0.4でテストされたかどうかはわかりませんが、前述の問題に遭遇しています。アニメーションは正しく割り当ててあり、チュートリアルもフォローしましたが、敵が移動する際に右方向しか向かないという状態です。これは横スクロールゲームです。
エンジンの標準的な移動アクションを使用するとキャラクターの向きは変わりますが、スクリプトを使用した際にはその変更が発生しません。

できる限り早く確認します。お知らせいただきありがとうございます!

いいニュースです、これは 2.0 の変更点でした。2.0 では、キャラクターの向いている方向はスクリプト由来の移動に従わなくなったため、敵は歩行方向に関係なくデフォルトの向きを維持し続けました。

最初の投稿を v1.1 に更新しました。スクリプトが敵を移動方向に向けてくれるようになったので、アニメーションの向き設定は「移動」に任せておくことができます。baz_nav_agent_movement.gd を新しいものに差し替えるだけで、セットアップの他の部分は変更する必要はありません。

2.0.4 でサイドビュープロジェクトにてテストしましたが、両方向への向き転換が正常に動作することを確認しました。まだ問題が発生する場合はお知らせください。

「いいね!」 2

一つだけ:スクリプト実行中にオブジェクトの速度を変更することはできません。アクション内で変更する場合でも、コマンド経由で変更する場合でも同様です。

v1.2をアップロードして修正しました。スクリプトは敵が動き始めた際に速度を1回しか読み込んでいなかったため、それ以降の変更は無視されていました。今ではオブジェクトの移動速度変数から毎フレーム速度を読み込むようになったので、実行中にそれらを変更しても反映されるようになりました。

まだ対応していないのは、ステート設定内の「水平速度倍率」のみです。そのため、代わりに移動速度変数を変更することをお勧めします。