simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:ビヘイビアツリーなどのAIアセットと、自作

今のところ、ゲームAIを実装するなら、複雑になってもロジックの可視性が高いビヘイビアツリー(Behaviour Tree)やステートマシン(FSM)を使って実装を管理していくのか良いとされています。
なぜなら、AIの振る舞いをデザインする人間はコードを書きたくない(デザインだけに集中したい)場合が多いからです。

さっそく Behavior Designer を購入してチュートリアルビデオを半日ほど眺めてみました。
Behavior Designer と親和性の高い FSM として、Playmaker アセットがあることを知りました。
また、ビジュアルスクリプティングできる uScript Professional とも相性が良いことがわかりました。

ここで気付いたことに、これらのアセットで作成されたスクリプトは Unity に依存したコードとなるということでした。
もし完全に Unity 非依存でビヘイビアツリーの挙動がスクリプトで実現できたなら素晴らしかったのですが…残念ながらそうはいきません。

今回デザインするゲームはビューとは完全に独立したモデル領域でAIが動かなくてはならないため、Unity 非依存のビヘイビアツリーを実装することにします。

ビヘイビアツリーとは

ビヘイビアツリーはもともとはコードに書かれた内容を視覚化した階層グラフです。
Behavior Desinger のチュートリアル人工知能 Vol.32 No.2 (2017年03月号)を参考に、実装について要点をまとめてみました。

ビヘイビアツリーを構成しているノードは三つに分けられる、それぞれ Task, Composite, Decorator である。

・Task はツリーのリーフ要素で、1フレームに許された計算時間で条件判定やアクションを実行し、戻り値として1)Running(まだタスクが残っている), 2)Failure(条件に合わない、または失敗), 3)Success(条件一致、または成功) の三つのいずれかを返す。
・Composite は子ノードの実行を制御するノードで、シーケンスとセレクターの二種類が存在する。
シーケンスは最初の子ノードが実行完了するまで待機し、成功を返した場合に、次の子ノードを実行し、この操作を繰し、最後の子ノードが成功を返したら、シーケンスノードも成功を返す。一度でも子ノードが失敗を返したら、残りの子ノードは無視して失敗を返す。子ノードが実行中を返すようなら、シーケンスも実行中を返す。
セレクターは優先度順に子ノードの選択を行い、選択したノードを実行する。シーケンスと違う点は、どれか一つの子ノードが成功を返した時点で、まだ実行していない子ノードがあっても、成功を返す点である。
セレクターには指定した割合の確率で選択する Probability Selector や、1フレームにすべての子ノードを実行する Parallel がある。
・Decorator ノードは特質系で、子ノードを一つしかとることができない。ノードのタイプによって振る舞いはさまざまで、たとえば n 回子ノードを繰り返し実行してから成功を返したり、子ノードがn秒以上実行中だったら成功失敗に関わらず強制的に失敗を返したりする。

なるほどと感じたのは、ルートノードにて実行処理を行ったときに、すぐに成功失敗が返るケースは稀で、ほとんどは何かしらのタスクの実行中が返ってくることでした。
じゃ、ちょっくら実装してユニティちゃんが自律的に行動するシーンを確認してみたいと思います。