Tutorial 1: Getting started

Step one: Setting up a Behave unity project

When you’ve created a new unity project or already got one which you’d like to extend with the Behave library, you first need to fetch the Behave unity package from the Downloads section of this site.

This package includes some editor scripts, the Behave library, a license file and some logo files (please read the license if you haven’t done so already).

Once you have the file downloaded and unzipped, you need to add its contents to your project. Do this by selecting “Import package…” from the unity “Assets” menu and choosing the unzipped Behave package file. unity will now add the files contained in the package to its correct locations within your assets folder.

Note: Do not relocate the Behave library or the script files – doing so could render the Behave features unusable.

Step two: Creating your first Behave library asset

Your project is now Behave enabled! Ka-ching! Now lets get cracking!

At the core of the Behave library lies your Behave asset files: Behave libraries (yea I know the name is a bit silly with the core assembly being named the Behave library and all, but I’m up for suggestions!). These files store your collections: lists of your behaviour trees.

Note: Even though these assets are not used in the run-time, you would be wise to keep them around. Behave can *not* extract this data from compiled assemblies, so if you delete your Behave library asset, you cut yourself off from editing the collections within any further. Also, since these assets are not referenced by any run-time scripts, unity will not include them in your build process.

So… Lets set this up! When you added Behave to your project, some new items were added to your unity menus:

  • In the “Help” menu, you have direct access to the Behave online documentation via the “Behave documentation” item (alt+command+?)
  • In the “Assets” menu, a “Behave” submenu has been added which gives you access to the Behave editor, the compiler and import / export functionality handling Behave builder files
  • In the “Assets” -> “Create” menu, a “Behave library” item has been added – this is also available from the “Create” mini-menu in your assets browser

Right now we need to access the “Assets” -> “Create” menu in order to create our first Behave library asset.

Selecting this menu item creates a new library in your Assets folder and automatically launches the Behave library editor.

Note: Whenever you need to edit your library, you need to first select the library asset to be edited from the Assets browser and then launch the editor via the “Assets” -> “Behave” -> “Edit library” (alt+command+E).

Step three: Creating your first collection and tree

The library editor is split in two: A collection list and a tree list. Since we just created the library anew, it is quite empty and boring. To add a new collection to your library, click the “+” button below the collections list. When prompted, fill in a suitable name and click “Create”.

To add a tree to your new collection, select the collection and click the “+” button below the trees list. When prompted, fill in a suitable name and click “Create”.

Your library now contains one collection containing one blank behaviour tree.

Note: Any changes you make in the library editor are saved to your asset immediately, so be careful not to delete the wrong collection or tree.

Step four: Editing your new behaviour tree

So this is all good and well, but not much fun really. After all this is all about designing and using behaviour trees. Select your newly created tree from the trees list of the library editor and hit “Edit” to launch the behaviour tree editor. This is where the real magic happens.

The tree editor is split in two general sections: The component library / inspector area (yawn) and the tree designer (yay!).

The component library allows you to select one of the four basic behaviour tree components: Sequence, selector, decorator and action plus references to other trees in the same collection as your current tree. To add a selected component to your current tree, select it and hit the “Add component” button. To remove a component, select it by clicking its icon and then push the “Remove component” button in the inspector view.

Components (or “nodes”) in your tree can be moved around freely in the tree designer area by simply drag-dropping them by their icon. The box above each component is its connection input socket and the one below it is its connection output socket. The sequence and selector components have wider output sockets showing that they offer multiple output connections.

Add a selector component to your tree.

At the top centre of your tree designer area, you will notice a lonely connection socket. This is the entry point of your behaviour tree. Whenever your tree is evaluated, the component connected to this socket will be handled first.

Create a connection between the entry point of your tree and your newly created selector component by clicking the entry point connection socket, dragging and releasing on your selector component input socket. Your tree editor should now look something like this:

Notice how the colour of both connection sockets change, indicating that they are no longer unused.

Note: Unlike the library editor, changes made in the tree editor are not saved until you close the editor.

Step five: Building a tree structure

Yay. One component in an editor. Wohoo! This isn’t exactly much of a tree though. Moar stuff!

Add a sequence component and four actions to your tree. Create connections in your tree like this:

  • Selector -> Sequence
  • Sequence -> First action
  • Sequence -> Second action
  • Selector -> Third action
  • Selector -> Fourth action

Your tree should now look something like this:

As you can see I’ve made a mistake and “accidentally” connected the selector to one of the actions before connecting it to the sequence. Oh my.

To correct this, I simply select the selector (bwarharhar) and, in the connections list of the inspector view, find the connection which I wish to move. Doing so highlights the connection in the tree designer area and brings up two arrow buttons. Clicking either of these moves the selected connection up or down in the connection list – thus changing the order in which the connections are activated.

Wee! Fixed!

Step six: Actions

While the Behave editor lets you design the logic your AI characters, the actual execution of input gathering and reactions takes place in your own code.

Not only does this grant you access to the full powers of the unity API for input gathering and agent reaction, but it also allows you to implement the same behaviour logic on different character types by simply referencing the same behaviour trees from the Behave runtime.

Additionally you can take advantage of object oriented programming in your AI creation by, for instance, creating a set of default action / decorator implementations in one class and overriding some / adding new ones in another class by way of inheritance.

More on this when we discuss adding your tree to the Behave runtime.

Notice the labels reading “Unknown” next to all your actions? These are the action names by which the Behave runtime will handle them. To set an action name to something more meaningful, select the action component and fill out the “Action name” property in the inspector.

Notice that the name can only contain letters, numbers and underscores (except the first character which must be an underscore or a letter). This restriction is set in place since your action names later on will be compiled to entries in an enum list.

Name your actions “ActionOne”, “ActionTwo”, “ActionThree”, “ActionFour”, giving you a tree looking something like this:

Yay! You now have a tree which “does” something. If you like, you can add comments to any of your components by selecting it and entering a string in the “Comment” property. This is purely for your own amusement, but can come in handy when your behaviour trees grow in size.

We’re done editing! Close your tree editor and choose to save your tree when prompted. Also close the library editor. Time to move on!

Step seven: Compiling your library for the Behave runtime

To access your library from your code, you first need to compile it. The Behave compiler translates all your metadata into one neat streamlined .net assembly. No expensive runtime data parsing or strange script languages. Neat huh?

Select your library asset from your assets browser and choose “Build library debug” (alt+command+B) from the “Assets” -> “Behave” menu. This launches the Behave compiler. Let it do its magic – it shouldn’t take long.

Building in debug mode enables some neat runtime debugging features on your library. A side effect of this is an increase in the size of the resulting assembly as your library metadata is included in the build and also you will get a minor processing overhead as a result of the debugger tracking the state of the tree more closely. We’re talking tiny bits of overhead here, but you might as well get rid of that when you’re ready for release.

Another neat trick of the debug compile mode is the generation of a text file containing the name of your library class in the Behave runtime and a complete list of the enum values available (tree, action and decorator names).

If you experience any problems in this compile (you really, really shouldn’t), please consult the FAQ in the Documentation section of this page. Should following this still not solve your problem, please post a reply to the updates and feedback forum thread linked from the “Updates and feedback” menu item.

Its done already, isn’t it? Lets see what this baby can do!

Step eight: Your library in the Behave runtime

The .net assembly generated by the compiler contains a class named BL<TheNameOfYourLibraryAsset>. Inside this class you’ll find three sets of enums containing the names of your trees, actions and decorators, accessors for your behaviour trees and a set of debug functions (only enabled if you chose to build for debug).

As mentioned in the previous step, compiling for debug will also generate a text file containing a list of these names. To put it in coders terms, your library class looks like this:

