知識0からのUnityShader勉強

知識0からのUnityShader勉強

UnityのShaderをメインとして、0から学んでいくブログです。

【Behavior Tree】Behavior TreeをUnityで実装 【1】#59

前回の成果

図形の移動を行なった。

soramamenatan.hatenablog.com


今回やること

Behavior TreeをUnityで実装していきます。
まずは、Behavior Tree自体について学んでいきます。


Behavior Treeとは

AIにおけるアルゴリズムの1つです。
Tree構造によって管理していて、各ノードはその深さに応じてTaskが実行されます。

en.wikipedia.org


Tree構造とは

親に対して複数の子を持つ構造のことです。

詳しくは、

木構造とは、データ構造の一つで、一つの要素(ノード)が複数の子要素を持ち、一つの子要素が複数の孫要素を持ち、という形で階層が深くなるほど枝分かれしていく構造のこと。
木が幹から枝、枝から葉に分岐していく様子に似ているためこのように呼ばれる。

木構造(ツリー構造)とは - IT用語辞典 e-Words:より引用

とのことです。

イメージは以下の画像のようになっています。

f:id:soramamenatan:20200622142843p:plain

4 ツリー構造:より引用

画像内の補足
名称 意味
ルート 最上位のノード
ノード 枝が分かれるところ
ブランチ 親と子を結ぶ線
リーフ 子がないノード


ステイトマシーンとの違い

Behavior Treeと似たアルゴリズムに ステイトマシーン(State Machine)というものがあります。
ステイトマシーンとの一番の差別化点は各ノードの状態の管理のしやすさにあります。
ステイトマシーンですと、状態が複数ある場合に遷移が増えすぎてしまう恐れがあります。

状態遷移が増えすぎてしまうイメージ

f:id:soramamenatan:20200622170217p:plain

NFC クラス拡張のステートマシン - Windows drivers | Microsoft Docs:より引用

Behavior Treeの場合ですと、Tree構造となっているので管理がしやすくなっています。

Behavior Tree

f:id:soramamenatan:20200622170352p:plain

[Behavior Tree] ワタシハ ビヘイビアツリー チョットデキル - LINE ENGINEERING:より引用

一概にBehavior Treeの方が優秀というわけではないので、そこは気をつけてください。
例えば、以下サイト様ですとBehavior Treeとステイトマシーンを併用して、それぞれの長所を活かしています。

thinkit.co.jp


ノードのステータス

各ノードの現在の状態になります。
以下の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


参考サイト様

engineering.linecorp.com

www.slideshare.net

edom18.hateblo.jp

www.slideshare.net

今回は以上となります。
ここまでご視聴ありがとうございました。