Page 1 of 1

アクション実行終了後のServiceやDecoratorの実行順について

Posted: 2019/01/15 16:08
by kato
Unity 5.6.3p3
Arbor 3.4.2

添付のようなビヘイビアツリーを作成しました。
前進しつづけ、崖か壁にぶつかると折り返すような処理を意図しています。

このとき、主要なメソッドの実行順が以下のようになります。
FrameCount=2~40の挙動は理解できます。ツリーを優先度順に辿るとこのような順番になるかと思います。
FrameCount=41において崖判定(IsOnEdge)が真になり、折り返すアクション(GazeBackward)を
実行したものの無限ループに陥りました。

アクション(GazeBackward)内でFinishExecute(true)を実行しているにもかかわらず
ツリー上部へ戻ってServiceが実行されることなく、再度CalculatorCheckが実行されてしまうのは仕様でしょうか?
これによって無限ループが生じていると思われますが、想定する運用と異なるのでしょうか?
(Serviceでパラメータを更新し、Decoratorでそれをもとに判断する)

-----------------------------------------------
FrameCount,ClassName,MethodName
1,CalculatorCheck,OnConditionCheck
1,CalculatorCheck,OnConditionCheck
1,CalculatorCheck,OnConditionCheck //Decoratorが複数回呼ばれ、Serviceは呼ばれない
1,MoveForward,OnExecute
2,EdgeSensor,OnUpdate
2,WallSensor,OnUpdate
2,CalculatorCheck,OnConditionCheck
2,MoveForward,OnExecute
(繰り返しのため中略)
40,EdgeSensor,OnUpdate
40,WallSensor,OnUpdate
40,CalculatorCheck,OnConditionCheck
40,MoveForward,OnExecute
41,EdgeSensor,OnUpdate //ここで崖判定が真になった
41,WallSensor,OnUpdate
41,CalculatorCheck,OnConditionCheck
41,CalculatorCheck,OnConditionCheck //なぜか2回呼ばれる
41,GazeBackward,OnExecute
41,CalculatorCheck,OnConditionCheck //Serviceに戻らず、Decoratorが呼ばれる(今回の質問)
41,CalculatorCheck,OnConditionCheck
41,GazeBackward,OnExecute
(以下、無限ループしてしまう)
-----------------------------------------------

以上、よろしくお願いいたします。
Image

Re: アクション実行終了後のServiceやDecoratorの実行順について

Posted: 2019/01/16 00:40
by caitsithware
BehaviourTreeのノードの実行順についてですね。
kato wrote: 2019/01/15 16:08 アクション(GazeBackward)内でFinishExecute(true)を実行しているにもかかわらず
ツリー上部へ戻ってServiceが実行されることなく、再度CalculatorCheckが実行されてしまうのは仕様でしょうか?
これによって無限ループが生じていると思われますが、想定する運用と異なるのでしょうか?
(Serviceでパラメータを更新し、Decoratorでそれをもとに判断する)
最初に、自作されたスクリプトの内容がこちらで把握できなく動作確認可能でないため、あくまで頂いた情報からの想定によるものとご了承ください。

まずPatrolノードはSelectorですので、「成功を返すと上位ノードに返る」仕様となっております。
つまり、以下のような流れで再度Gaze Backwardノードが実行されるようになります。
  • GazeBackwardでFinishExecute(true)
  • Selectorの子ノードが成功したため、そのまま上位ノードに返す。
  • ルートノードに到達したため、BehaviourTreeが終了。
  • BehaviourTreeの「Restart On Finish」の設定に従って再開。
  • Patrolノードがアクティブになる。(アクティブになっただけではService.OnUpdateは呼ばれない。OnStartは呼ばれる)
  • 優先度に従い、Gaze Backwardノードが実行可能かDecoratorをチェック。
  • パラメータが変更されていないのでtrueが渡されDecoratorが成功。Gaze Backwardノードがアクティブになる。
  • GazeBackwardを実行、最初に戻る。(アクティブ化直後のService.OnUpdadeは呼ばれない)
ここで問題となるのが「Service.OnUpdateはいつ呼ばれるのか」ですが、毎フレーム(アクティブ化直後のノードの場合は次のフレーム)の最初に呼ばれる仕様となっています。
1フレーム内に何度もServiceを呼ぶ必要がないケースが多く、またルートからアクティブノードへ辿ったすべてのServiceが呼ばれるため、処理負荷のことも考慮に入れた仕様です。
(今回の件もありますので、今後、よりわかりやすい仕様に変更したいと思います)

現状、もしアクティブになった瞬間も処理したい場合は、Service.OnStartでも同様の処理を行うようにしてください。

もし解釈に間違いがあり改善できそうになかったら申し訳ありません。
動作確認可能な最小限プロジェクトがありましたら、そちらも頂けるとより詳しいサポートもできますのでご検討ください。

Re: アクション実行終了後のServiceやDecoratorの実行順について

Posted: 2019/01/16 12:35
by kato
早速のご返信ありがとうございます。
FinishExecute後の実行順の仕様については理解いたしました。
ただ、Service.OnStartにてOnUpdateと同様の更新処理を記述しても解決しませんでした。
caitsithware wrote: 2019/01/16 00:40
  • Patrolノードがアクティブになる。(アクティブになっただけではService.OnUpdateは呼ばれない。OnStartは呼ばれる)
とありますが、Service.OnStartも呼ばれていないように見えました。

動作確認用プロジェクトを作成しましたので、お手数ですがご確認いただけないでしょうか?

[管理人追記] プロジェクト内にArbor本体がそのまま含まれていたためURLを削除しました。Dropboxの方も削除お願いします。
もし今後動作確認用プロジェクトを共有する際はArborなどの再配布不可のアセットは含めないようにお願いいたします。

Re: アクション実行終了後のServiceやDecoratorの実行順について

Posted: 2019/01/16 14:08
by caitsithware
確認用プロジェクトありがとうございます。
kato wrote: 2019/01/16 12:35 Service.OnStartも呼ばれていないように見えました。
確認してみたところ、確かにFinishExecute(true)後にService.OnStartが呼ばれていないのを確認できました。
想定した動作と異なっているため不具合として修正いたします。

修正版公開までの間、以下の方法で暫定対処をしてください。

暫定対処方法
  • Assets/Plugins/Arbor/Internal/Scripts/BehaviourTree/BehaviourTreeInternal.csをコードエディタで開く。
  • 284行目のelse if文を以下のように変更する。

    Code: Select all

    else if (!revaluationNode.isActive && revaluationNode.HasAbortFlags(AbortFlags.LowerPriority) && revaluationNode.priority < _CurrentNode.priority)
    
ご不便おかけして申し訳ございませんがよろしくお願いいたします。

Re: アクション実行終了後のServiceやDecoratorの実行順について

Posted: 2019/01/16 14:41
by kato
早速のご対応ありがとうございます。
確認用プロジェクトにArbor本体を含めてしまい申し訳ありませんでした。Dropboxの方も削除いたしました。

暫定対処にて期待通りの動作を確認できました。ありがとうございます。