Behavior Tree: Controlling Tick of Decorator Nodes

I’ve been trying to understand when the Decorator Nodes “tick” and invoke their conditionals. I want the conditional to fire on some interval or event while a task on it is executing, specifically a “MoveTo” task. What I’ve observed is that the condition will only be executed before the task begins execution and not while it is in an executing state.

I created a subclass of UBTDecorator and overrode the CalculateRawConditionValue member function. I tried overriding the “TickNode” member function but couldn’t figure out how to re-evaluate the conditional from this and have it execute the abort behavior of “Self” I have configured. I could create a custom “MoveTo” task and call or invoke logic to determine if task should complete but that seems like a hack and would rather separate the logic if possible. I also tried a “Simple Parallel” node with a wait task primary to simulate a “tick” but this seems like a hack as well.

What I want to do is have the AI move to the player except if some condition is met such as the player fires back and the AI is close enough, which is controlled by my C++ decorator class shown here. Only solution I’ve found that almost works is the parallel node solution though it sometimes causes a “vibrating AI” glitch that I am still trying to track down.

image

Ok, I think I figured it out. I needed a rubber ducky :slight_smile: Instead of trying to do this tick execution with a decorator I switched “Should Move to” to a service that runs on an interval to compute the condition boolean and then check the blackboard value as a simple decorator on the task. Also changing to a selector to pick the condition I want:

Here is the section of my tree where I pick between shouting out “Hey you!”, moving to the player condition or going into a shooting sequence:

Another problem was bShouldMoveTo calculated true but the MoveTo had an allowed variance closer to the position so it would get stuck in move to but not actually move causing the hilarious shaking effect. Setting bShouldMoveTo to false within say 500cm when the MoveTo task had an acceptableRadius of 600cm prevented this from happening.

Found the gameplay debugger super helpful for visualizing the AI execution onscreen: AI Debugging | Unreal Engine Documentation

Only missing feature was an AI pawn toggle as it doesn’t always debug the AI controller that I want. Workaround is to the pause the game and select the enemy actor from the world outliner in the running game which will switch which AI is being described by the debugger.

Just to be sure I followed this all correctly, you’ve solved your issue?

@DanM I was able to achieve the result I was looking for by having the AI engage the player if they were already fired upon instead of continuing to move to a closer location. I was only able to control the tick in the behavior tree using a Service. Do you know if a decorator node can be “ticked” or forced to re-evaluate if some external condition/event changes? As I mentioned in the post, it seems it only executes right before a task as a guard condition but can’t be re-evaluated directly to abort an in-progress task that is executing.

There’s TickNode. Though I think Observer Notify on Value Change is what you’re after?

1 Like

Correct. I ended up going with “Notify on Result change” on a boolean bShouldMoveTo that was computed in a C++ UBTService since it was based on several conditions and wanted to make sure it was evaluated on a regular interval. Wondering if I am approaching things in a sensible way.

Was trying to understand when the various callback functions are invoked as the documentation is kind of vague:

  • OnNodeActivation
  • OnNodeDeactivation
  • OnNodeProcessed
  • OnBecomeRelevant
  • OnCeaseRelevant
  • TickNode

For example, I assume TickNode is not the same as onTick and is only called if the task is in an executing state and not every frame of the game. Looking through the source code of UBTDecorator_BlackboardBase to figure out the notify magic and see you can register observers on the BlackboardComponent which now makes sense.

You are correct on your assumptions (unless I’m misremembering, 90% sure though). Yeah, documentation for Behaviour Trees, other than getting started, is pretty bare bones and a bit hard to find as it’s a bit scattered around the code base. Definitely could do with an improvement.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms