Bolt / Behavior Designer Integration Tutorial

This entry is part of a series of tips I am creating as I make my game.

You can use Bolt for free by downloading it from the Asset Store.

Behavior Designer is an Artificial Intelligence Behavior Tree tool that can also be found on the Asset Store.

In this tutorial, I’ll be explaining how to integrate Bolt and Behavior Designer; specifically, their variables. For example, taking a string directly from Bolt and assigning it to a variable inside a Behavior Tree.

Summary

This tutorial focuses on creating a C# integration script for transferring variables from Bolt Visual Scripting to Behavior Designer. Here’s the TL;DR version of the steps:

  1. Create a custom Behavior Designer Action Task.
  2. (Inside the Custom Task C# Script) Reference the GameObject if using GameObject Bolt Variables, otherwise directly access (i.e. Bolt Scene Variables).
  3. (Inside the Custom Task C# Script) Set Behavior Designer shared variable’s value equal to the ‘Get’ of a Bolt Variable.
  4. Open the Behavior Tree and include the new Task in your tree using a Sequence, Selector, etc.
  5. Open the Task in your Behavior Tree with the inspector and assign the variables to variables inside your Behavior Tree.

What is Behavior Designer?

What is Bolt Visual Scripting?

How Can we Integrate the Two?

If you are just interested in the script, I’ve included it below in Custom Behavior Designer Task section below (just copy paste the code into a text file and save it with a .cs extension inside your Unity3D Asset Folder).

First things first. What does integration look like?

When I thought about it, I came to the conclusion that much of the time we’re going to have some kind of variables that we need to share between Behavior Designer and Bolt and so that’s what I focused on.

Here’s what you will end up with:

The Custom Action Task will run inside your Behavior Tree, and can be modified to Get or Set variables for both Bolt and Behavior Designer. The reason why I chose to do this via a task in Behavior Designer was this:

Behavior Designer requires a setting inside the Behavior Tree where you assign the result of a value to a variable within the tree. This requirement can be an issue if you tried to drive the variable from a Custom Bolt Task instead.

Custom Behavior Designer Task

Below is the code for creating a Custom Behavior Designer Action Task to upload variables from Bolt -> Behavior Designer. You can modify it if you need to apply variables from Behavior Designer -> Bolt as well! Please feel free to add comments below if you have any issues, or would like anything added.

Step-by-step:

  1. Make sure your Behavior Designer / Bolt integration C# script contains both namespaces, i.e.;
// Make sure to include the Behavior Designer namespace:
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
// And the Bolt namespace:
using Ludiq;
using Bolt;

2. Next, change MonoBehavior to Action in your class declaration:

// INCORRECT:
public class Upload_Bolt_Variables : MonoBehaviour {}
// CORRECT:
public class Upload_Bolt_Variables : Action {}

3. Declare your Behavior Designer variables. In my example case, I used SharedString. The following steps use the Behavior Designer API.

// A string variable that can be seen in the Behavior Tree editor
public SharedString behaviorDesignerString;

4. Setup the method that you want to use. If you want these variables to update a single time, you can use:

// This runs a single time
public override void OnAwake(){ }

Or, if you want these variables to constantly update..

// This runs every frame
public override TaskStatus OnUpdate(){ }

5. Within the OnAwake() or OnUpdate(), before the variable updates. In my example case, I am updating a single string called behaviorDesignerString using a Bolt Visual Scripting string. The .Value attribute works for accessing most variables in Behavior Designer.

behaviorDesignerString.Value = (string)Variables.Object(this.gameObject).Get("boltString");

If I wanted to instead update the Bolt Visual Scripting Variable with the value stored at the Behavior Designer variable, I would do the following:

Variables.Object(gameObjectWithVariable).Set("boltString", behaviorDesignerString.Value);

In this case, the Bolt Visual Scripting Variable is obtained from the GameObject gameObjectWithVariable. This is whatever you have attached the following module to:

6. Once your C# script is ready (and is properly configured to be included in the Behavior Designer API), you do not need to attach it to anything. Instead, open up the Behavior Designer Tree (Shown above). You should see this:

7. If your new Behavior Designer Action is working properly, it should show up once you search it by it’s class name:

Notice how it matches this:

8. Now you can include it in your Behavior Tree! Here I used a Sequence so that I could examine the results using the Debug Log.

9. Depending on how you are Setting or Getting variables in your C# script, you will want to assign them (or pull from) variables within the Behavior Tree.

10. Finally, access the new Behavior Designer Action you added to the Tree so that you can have the variable either store or assign the Bolt Variable(s). Experiment with viewing these variables in the Debug Log so that you can understand how they are being set. The Complete Integration Script below combined with this tree will output behaviorDesignerString to the console, where behaviorDesignerString = boltString, the Bolt Visual Scripting Variable that we wanted originally.

See the Complete Integration Script below for more examples of how you can configure this Variable communication. From here you should be able to build out your logic in both Bolt and Behavior Designer and use this method to communicate between the two. For more information, see the documentation linked below.

Bolt Variables:

  1. Bolt Variable API.

Custom Behavior Designer Task documentation:

  1. Writing a new Action Task.
  2. Behavior Designer Task API.

The Complete Integration Script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// Make sure to include the Behavior Designer namespace:
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
// And the Bolt namespace:
using Ludiq;
using Bolt;

/* Purpose: To demonstrate how to transfer Bolt Variables to Behavior Designer, and vice-versa, using a C# script.

Dependencies
  - Behavior Designer: https://bit.ly/3jY8W7k
  - Bolt Visual Scripting: https://bit.ly/30THPS3
 
 */

public class Upload_Bolt_Variables : Action
{
	[Header("Behavior Designer Variables:")]
	/* Some Example Behavior Designer variables:
	
    public SharedGameObjectList exampleGameObjectList;
	public SharedGameObject exampleGameObject;
	public SharedTransform exampleTransform;
	public SharedInt exampleInt;
	public SharedFloat exampleFloat;
	public SharedString exampleString;
	public SharedVariable exampleVar;
	
	Setting/Getting a Behavior Designer variable:
	exampleString.Value = "I'm now set to this string!";
	demoString = exampleString.Value;
	
	Read the docs for Behavior Designer - Writing a new Task: https://opsive.com/support/documentation/behavior-designer/writing-a-new-conditional-task/
	Read the docs for Behavior Designer - Task API: https://opsive.com/support/documentation/behavior-designer/tasks/
	*/
	public SharedString behaviorDesignerString;
	
	[Header("Bolt Variables:")]
	public string valueOfBoltString;
	
	/* Some Example Bolt Variables
	
	Accessing Scene, Object, Application, or Saved variables:
	- Variables.Scene(scene)
	- Variables.Object(gameObject)
	- Variables.Application
	- Variables.Saved
	
	Note: Bolt Variables are not strongly typed, so you will need to cast them manually, i.e. the '(int)' shown below.
	
	Getting Bolt Variables:
	int exampleInteger = (int)Variables.Object(gameObjectWithVariable).Get("exampleInteger");
	
	Setting Bolt Variables (Using Set with a Variable Name that does not exist yet will create a new one):
	Variables.Object(gameObjectWithVariable).Set("exampleInteger", 10);
	
	Read the docs for Bolt Variable API: https://docs.unity3d.com/2019.3/Documentation/Manual/bolt-variables-api.html
	*/
	
	public override void OnAwake(){
		// If we want to update a Behavior Designer variable using a Bolt Variable that is defined on the game object this script is attached to..
		behaviorDesignerString.Value = (string)Variables.Object(this.gameObject).Get("boltString");
		valueOfBoltString = behaviorDesignerString.Value; 
		/* For reference, if you need to obtain a List Variable from Bolt (It's hard to find this in the documentation):
        myBehaviorTreeGameobjectList.Value = 
 ((IEnumerable)Variables.Object(objectWithVariables).Get("myBoltGameobjectList")).Cast<GameObject>().ToList();
You will need to include the using System.Linq; namespace.
*/ 
	}

/*
If you prefer updating variables every frame, put your code here:
	public override TaskStatus OnUpdate(){
        // return TaskStatus.Success; // If this branch leads to success (Behavior Tree continues running)
        // return TaskStatus.Failure; // If this branch leads to success (Behavior Tree stops)
	}

*/
}

Thanks for reading!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: