simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity: Behavior Designer のノードの勉強

基本的なことはこちら
simplestar-tech.hatenablog.com

ビヘイビアツリーを構成しているノードは三つに分けられる、それぞれ Task, Composite, Decorator である。

・Task はツリーのリーフ要素で、1フレームに許された計算時間で条件判定やアクションを実行し、戻り値として1)Running(まだタスクが残っている), 2)Failure(条件に合わない、または失敗), 3)Success(条件一致、または成功) の三つのいずれかを返す。
・Composite は子ノードの実行を制御するノードで、シーケンスとセレクターの二種類が存在する。
シーケンスは最初の子ノードが実行完了するまで待機し、成功を返した場合に、次の子ノードを実行し、この操作を繰し、最後の子ノードが成功を返したら、シーケンスノードも成功を返す。一度でも子ノードが失敗を返したら、残りの子ノードは無視して失敗を返す。子ノードが実行中を返すようなら、シーケンスも実行中を返す。
セレクターは優先度順に子ノードの選択を行い、選択したノードを実行する。シーケンスと違う点は、どれか一つの子ノードが成功を返した時点で、まだ実行していない子ノードがあっても、成功を返す点である。
セレクターには指定した割合の確率で選択する Probability Selector や、1フレームにすべての子ノードを実行する Parallel がある。
・Decorator ノードは特質系で、子ノードを一つしかとることができない。ノードのタイプによって振る舞いはさまざまで、たとえば n 回子ノードを繰り返し実行してから成功を返したり、子ノードがn秒以上実行中だったら成功失敗に関わらず強制的に失敗を返したりする。

これから Behavior Tree を活用していくので、使い方に慣れるため、各ノードの動きを確認しながら、道具として使えるようになるため、覚えていこうと思います。

## Parallel

子タスクを一斉に並列実行し、いずれかが失敗を返したらすべての子タスクを停止して失敗を返す
実行中の子タスクが残るなら、実行中を返し
すべての子タスクが成功したとき、成功を返す
イメージとしては並列実行の And 条件 if 文って感じですかね

f:id:simplestar_tech:20210703130241p:plain
Parallel

## Parallel Complete

子タスクを一斉に並列実行し、最も早く答えを出した子タスクの答えを返す
全部成功していて、残る実行中のものがあったとしても、最初に成功を返した子タスクを見つけた時点で成功を返す
イメージとしては並列実行の Or 条件 if 文って感じですかね、False を返すのが先だと False が返るところが全然違う

f:id:simplestar_tech:20210703131331p:plain
Parallel Complete

## Parallel Selector

子タスクを一斉に並列実行し、すべて失敗となるまで待つが、いずれかが成功を返した瞬間に子タスクをすべて停止して成功を返す
イメージとしては並列実行の Or 条件 if 文って感じですね
f:id:simplestar_tech:20210703131954p:plain

## Priority Selector

float GetPriority(); を Action Task 側で実装して返す必要がある
この値が大きい順で子タスクを順番に実行して、先に成功を返したタスクが生まれたら成功を返すもの

f:id:simplestar_tech:20210703142958p:plain
Task class

## Random Selector

ランダムに子タスクの順番を決めて Selector として、成功を見つけるまで続け、成功を返す子タスクによって、続く子タスクの実行を停止して、成功を返す
イメージとしては順番実行の Or 条件 if 文って感じで、評価順がランダムというものですね

f:id:simplestar_tech:20210703143258p:plain
Random Selector

## Random Sequence

ランダムに子タスクの順番を決めて Sequence として、すべてが成功するまで続け、失敗を返す子タスクによって、中断して子タスクの実行を停止して、失敗を返す
最後の子タスクが成功したときにやっと成功を返すという
イメージとしては順番実行の And 条件 if 文って感じで、評価順がランダムというものですね

f:id:simplestar_tech:20210703150525p:plain
Random Sequence

## Selector

いずれかが成功したら成功を返し、残りの実行を中断する
イメージとしては順番実行の Or 条件 if 文って感じ

f:id:simplestar_tech:20210703150847p:plain
Selector

## Selector Evaluator

実行中を返す Action が子タスクの優先度の低いものであったなら、それより高い優先度の Action の評価をもう一度行う様子
実行中のタスクより低い子タスクの実行はせず
優先度が高いタスクは常にチェックしたいといったギミックに良いのかも たとえばプレイヤーを視認していること という条件に使って、続くアクションに追いかけるといった running ステータスを返す何かが挟まるなど
イメージとしては順番実行の Or 条件 if 文って感じだが、どういうわけかさっき調べた条件をもう一度しらべいにく
いくつもの Task のうち、最初に成功を返した Task の結果をもって成功を返す

f:id:simplestar_tech:20210703151759p:plain
Selector Evaluator

## Sequence

順次実行して、失敗が返ると即子タスクを停止して失敗を返す
イメージとしては順番実行の And 条件 if 文って感じ

f:id:simplestar_tech:20210703153116p:plain
Sequence

## Utility Selector

float GetUtility の値が大きいものを常に選んで実行する
子タスクすべてを見ていて、Utility 値が実行中に小さくなったなら、他の Utility 値が大きいタスクの実行へと移る
いずれかが成功を返したら、他のタスクを停止して成功を返す でも、いずれの子タスクも Running を返すようにする使い方がメインなのかな
Priority Selector との違いは、それまで最高Utility だったタスクが Running 中でも、他の Utility が高まったら中断するところかな

f:id:simplestar_tech:20210703153501p:plain
GetUtility
f:id:simplestar_tech:20210703154804p:plain
Utility Selector