F.E.A.RのAI

少し前にGDC06で発表されたPCゲーム『F.E.A.R』のAIに関する論文を翻訳しました。
F.E.A.R』は昨年発売されたFPSで、なかなか評判のいいゲームです。
私は、何故か体験版が動かなかったので遊んでいません。
起動はするのですが、オープニングイベント終了後の(多分)プレイヤーが動けるようになった瞬間にPCが再起動するんですよ。
原因がわからないので諦めました。
そんなわけで、評判のAIはチェックできていないのですが、論文は非常に面白いです。

通常、FPSのAIには有限状態マシン(FSM)が使用されます。
FSMは任意の数の状態を様々な条件により行ったり来たりすることで処理を実行するものです。
例えば、FPSの敵AIは敵(=プレイヤー)を見つけるまでは”パトロール”という状態にあります。
ここで敵を発見すると状態は”攻撃”に変更されます。
また、この状態で弾切れになると”リロード”状態になり、ダメージが多くなると”退却”状態になります。
この方法は直感的にはわかりやすいのですが、実装は大変です。
実装は基本的にC++スクリプト言語を利用しますが、それだといじれるのはプログラマくらいしかいません。
状態遷移の条件を1つ追加するだけでもプログラマが動く必要がありますし、同じようなFSMを持ったキャラすべてに同じ条件を組み込むとなると一苦労です。
そもそも同じ兵士というキャラでも持っている武器が違えば行動は変わってきます。
それらをどうにかしようとすると条件分岐が山のようになってわけがわからなくなること請け合いです。
F.E.A.R』でもFSMを使っていますが、状態は3つだけです。Goto、Animate、UseSmartObjectの3つ。
決められた位置に移動するのがGoto、アニメーションを発行するのがAnimate、マップ中にあるオブジェクトによってアニメーションが発行されるのがUseSmartObjectになります。
この状態だけでAIの振る舞いが実行できるのかというと、それなりのトリックで出来るようです。
Gotoは問題ないでしょう。
Animateはアニメーションデータに追加データとしてその行動によるワールドの変化を持っています。
例えば、側転のアニメーションをすると横にプレイヤーが移動し、銃を撃つアニメーションをすると銃から弾が飛び出ます。
つまり、アニメーションを発行するだけでそれに応じた変化が起こるというわけです。
UseSmartObjectはこのAnimateをAI側からではなくオブジェクト側から行うようなものです。
例えば、AIが箱の陰に隠れようとすると、箱がAIに対して、側転をしなさい、と命令します。
するとAIは側転をして箱の陰に飛び込みます。

もちろんこれだけではAIは何も出来ません。どこに移動するか、どんなアニメを発行するかはどうやって決めるのか?
それがこのシステムの肝であるプランニング・システムです。
各AIは複数の目標と動作を持ちます。目標はノード、動作はノードとノードを繋げるパスのようなものと考えてください。
ある目標を達成したい場合、そこの繋がる一連の目標を次々に達成します。
ある目標からある目標へ遷移するには動作を実行します。
例えば敵を倒すという目標のためには、武器の射程まで近づき、武器を発射しなければなりません。
最初の目標は武器の射程まで近づくことです。このためには歩くとか走るとかいった動作を実行します。
次に武器を発射するという動作で敵に攻撃を加えます。
この目標と動作の繋がりは非常に複雑になっていますが、A*アルゴリズムを用いれば最短ルートを検索することが出来ます。
これがプランニング・システムらしいです。
この方法を用いると、動的に問題解決策を立案できますし、それにより、極めて人間っぽい動きになる…らしいです。
F.E.A.R』自体を遊んでないので、どの程度までそれっぽいのかわからないのですがね。

ただ、移動する場所とかは動作の中に含めることは出来そうにないし、目標の更新はどの段階で行うかというのも論文には詳しく書いていません。
論文の方には実装のヒントがあまりないように見えます。書かれてるコードはほとんどイメージみたいなもんだし。
面白い手法だとは思うのですが、簡単なものでも実際に動かして見ないとなんともいえない部分ではあります。
簡単なものだと人間っぽいのかもわかりそうにないですが。
でも、試してみたい技術ではありますね。