What does UE4 use instead of “Parallel” nodes?
There are three types of nodes which provide the functionality that would normally come from Parallel nodes:
“Simple Parallel” nodes
Simple Parallel nodes allow only two children: one which must be a single task node (with optional decorators), and the other of which can be a complete subtree.
You can think of the Simple Parallel node as “While doing A, do B as well.” For example, “While attacking the enemy, move toward the enemy.” Basically, A is a primary task, and B is a secondary or filler task while waiting for A to complete.
While there are some options as to how to handle the secondary “meanwhile” task (Task B), the node is relatively simple in concept compared to traditional Parallel nodes. Nonetheless, it supports much of the most common usage of Parallel nodes.
Simple Parallel nodes allow easy usage of some of our event-driven optimizations. Full Parallel nodes would be much more complex to optimize.
(I’ll add a screenshot of this ASAP. Sorry for the lack of fun images.)
“Services”
Services are special nodes associated with any composite node (Selector, Sequence, or Simple Parallel), which can register for callbacks every X seconds and perform updates of various sorts that need to occur periodically.
For example, a service can be used to determine which enemy is the best choice for the AI pawn to pursue while the pawn continues to act normally in its behavior tree toward its current enemy.
Services are active only as long as execution remains in the subtree rooted at the composite node with which the service is associated.
(I’ll be adding a screenshot here ASAP. Also, there will be more detailed information in a separate document about Services.)
Decorator “Observer Aborts” property
One common usage case for standard Parallel nodes is to constantly check conditions so that a task can abort if the conditions it requires becomes false. For example, if you have a cat that performs a sequence “Shake Rear End”, “Pounce”, you may want to give up immediately if the mouse escapes into its mouse hole. With “Parallel” nodes, you’d have a child that checks if the mouse can be pounced on, and then another child that’s the sequence to perform. Since our Behavior Trees are event-driven, we instead handle this by having our conditional decorators “observe” their values and abort when necessary. (In this example, you’d just have the “Mouse Can Be Pounced On?” decorator on the sequence itself, with “Observer Aborts” set to “Self”. )
(For more information, I’ll link to the “Observer Aborts” explanation documentation ASAP.)