public class BLYourLibraryName
{
    public enum Trees{ /*…*/, Unknown };
    public enum Actions{ /*…*/, Unknown };
    public enum Decorators{ /*…*/, Unknown };
       
    public Tree Tree( int treeID );
    public int TreeID( Tree tree );
    public bool DebugAvailable();
    public string GetActiveComponent( Tree tree );
    public void OnGUI( Tree tree );
}

In my case I kept the default name of the library asset and simply named my collection and tree “Collection” and “Tree”. This gives me a debug text file like this:

Library class:
BLNewBehavelibrary0

Trees:
	Collection_Tree
	Unknown

Actions:
	ActionOne
	ActionTwo
	ActionThree
	ActionFour
	Unknown

Decorators:
	Unknown
									

And that means that my library class looks like this:

public class BLNewBehavelibrary0
{
    public enum Trees{ Collection_Tree, Unknown };
    public enum Actions{ ActionOne, ActionTwo, ActionThree, ActionFour, Unknown };
    public enum Decorators{ Unknown };
       
    public Tree Tree( int treeID );
    public int TreeID( Tree tree );
    public bool DebugAvailable();
    public string GetActiveComponent( Tree tree );
    public void OnGUI( Tree tree );
}

Your library class is actually a singleton and you therefore needn’t create and keep track of an instance of it in order to access it. If I, for instance, need an instance of the single tree contained within my library, I can simply write:

Tree myTree = BLNewBehavelibrary0.Instance.Tree( ( int ) BLNewBehavelibrary0.Trees.Collection_Tree );

Notice how your enum value needs to be cast to integer before being sent as a parameter to the Tree method. All names within the Behave runtime are replaced by integer values, but the values used are mapped, for your convenience, to the name enums defined in your library class. Neat huh?

Step nine: Hooking up your script via the Agent interface

As mentioned earlier, all actions and decorators used by your behaviour tree logic must be implemented in scripting (you may choose to not handle some actions and in stead return a default behaviour value for unhandled actions and decorators). To link this up, you need to provide your trees access to your implementation via the Agent interface:

namespace BehaveLibrary
{
    public interface Agent
    {
        BehaveResult TickAction( int action, Tree sender, Object data );
        void ResetAction( int action, Tree sender, Object data );
        BehaveResult TickDecorator( int decorator, Tree sender, Object data );
        void ResetDecorator( int decorator, Tree sender, Object data );
    }
}

Create a new MonoBehaviour script and add BehaveLibrary.Agent to its interface list like so:

public class NewBehaviourScript : MonoBehaviour, BehaveLibrary.Agent {

Since we’ve now told the mono compiler that we’re implementing the Agent interface, we need to also define the TickAction, ResetAction, TickDecorator and ResetDecorator methods as described in the interface definition above. Note that these methods *must* be declared public.

The TickAction and TickDecorator method are executed when a tree, during an evaluation, hits an action or decorator respectively. The parameters of these methods are populated by:

  • An integer value representing the name of the action or decorator requested. You can cast this to BL<YourLibraryClass>.Actions or BL<YourLibraryClass>.Decorators respectively to get the corresponding enum name.
  • A reference to the tree requesting the action or decorator. This could be useful in case you have multiple trees addressing the same Actor.
  • A data parameter. You’re free to set this to any value when you request a tree update (or to simply ignore it). This could be useful if, for instance your tree is designed to evaluate an enemy, and you pass a reference to the enemy currently being evaluated as data parameter.

The ResetAction and ResetDecorator method receive the exact same parameters – the only difference being that they are executed when a tree is reset. This would be the place to reset internal data structures which only make sense until you reset the internal state of the tree.

Since behaviour trees operate with the three basic values Success, Failure and Running, we need to have our actions return one of the three back to the tree requesting action or decorator execution. The values used in Behave are given by the BehaveResult enum, defined in the BehaveLibrary namespace:

namespace BehaveLibrary
{
    public enum BehaveResult{ Running, Success, Failure };
}

For this example, lets just simply catch the four actions we defined in our tree, output some strings and return success. Later on you could try changing the values being returned and add some more functionality to each action. Since we know that we won’t be getting any decorator requests, we’ll just implement empty methods for decorator handling.

Your code should now look something like this (note that I added “using BehaveLibrary;” to the beginning of the code for less typing):

using UnityEngine;
using System.Collections;
using BehaveLibrary;

public class NewBehaviourScript : MonoBehaviour, Agent
{
        // Use this for initialization
        void Start () {

        }

