Behaviour Tree

Checked with version: 2017.3

-

Difficulty: Beginner

Note: This is a scripting-only system. You need at least basic knowledge in how scripts and C# work in Unity to understand how it works and how to use it

As the name implies, Behaviour Trees are a way to code behaviour using a tree of actions. They are used in the Game Kit to control the behaviour of AI for enemies and the boss battle sequence.

A visual example of a Behaviour Tree is shown below:

Theory

During each update of the game, the tree is "ticked", meaning it goes through each child node of the root, going further down if said node has children, etc.

Each node has associated actions, and returns one of three states to its parent:

  • Success: the node successfully finished its task.

  • Failure: the node failed the task.

  • Continue: the node didn't finish the task yet.

Returned state is used by each node parent differently.

For example:

  • Selector makes the next child active if the current one returns Failure or Success, and keeps the current one active if it returns Continue.

  • Test nodes call their child nodes and return the child state if the test is true, or return Failure without calling their child nodes if the test is false.

Game Kit Implementation

The way Behaviour Trees are used in the game kit is through script. Here is an example of a very simple behaviour tree:

First, we need to add using BTAI; at the top of the file.

Root aiRoot = BT.Root();

aiRoot.Do(

BT.If(TestVisibleTarget).Do(

BT.Call(Aim),

BT.Call(Shoot)

),

BT.Sequence().Do(

BT.Call(Walk),

BT.Wait(5.0f),

BT.Call(Turn),

BT.Wait(1.0f),

BT.Call(Turn)

)

);

aiRoot should be stored in the class as a member, because you need to call aiRoot.Tick() in the Update function so that Tree actions can be executed.

Let's walk through how the Update works in the aiRoot.Tick():

  • First, we test if the function TestVisibleTarget returns true. If it does, it goes on to execute the children, which are calling the functions Aim and Shoot

  • If the test returns false, the If node returns Failure and the root then goes to the next child. This is a Sequence, which starts by executing its first child

    • This calls the function Walk. It returns Success so that the Sequence sets the next child as active and executes it

    • The Wait node executes. Because it has to wait for 5 seconds and was just called for the 1st time, it hasn't reached the wait time, so it returns Continue

    • Because the Sequence receives a Continue state from its active child, it doesn't change the active child, so it starts from that child on the next Update

  • Once the Wait node has been updated enough to reach its timer, it returns Success so that the sequence goes to the next child.

Nodes List

Sequence

Execute child nodes one after another. If a child returns:

  • Success: the sequence ticks the next child on the next frame.

  • Failure: the sequence returns to the first child on the next frame.

  • Continue: the sequence calls that node again on the next frame.

RandomSequence

Execute a random child from its list of children every time it is called. You can specify a list of weights to apply to each child as an int array in the constructor, to make some children more likely to be picked.

Selector

Execute all children in order until one returns Success, then exit without executing the remaining children nodes. If none return Success then this node returns Failure.

Call

Call the given function, which always returns Success.

If

Call the given function.

  • If it returns true, it calls the current active child and return its state.

  • Otherwise, it returns Failure without calling its children

While

Return Continue as long as the given function returns true (so the next frame when the tree is ticked, it starts from that node again without evaluating all the previous nodes).

Children are executed one after another.

Returns Failure when the function returns false and the loop is broken.

Condition

This node returns Success if the given function returns true, and returns Failure if false.

Useful when chained with other nodes that depend on their children’s result (e.g Sequence, Selector.)

Repeat

Executes all child nodes a given number of times consecutively.

Returns Continue until it reaches the count, where it returns Success.

Wait

Returns Continue until the given time has been reached (starting when first called), where it then returns Success.

Trigger

Allows the setting of a trigger (or unsetting of a trigger if the last argument is set to false) in the given animator. Always returns Success.

SetBool

Allows setting the value of a Boolean Parameter in the given animator. Always returns Success

SetActive Set active/inactive a given GameObject. Always returns Success.

Related tutorials