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つ。
ドキュメントもしっかりしているので安心。
##導入
普通にアセットからインポートしてツールを起動する。
割と見やすい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を作ろうと思います。
思考としては、
- ずっと処理をさせたいのでリピートさせる
- Key入力があったか判定
- 座標を移動させる
があります。
これをBehavior Designerで実装するとこうなりました。(各NodeのInspectorをいじっています)
簡単 :)
##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 は毎チック子タスクを再評価します。