Simple Parallel Freezing


I have a simple parallel with a wait task and a “do nothing” task. Do nothing task is only there so that it can be decorated with an inversed “IsInventory” decorator. The idea being that the moment IsInventory returns true it would bail out of the simple parallel, causing wait to abort. However, in reality, the moment by IsInventory decorator returns true the engine freezes. It seems to get stuck in the loop in UBTCompositeNode::FindChildToExecute. It does call NotifyDecoratorsOnFailedActivation inside that loop, but ChildIdx is always 1 and it never exits the loop. Is this a bug or am I misunderstanding simple parallel trees ?

here’s the pic of that subtree:


That’s a mighty over-engineered setup you got there! :slight_smile:

It’s seems you’ve encountered a bug with this exotic setup, so I’ll file a ticked to have safeguards added.

Now, when that’s out of the way, let me tell you how you set it up without shooting yourself in the foot.

Ideally you’d have a Blackboard key containing information whether IsInventoryMode is true or not. Is you had that you could get the functionality you’ve described just by putting down a wait task and decorating it with blackboard-value checking decorator configured to “abort self”.

If for some reason you don’t want to use blackboard you can implement a custom BT decorator (and you can do it even in BP!) that will be checking the condition you want. If you configure such a decorator as “abort self” the condition would be checked every frame and the underlying task will get aborted as soon as the condition is no longer true.

Let me know if you encounter issues while going this route.



yeah - initially I tried without simple parallel, but it would only kick in when wait task was done, so that’s why I went ahead and tried with simpleparallel. Maybe I was missing the “abort self” part - if that checks every frame then it should work exactly the way I want. I’ll try that out and see what happens. Thanks !

I’ve yet to get a simple parallel to work but I’ll try this when I get home and let you know if it worked. Thanks!


I just got around to doing this and I still can’t get the wait task to interrupt even though the decorator is set on it. I know that the decorator works, because after the task is done with its 5 second wait the tree will redirect to the new path that is caused by the value change from IsInventory decorator. However, even though I set the decorator to aborts self the value is not checked until AFTER Wait task is done. I also confirmed in the debugger that decorator is not entered until after the wait task is done. What can I do to get this wait task interrupted ?

Oh, and btw - to make sure we’re all on the same page. The decorator is a C++ decorator and derives straight from UBTDecorator.

Hi tardygrade,

Can you show me a screenshot of your behavior tree setup, specifically where you have the abort task located?

Hi. I actually changed the tree since the post, but here’s what it looks like now. In this particular case I want this RunBehavior BT_MoveToTarget to be interrupted once inventory is switched. The IsInventory decorator is a c++ decorator that checks the global variable (not blackboard variable) to determine if the game is in Inventory Mode

And this is what the decorator’s CalculateRawConditionValue looks like:

AMyGameMode* MyGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld()));
if (MyGameMode->GetGameplayMode() == EGameplayMode::Inventory)
return true;
return false;

It looks like your BT aborts your wait if you are in the inventory currently. At the bottom “Is Target Actor Set” is set to abort lower priority, which means it would ignore the idle afterwards.

Yeah - basically either wait or RunBehavior further down will only get aborted AFTER they are done. So for example - in case of RunBehavior (which is a subtree that just runs that moveTask), if the agent was currently running and I entered Inventory state the tree would still continue executing RunBehavior. It’s only when RunBehavior ends that this decorator fires up and shortcircuits the rest of the tree. How can I get it to fire every frame so that it can interrupt move the moment Inventory becomes true. (Right now I got this solved by restarting the entire tree when the user clicks Inventory - which is OK for this case, but sooner or later I feel I m gonna run into something similar that I will not be able to resolve this way)

Have you tried adjusting the values as well as the location of your abort nodes to see if it could be where they are placed that is causing the error to occur? Try moving your abort decorators to different nodes.