        // Update is called once per frame
        void Update () {

        }

        public BehaveResult TickAction( int action, Tree sender, Object data )
        {
                switch( ( BLNewBehavelibrary0.Actions )action )
                {
                        case BLNewBehavelibrary0.Actions.ActionOne:
                                Debug.Log( "ActionOne" );
                                return BehaveResult.Success;
                        case BLNewBehavelibrary0.Actions.ActionTwo:
                                Debug.Log( "ActionTwo" );
                                return BehaveResult.Success;
                        case BLNewBehavelibrary0.Actions.ActionThree:
                                Debug.Log( "ActionThree" );
                                return BehaveResult.Success;
                        case BLNewBehavelibrary0.Actions.ActionFour:
                                Debug.Log( "ActionFour" );
                                return BehaveResult.Success;
                }

                Debug.LogError( "Unknown action ID: " + action );
                return BehaveResult.Failure;
        }

        public void ResetAction( int action, Tree sender, Object data )
        {
        }

        public BehaveResult TickDecorator( int decorator, Tree sender, Object data )
        {
                return BehaveResult.Success;
        }

        public void ResetDecorator( int decorator, Tree sender, Object data )
        {
        }
}

That’s all good and well – pretty code, but it doesn’t really do anything. Next up: Connecting our tree to our agent and running it. Wohoo!

Step ten: Patching in to the tree. Its showtime!

Ok so now we have an Agent script capable of handling the four actions of our tree and we have our tree compiled and ready for action. Lets connect these two, shall we?

First we need to create and store an instance of our tree class. Add a private variable of the type Tree to your class and in the Start method of your script, grab an instance of the tree:

        private Tree myTree;
       
        // Use this for initialization
        void Start () {
                myTree = BLNewBehavelibrary0.Instance.Tree( ( int ) BLNewBehavelibrary0.Trees.Collection_Tree );
        }

Note: If the integer passed to the Tree method of your library does not evaluate to a known tree, the method will return null.

Secondly we need to update the tree regularly. You could choose to do so in your Update method, but I prefer using FixedUpdate so as to not spend too many CPU cycles on my AI. You might even opt to add some code which updates the tree even less often for better performance.

For this example, lets just change the Update method, which unity added by default to our code, to FixedUpdate and update out tree instance inside this:

        void FixedUpdate () {
                if( myTree.Tick( this, null ) != BehaveResult.Running )
                {
                        Debug.Log( "Resetting" );
                        myTree.Reset( this, null );
                }
        }

The first parameter of the Tree.Tick method is the Actor which should receive action and decorator requests and the second parameter is the data parameter. Since we’re not using the data parameter for anything, we’ll just pass null.

I’ve put the Tick call inside an if which checks if the tree still has tasks to complete or whether it has completed a full evaluation. When the tree has gone through all its brances and all actions and decorators within have returned either Success or Failure, the entrypoint of the tree will evaluate to either Success or Failure.

For this example I’ve chosen to simply reset the tree state (effectively restarting the tree) when that happens. For your needs, you might want to handle a completed evaluation differently.

That’s it! No more coding! Add your script to a game object, for instance the Main Camera, and hit play!

Play around with returning different BehaveResults for your actions and observe the results in the log. Also check out the various debug methods available in your library class. You will find them described in the “Documentation” section of this site.