# ビヘイビアツリー

# ビヘイビアツリーとは？

- ビヘイビアツリーとは、挙動の優先順位や条件を明確にし制御しやすくするための木構造です。
- 例えば、敵AIを考えてみましょう。
  - 敵とプレイヤーとの距離が１０メートル以内なら近づく。
  - それ以外の時は決まった経路を移動する。
- プレイヤーに近づく挙動は決まった経路を移動する挙動に比べて優先度が高いと言えます。
- ArborのBehaviourTreeで仮組すると以下のようになります。
  (解説はのちほど)
  - 左のノードほど優先度が高く、右に行くにつれ優先度が低くなります。
  - また、Decoratorと呼ばれるスクリプトをノードに追加することで条件判定を行い、実行するノードを制御しています。

# ノードの構成要素

## ルートノード

ビヘイビアツリーを実行する際に一番最初にアクティブになるノードです。

１つの子ノードと接続できます。

## コンポジットノード

１つか複数の子ノードを持ち、どの子ノードを実行するかの制御を行います。

どのように制御するかはCompositeBehaviourスクリプトで記述されています。

また、後に説明するDecoratorスクリプトやServiceスクリプトを追加できます。

### 組み込みCompositeBehaviour

- Selector
  子ノードを左から順に実行し、子ノードが 成功を返した時点で終了 し成功を返します。
  すべての子ノードが失敗を返した場合は失敗を返します。
  左から順に成功ノードを探し、それ以降のノードは実行したくない場合に用います。
- Sequencer
  子ノードを左から順に実行し、子ノードが 失敗を返した時点で終了 し失敗を返します。
  すべての子ノードが成功を返した場合は成功を返します。
  子ノードが成功を返す限りすべて実行させたい場合に用います。

組み込みCompositeBehaviourのリファレンスはこちらを参照してください。

Arborリファレンス : 組み込みCompositeBehaviour

## アクションノード

アクションを実行するノードです。

どのようなアクションを行うかはActionBehaviourスクリプトで記述します。

また、こちらもDecoratorスクリプトやServiceスクリプトを追加できるようになっています。

組み込みActionBehaviourのリファレンスはこちらを参照してください。

Arborリファレンス : 組み込みActionBehaviour

ActionBehaviourスクリプトの作成についてはこちら。

スクリプティング : ActionBehaviour

## Decoratorスクリプト

条件判定を行って実行中ノードの中断や割り込みを行ったり、終了するタイミングで繰り返し判定などを行えるスクリプトです。

コンポジットノードやアクションノードに追加して使用します。

組み込みDecoratorのリファレンスはこちらを参照してください。

Arborリファレンス : 組み込みDecorator

Decoratorスクリプトの作成についてはこちら。

スクリプティング : Decorator

### AbortFlagsについて

中断や割り込みの対象はAbortFlagsで制御します。

- Self
  自ノードもしくはその配下のノードが実行中に条件判定を行う。
  条件判定の結果がfalseである場合は中断し、親ノードへ失敗を返す。
- LowerPriority
  自ノードよりも右にある低優先度のノードが実行中に条件判定を行う。
  条件判定の結果がtrueである場合は実行中ノードを中断し、自ノードがアクティブになる。

上記２つのフラグを組み合わせて設定できます。

また、AbortFlagsに関係なく自ノードがアクティブになる際に一度条件判定を行い、結果がfalseであればそのまま失敗として返します。

## Serviceスクリプト

Serviceスクリプトはコンポジットノードとアクションノードに追加でき、ノードがアクティブの間何かしらの処理を行えるスクリプトです。

例のBehaviourTreeでは使用していませんが、
例えばプレイヤーとの距離をParameterに格納するServiceをSelectorノードに追加するなど、補助的な処理を記述するのに適しています。

Serviceスクリプトの作成についてはこちら。

スクリプティング : Service

# 実行の解説

では、先ほどの例をもう一度見てみましょう。

- まずルートノードからはじまります。
- Selectorノードにより、子ノードの成功ノードを探して左から順に実行していきます。
- Agent Move To Transformノードでは、ParameterCheckデコレータが追加されているため、Parameterを条件に判定が行われます。
- 例として、プレイヤーとの距離はDistanceパラメータに格納しているものと仮定して作成しています。
- 仮にDistanceが15だったとすると、ParameterCheckデコレータがfalseを返すため、Agent Move To Transformノードは失敗になり、Selectorに戻ります。
- SelectorはAgent Move To Transformノードが失敗したため、次のAgent Move On Waypointノードを実行します。
- Agent Move On Waypointアクションは、TypeがCycleになっているため中断などが起きない限り繰り返し実行し続けます。
- ここで、Distanceパラメータを10以下にしてみましょう。
- Agent Move To TransformノードのParameterCheckの条件に合致するため、現ノードを中断して割り込みします。
- 再びDistanceパラメータを10より大きくすると、Agent Move To Transformノードが中断されAgent Move On Waypointノードがアクティブになるのが確認できます。

  Distanceパラメータによってアクティブノードが変わる様子

このように、右に行くほど実行優先度が低くなり、また優先度が高いノードのDecoratorにより割り込みなどができるのがわかったかと思います。

今回のような簡単な例であれば有限ステートマシンでも特に複雑にならずに組めますが、
ステートの数が多く条件が複雑化しそうな場合ではビヘイビアツリーの方が、遷移線が交差することもなく実行ノード側に条件が記述できるためメンテナンスしやすい状態遷移が組めるようになります。

# ビヘイビアツリーの使い方

詳しい使い方はこちらを参照してください

ビヘイビアツリーの使い方

# スクリプティング

各種スクリプトによるカスタマイズについてはこちらを参照してください

スクリプティング