経路探索・意思決定

GOAP

Goal-Oriented Action Planning

目標と行動の前提から手順を計画する。

8 / 10

インタラクティブデモ

デモを準備しています…

GOAP

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

キャラクターに「目標」と「行動の一覧(前提と効果とコスト)」だけを与え、目標を達成する行動の手順を自動で組み立てさせる方法です。「火を起こすには薪が要る」「薪を得るには、斧で木を切るか、店で買うか、枝を集める」といった関係を行動ごとに書いておけば、手順はA* が見つけます。斧がなくなれば別の手順を、お金があれば買う手順を、その場で選び直します。『F.E.A.R.』(2005)の敵兵が、状況に応じて自然に連携するように見えたことで広く知られました。

ゲームでの使いどころ

  • 戦術的な敵:「敵を倒す」を目標に、武器を拾う・弾を補充する・物陰に移る・回り込む、などを組み合わせる。
  • 生活する NPC:「空腹を満たす」「眠る」などの欲求を目標にし、料理する・買う・狩るといった手段を状況に応じて選ぶ(シミュレーションゲーム)。
  • サバイバル・クラフト:道具や素材の有無によって、作る順番が変わる手順。
  • デザイナーの負担を減らす:行動を 1 つ足すだけで、それを使う新しい手順が自動で生まれる。

しくみ

世界の状態を「事実」の集まりで表します(斧を持っている、薪を持っている、火がある…)。行動は次の 3 つを持ちます。

  • 前提:実行できる条件(「木を切る」には斧を持っていること)。
  • 効果:実行後に変わる事実(「木を切る」と薪を持つ)。
  • コスト:手間や時間(移動距離を足すことも多い)。

計画は、状態をノード、行動を辺とするグラフの上で、今の状態から目標を満たす状態までの最小コストの道を探す問題です。前から探す(今の状態に使える行動を足していく)方法と、後ろから探す(目標を満たすには何が要るか、とさかのぼる)方法があります。見積もり hh には「満たしていない目標の事実の数」がよく使われます。

実行と計画し直し:見つかった手順を 1 つずつ実行し、次の行動の前提が崩れたら(斧を誰かに取られた、店が閉まった)、今の状態から計画し直します。

実装のポイント

  • 状態をビットで持つ:事実を整数のビットで表すと、前提の判定((state & need) === need)も効果の適用も速く、探索の状態の比較も簡単です。
  • コストに移動距離を入れる:同じ「薪を得る」でも、遠くの森より近くの店を選ぶなど、場所を考えた計画になります。その場合、探索の状態には「いる場所」も含めます。
  • 計画の頻度:探索は重くなりがちなので、毎フレームではなく、目標が変わったときや前提が崩れたときだけ行います。
  • 目標の選択:どの目標を追うか(空腹か、身の安全か)は、GOAP の外で、欲求の強さなどで決めます。

つまずきやすい点

  • 探索の爆発:行動や事実が増えると、状態の数が爆発して計画が遅くなります。行動を目標ごとに絞る、深さに上限を付ける、といった工夫をします。
  • 思いがけない計画:組み合わせの自由さの裏返しで、デザイナーの意図しない手順(むだな行動をはさむ、変な順番)が選ばれることがあります。コストの調整で直すのは難しいので、前提を細かく書きます。
  • 細かな動きは苦手:GOAP が決めるのは「何をするか」の順番です。どう歩くか、どう撃つかは、有限状態機械やビヘイビアツリーで実行するのが一般的です。

デモで試すこと

  1. 村人の目標は「火がある」です。最初は斧が置き場にあるので、「斧を拾う → 木を切る → 火を起こす」が選ばれ、右下に候補とコストの比較が出ます。
  2. 「斧が置き場にある」を切ると、斧を使う手順が消え、「枝を集める」(手間が大きい)が選ばれます。実行中に切り替えると、その場で計画し直します。
  3. 「お金を持っている」を入れると、「薪を買う → 火を起こす」が候補に加わり、距離しだいで選ばれます。
  4. 「移動距離の重み」を 0 にすると、場所の遠さを無視した計画になり、大きくすると近い場所ですむ手順が選ばれやすくなります。火が消えると目標がまた満たされなくなり、次の計画が始まります。

参考資料

Red Blob Games — A* Introduction ↗

分野全体の資料で、この項目を直接扱っているとは限りません。