Posted at

Behavior DesignerでAIを組んでみる

More than 1 year has passed since last update.

Behavior Desinger

https://www.assetstore.unity3d.com/jp/#!/content/15277

Behavior Designerを使って簡単なAIを組んでみます。


概要

Behavior DesignerはBehavior Tree形式を利用してNode/GUIベースでAIが組めるアセットです。Behavior Treeの形式を理解していれば割とすんなりBehavior Designerを使えるようになるかと思います。

ゲーム再生中にAI Nodeの結果が見れたり拡張性が高かったりと割と便利なので、今後AIを作る際は使っていきたいアセットの1つ。

ドキュメントもしっかりしているので安心。


導入

普通にアセットからインポートしてツールを起動する。

スクリーンショット 2017-01-12 1.07.17.png

割と見やすいUIになっている。

UIの説明はドキュメントを参照

http://www.opsive.com/assets/BehaviorDesigner/documentation.php?id=1

設定とかは特に必要なくこのまま使える。


超簡単なAIを書いてみる。

Behavior Designerが使っているBehavior TreeというAI実装形式はTaskという処理単位でAI実装が行われます。

Taskは実行結果を必ず返します。Running(実行中),Success(成功したよ),Failure(失敗したよ)等。

Taskは4つの種類があります。

1: Action (何かを実行する。ex:攻撃アニメーションを開始する)

2: Conditional (何かを判断する。ex:体力が5以下であるか)

3: Composites (1つ、または複数のタスクを子タスクとして内包できる。内包した子タスクを指定した方法で実行する)

4: Decorator (タスクの結果を変更する。ex:失敗を返す。リピートする等)

これらのTaskを組み合わせることで任意のAIをフレキシブルに作成することが可能です。

Behavior Desginerでは基本的なTask(ex:Animatorを制御する。ボタンが押されている等)はあらかた用意されています。もちろん用意されているだけのTaskでは複雑なAIを組めません。そのためBehavior Designerでは簡単にTaskを追加しやすいように設計されており、これによってエンジニアは自由に、そして簡単に新しいTaskをいくつでも作成することができます。

新しいTaskの追加方法はこちら

http://www.opsive.com/assets/BehaviorDesigner/documentation.php?id=5

とはいえ最初なのでデフォルトで用意されているTaskだけを使ってAIを組んでいこうと思います。

とっても簡単に

"Key入力があったら" + "X座標0.1移動する"

AIを作ろうと思います。

思考としては、

1. ずっと処理をさせたいのでリピートさせる

2. Key入力があったか判定

3. 座標を移動させる

があります。

これをBehavior Designerで実装するとこうなりました。(各NodeのInspectorをいじっています)

2017-01-14 02.49.27.jpg

簡単 :)


Compositesについて

ActionやConditionalsは分かりやすいのですが、Compositesタスクがいまいちわかりにくいのでいろいろ調査してみます。

Composites(コンポジット)の意味は”複合”とのこと。自分の子タスクを複合していろいろできるよってことでしょうか。

デフォルトで用意されているCompositesタスクの種類

- Sequence

- Selector

- Parallel

- Parallel Selector

- Priority Selector

- Random Selector

- Random Sequence

- Selector Evaluator

- Utility Selector


Sequence

SequenceタスクはAndオペレーションと似ています。いくつでも子タスクをセットでき、左から順番に子タスクを実行していきます。子タスクが一つでもFailureを返した場合は、子タスク実行をやめて、すぐさま自身もFailureを返して自身のタスクも終了させます。すべての子タスクがSuccessを返した場合のみ自分もSuccessを返して終了します。


Selector

SelectorタスクはOrオペレーションと似ています。いくつでも子タスクをセットでき、左から順番に子タスクを実行していきます。子タスクが一つでもSuccessを返した場合は自身もすぐさまSuccessを返して終了します。子タスクがFailureを返した場合はすぐさま次の子タスクを実行し、すべての子タスクがFailureを返した場合は、自身もFailureを返して終了します。

子タスクがSuccessを返した場合は残りの子タスクが実行されないことに注意ですね。


Parallel(パラレル)

パラレルの意味は平行です。パラレルワールドのパラレルですね。

ParallelタスクはSequenceタスクに似ています。子タスクがFailureを返すまで子タスクを実行させます。

Sequenceとの違いは、子タスクをいっぺんに実行させる点です。子タスクが一つでもFailureを返した場合は、すべての子タスクを終了させ、自身もFailureを返して終了します。


Parallel Selector

このタスクはSelectorに似ています。いっぺんに子タスクを実行し、一つでもSuccessが返ってきた場合は、すぐさまほかの子タスクを終了させ、自身もSuccessを返します。

すべての子タスクがFailureを返した場合は自身もFailureを返します。


Priority Selector

このタスクはSelectorに似ています。左から順に子タスクを実行するのではなく、各子タスクのPriorityをチェックし、Priorityの高い子タスクから実行していきます。一つでも子タスクがSuccessを返せば自身もSuccessを返して終了します。


Random Selector

このタスクはSelectorに似ています。子タスク実行時にSuccessが返れば自身もSuccessを返します。違いは、子タスクの実行順序をランダムで決めることです。シードを指定してランダムさせることも可能です。


Random Sequence

Random SelectorのSequence版です。


Selector Evaluator

Selector Evaluatorはすべての子タスクを毎チック時に再評価するタスクです。Runningステートを返す子タスクの内、Priorityがもっとも低い子タスクから実行されます。毎チック時にこの処理が行われます。もしPriorityの高い子タスクがRunningを返してきて、次のフレームにPriorityの低い子タスクをRunしようとした場合は、Priorityの高い子タスクに割り込み処理を入れます。Selector Evaluatorは一番最初に実行が終わった子タスクの評価がSuccessだった場合のみ自身もSuccessを返します。そうでない場合は、Priorityの高い子タスクたちを実行し続けます。このタスクはconditional abortの模倣です。また、子タスクはConditionalである必要はありません。Actionでも可能です。


Utility Selector

Utility Selectorは子タスクを utility theory aiを使って評価するタスクです。子タスクはUtility値をいつでも設定することができます。一番高いUtility値を持つ子タスクが実行され、その際、既存のRunning中だった子タスクは中断されます。Utility Selector は毎チック子タスクを再評価します。