【Behavior Tree】Behavior TreeをUnityで実装 【1】#59
前回の成果
図形の移動を行なった。
今回やること
Behavior TreeをUnityで実装していきます。
まずは、Behavior Tree自体について学んでいきます。
Behavior Treeとは
AIにおけるアルゴリズムの1つです。
Tree構造によって管理していて、各ノードはその深さに応じてTaskが実行されます。
Tree構造とは
親に対して複数の子を持つ構造のことです。
詳しくは、
木構造とは、データ構造の一つで、一つの要素(ノード)が複数の子要素を持ち、一つの子要素が複数の孫要素を持ち、という形で階層が深くなるほど枝分かれしていく構造のこと。
木が幹から枝、枝から葉に分岐していく様子に似ているためこのように呼ばれる。
とのことです。
イメージは以下の画像のようになっています。
4 ツリー構造:より引用
画像内の補足
名称 | 意味 |
---|---|
ルート | 最上位のノード |
ノード | 枝が分かれるところ |
ブランチ | 親と子を結ぶ線 |
リーフ | 子がないノード |
ステイトマシーンとの違い
Behavior Treeと似たアルゴリズムに
ステイトマシーン(State Machine)というものがあります。
ステイトマシーンとの一番の差別化点は各ノードの状態の管理のしやすさにあります。
ステイトマシーンですと、状態が複数ある場合に遷移が増えすぎてしまう恐れがあります。
状態遷移が増えすぎてしまうイメージ
Behavior Treeの場合ですと、Tree構造となっているので管理がしやすくなっています。
Behavior Tree
[Behavior Tree] ワタシハ ビヘイビアツリー チョットデキル - LINE ENGINEERING:より引用
一概にBehavior Treeの方が優秀というわけではないので、そこは気をつけてください。
例えば、以下サイト様ですとBehavior Treeとステイトマシーンを併用して、それぞれの長所を活かしています。
ノードのステータス
各ノードの現在の状態になります。
以下の4種類で実装しています。
ステータス名 | 状態 |
---|---|
Waiting | 待機中 |
Success | 成功 |
Failure | 失敗 |
Running | 実行中 |
ノードの初期状態はWaitingとなっており、実行結果に応じてSuccessやFailure、Runningを返します。
ノードの種類
ノードは以下の7種類あります。
- ActionNode
- ConditionNode
- DecoratorNode
- SequencerNode
- SelectorNode
- RepeaterNode
- ParallelNode
各ノードについて説明していきます。
ActionNode
実際に処理を行うノードとなります。
例えば、移動や攻撃といったものがこのノードに当てはまります。
リーフノードとなっているので、子を持つことが出来ません。
また、実行結果をそのまま親に返します。
ConditionNode
条件の判定を行うノードとなります。
例えば、HPが足りているかや敵が近くにいるかといったものが当てはまります。
このノードもリーフノードとなっているので、子を持つことが出来ません。
条件の判定の結果に応じて、結果を親に返します。
DecoratorNode
こちらも条件の判定を行うノードとなっています。
ConditionNodeと違う点は子を持つことが出来ることです。
ただし、1つしか子を持つことが出来ないので気をつけてください。
条件が通らなかったらFailureを、通ったら子のステータスを返します。
SequencerNode
子を複数個持ち、ノードを登録した順番に実行するノードです。
例えば、HPが一定以上あるなら攻撃をするといった行動をさせたい時に使用します。
子が1つでもFailureを返した場合、そこで全ての子の実行を終了させて親にFailureを返します。
子がRunningもしくはSuccessを返した場合、Runningを返します。
そして、全ての子がSuccessを返した場合のみSuccessを返します。
SelectorNode
こちらも子を複数個持ち、ノードを登録した順番に実行するノードです。
例を挙げると、HPが一定以上あるなら近距離攻撃、ないなら遠距離攻撃といった行動をさせたい時に使用します。
子が1つでもSuccessを返した場合、そこで全ての子の実行を終了させて親にSuccessを返します。
Successの子がおらず、Runningの子がいる場合Runningを返します。
そして、全ての子がFailureを返した場合のみFailureを返します。
RepeaterNode
指定された回数子ノードを実行するノードです。
例えば、複数回攻撃を行う時に使用します。
指定した回数子ノードを実行したらSuccessを返します。
そうでなければRunningを返します。
ParallelNode
子を複数個持ち、全ての子ノードを同時に実行するノードです。
例えば、移動と攻撃を同時に行う際に使用します。
必ずしもマルチスレッドである必要はありません。
子が1つでもFailureを返した場合、そこで全ての子の実行を終了させて親にFailureを返します。
子がRunningもしくはSuccessを返した場合、Runningを返します。
そして、全ての子がSuccessを返した場合のみSuccessを返します。
各ノードの説明は以上となります。
以下に表で簡単にまとめます。
ノード名 | 持つことの出来る子の数 | Successの条件 | Failureの条件 | Runningの条件 |
---|---|---|---|---|
ActionNode | 0 | 処理次第 | 処理次第 | 処理次第 |
ConditionNode | 0 | 条件を満たした時 | 条件を満たさなかった時 | 無し |
DecoratorNode | 1 | 条件を満たし、子次第 | 条件を満たさなかった時 | 条件を満たし、子次第 |
SequencerNode | 制限なし | 全ての子がSuccess | 子が1つでもFailure | 子がRunning |
SelectorNode | 制限なし | 子が1つでもSuccess | 全ての子がFailure | 子がRunning |
RepeaterNode | 制限なし | 指定回数子を実行した | 無し | 子がRunning |
ParallelNode | 制限なし | 全ての子がSuccess | 子が1つでもFailure | 子がRunning |
参考サイト様
www.slideshare.net
www.slideshare.net
今回は以上となります。
ここまでご視聴ありがとうございました。