Questions on fundamentals of Unity Behaviour Trees (Behaviour package 1.0.5)

Hi! I’m new to this package and to BTs in general. I’m implementing AI behaviour in my game, starting some with basic actions: “Patrol” (if a set of waypoints is provided), “Wander” (if no waypoints), “Detect” (look for a collider with tag in a given range) and “Flee” (if target spotted, run to a point a given distance in the direction away from the target.

I’m struggling a bit with some of the fundamentals of how Behaviour trees work:

  1. Is the whole tree “traversed” and evaluated each frame? I’m a bit stuck in an FSM mindset, and I can see BTs behave very differently.
  2. Actions have OnStart and OnUpdate - does the OnStart() event get triggered every frame / every time the BT is “executed”?
  3. When is the OnUpdate() event triggered and what’s the recommended pattern for when to use OnStart(), OnUpdate(), and OnEnd()?
  4. Is it “allowed” for an Action to update the Blackboard? For example, my “Detect” action might find a valid target, and I want that reflected in a Blackboard variable.
  5. If this is an appropriate thing to do, how do I reference the Blackboard from my Action script, in order to “set” a variable value? Does the action description pass a reference to the variable?

The logic I’m looking to implement in my simple tree is:

  • Character starts either Patrolling or Wandering, depending on whether a set of waypoints is provided to the “Patrol” action.
  • The Character is on the lookout for a collider with a tag defined in the “Detect” action. If it spots such a target, it’s set in the “Target” transform Blackboard variable.
  • If a Target is set in the blackboard, the character stops patrolling or wandering and flees away from the target, using a distance/range defined in the “Flee” action, deriving a direction using the target and AI transforms to travel “away” from the target.
  • When the character reaches the flee destination, it starts to Wander or Patrol again.

This is what I currently have:


I do worry that I’m not following the correct principles, and am trying to make a Finite State Machine!

Does this graph look “right”?

Many thanks in advance for any help you can give - apologies, I realise this is a probably a very basic “what is a Behaviour Tree” type question, and I’m asking for a lot of info in one post!

Hi @mroshaw

Thank you for reaching out and sharing your experience.

Even though the tool is a Behavior Tree as it core, it draws from other approach strength such as FSM to mitigate some of it’s weakness. BT as great for running behaviors in parallel and executing sequence of action while not being very efficient with state transition and reaction. FSM is almost the opposite, being excellent at handling transition but not very good creating sequence of action.

You can try to design your behavior using only BT approach, but in general, and especially for such a predefined set of state, I would recommend using FSM for decision making and BT for their implementation.

Usually with BT, the tree is traversed from the root node, evaluating only active branches until a task is running or successfully/unsuccessfully completed. Talking about frame is a bit misleading as some task or evaluation can last several frames. Once the tree reach and complete the end of a branch it will restart from the root node. There are a few nodes that can “hijack” this flow, often Modifiers such as Repeat, Restart or Abort nodes. I would recommend you to check the official documentation for more details.

  • OnStart get called everytime a node is start being evaluated.
  • OnUpdate is called on every Update (if using Behavior(Graph)Agent) as long as the node is Running (meaning that if a node OnStart returns Success/Failure/Waiting, OnUpdate will not be called.
  • OnEnd is called just after a node evaluation returns Success or Failure.

Yes absolutely. We provide several built-in nodes that do exactly that to assigned GameObject to a linked blackboard variable. You can inspect nodes such as Find With Tag, Wait For Trigger/Collision, Instantiate Object or PlayParticleSystem.

You just need to have a serialized reference BlackboardVariable<T> in your node. If it is not linked to the story it is going to be displayed in the node inspector. You can then assigned a Blackboard Variable to the field.

You graph looks like a proper BT implementation good. I don’t have the details of your nodes but if your Patrol/Wander nodes are step-based (not putting the node in Running state and being executed on Update), then I don’t see anything wrong.
However, if you Patrol/Wander nodes are running on Update, you might want to use a RunInParallel instead of the Sequence along with a Repeat node above your Detector Check to make sure your sensor is evaluated in parallel to the patrol/wander.

I would recommend you to have a look at the Demo we published as it showcases a similar use case as you are trying to achieve.

Hope this help!
Thanks for your patience :slightly_smiling_face:

Wow, thank you so much for a brilliant response!

And you’ve hit the nail on the head with a problem I’m having with my Movement Actions - they are basically “blocking” by waiting for the NavMeshAgent to arrive in OnUpdate(). I’ll look into the ‘Parallel’ node that you’ve mentioned there. This actually answers a specific question that I raised on this very topic: How to run Sequence with a "long running" Action in Behaviour 1.0.5.

As with pretty much everything, there are so many ways to achieve a goal, I find it overwhelming. While I do sometimes like to “just get it done”, a bit part of me wants to/enjoys learning about “good practice” and established patterns - really, I just don’t want to re-invent the wheel or make things complicated for myself in the long run. It’s really reassuring to get your feedback on what I’ve learned so far.

Keep up the great work with this awesome package, and thank you again for taking the time to respond to my questions in such depth. I genuinely appreciate it!