# Behavior Designer Pro - Opsive Documentation

> Complete Behavior Designer Pro documentation, generated from the Opsive documentation source on 2026-08-14.

Documentation home: https://opsive.com/support/documentation/behavior-designer-pro/

## Contents

- [Behavior Designer Pro](#page-behavior-designer-pro)
  - [Overview](#page-behavior-designer-pro-overview)
  - [Requirements](#page-behavior-designer-pro-requirements)
  - [Version Comparison](#page-behavior-designer-pro-version-comparison)
  - [Getting Started](#page-behavior-designer-pro-getting-started)
    - [Your First Behavior Tree](#page-behavior-designer-pro-getting-started-first-behavior-tree)
    - [Sample Scenes](#page-behavior-designer-pro-getting-started-sample-scenes)
    - [GameObject or Entity Tasks](#page-behavior-designer-pro-getting-started-gameobject-or-entity-tasks)
    - [Updating and Migration](#page-behavior-designer-pro-getting-started-updating-and-migration)
    - [Import Errors](#page-behavior-designer-pro-getting-started-import-errors)
    - [Custom Task Migration](#page-behavior-designer-pro-getting-started-task-migration)
  - [Concepts](#page-behavior-designer-pro-concepts)
    - [What is a Behavior Tree?](#page-behavior-designer-pro-concepts-what-is-a-behavior-tree)
    - [Behavior Trees vs Finite State Machines](#page-behavior-designer-pro-concepts-behavior-trees-vs-finite-state-machines)
    - [Flow](#page-behavior-designer-pro-concepts-flow)
    - [Blackboard](#page-behavior-designer-pro-concepts-blackboard)
    - [Tasks](#page-behavior-designer-pro-concepts-tasks)
      - [Actions](#page-behavior-designer-pro-concepts-tasks-action)
        - [Perform Interruption](#page-behavior-designer-pro-concepts-tasks-action-perform-interruption)
        - [Stacked Action](#page-behavior-designer-pro-concepts-tasks-action-stacked-action)
      - [Conditionals](#page-behavior-designer-pro-concepts-tasks-conditional)
        - [Stacked Conditional](#page-behavior-designer-pro-concepts-tasks-conditional-stacked-conditional)
      - [Composites](#page-behavior-designer-pro-concepts-tasks-composite)
        - [Selector](#page-behavior-designer-pro-concepts-tasks-composite-selector)
        - [Sequence](#page-behavior-designer-pro-concepts-tasks-composite-sequence)
        - [Parallel](#page-behavior-designer-pro-concepts-tasks-composite-parallel)
        - [Parallel Selector](#page-behavior-designer-pro-concepts-tasks-composite-parallel-selector)
        - [Utility Selector](#page-behavior-designer-pro-concepts-tasks-composite-utility-selector)
        - [Priority Selector](#page-behavior-designer-pro-concepts-tasks-composite-priority-selector)
        - [Random Selector](#page-behavior-designer-pro-concepts-tasks-composite-random-selector)
        - [Random Sequence](#page-behavior-designer-pro-concepts-tasks-composite-random-sequence)
        - [Selector Evaluator](#page-behavior-designer-pro-concepts-tasks-composite-selector-evaluator)
      - [Decorators](#page-behavior-designer-pro-concepts-tasks-decorator)
        - [Conditional Evaluator](#page-behavior-designer-pro-concepts-tasks-decorator-conditional-evaluator)
        - [Cooldown](#page-behavior-designer-pro-concepts-tasks-decorator-cooldown)
        - [Iterator](#page-behavior-designer-pro-concepts-tasks-decorator-iterator)
        - [Inverter](#page-behavior-designer-pro-concepts-tasks-decorator-inverter)
        - [Repeater](#page-behavior-designer-pro-concepts-tasks-decorator-repeater)
      - [Events](#page-behavior-designer-pro-concepts-tasks-event)
    - [Common Behaviors](#page-behavior-designer-pro-concepts-common-behaviors)
      - [Wander for a Limited Time](#page-behavior-designer-pro-concepts-common-behaviors-wander-for-a-limited-time)
      - [Patrol and Chase an Enemy](#page-behavior-designer-pro-concepts-common-behaviors-patrol-and-chase-an-enemy)
      - [Retry with Delay](#page-behavior-designer-pro-concepts-common-behaviors-retry-with-delay)
      - [Timeout](#page-behavior-designer-pro-concepts-common-behaviors-timeout)
      - [Attack with Cooldown](#page-behavior-designer-pro-concepts-common-behaviors-attack-with-cooldown)
      - [React to an Event](#page-behavior-designer-pro-concepts-common-behaviors-react-to-event)
      - [Search After Losing a Target](#page-behavior-designer-pro-concepts-common-behaviors-search-after-losing-target)
      - [Flee at Low Health](#page-behavior-designer-pro-concepts-common-behaviors-flee-at-low-health)
      - [Fallback Strategies](#page-behavior-designer-pro-concepts-common-behaviors-fallback-strategies)
      - [Switch Subtrees](#page-behavior-designer-pro-concepts-common-behaviors-switch-subtrees)
      - [Choose the Highest-Priority Need](#page-behavior-designer-pro-concepts-common-behaviors-highest-priority-need)
  - [New Tasks](#page-behavior-designer-pro-new-tasks)
    - [GameObject Task](#page-behavior-designer-pro-new-tasks-gameobject-task)
    - [Entity Task](#page-behavior-designer-pro-new-tasks-entity-task)
    - [Event Node](#page-behavior-designer-pro-new-tasks-event-node)
  - [Conditional Aborts](#page-behavior-designer-pro-conditional-aborts)
  - [Variables](#page-behavior-designer-pro-variables)
    - [Accessing Variables](#page-behavior-designer-pro-variables-accessing-variables)
    - [ECS Variables](#page-behavior-designer-pro-variables-ecs)
    - [Scope](#page-behavior-designer-pro-variables-scope)
    - [Property Binding](#page-behavior-designer-pro-variables-property-binding)
  - [Entity Baking](#page-behavior-designer-pro-entity-baking)
  - [Events](#page-behavior-designer-pro-events)
  - [Subtrees](#page-behavior-designer-pro-subtrees)
  - [Debugging](#page-behavior-designer-pro-debugging)
  - [Performance](#page-behavior-designer-pro-performance)
  - [Syncing Animations](#page-behavior-designer-pro-syncing-animations)
  - [Referencing Scene Objects](#page-behavior-designer-pro-referencing-scene-objects)
  - [Save/Load](#page-behavior-designer-pro-save-load)
  - [Extending the Editor](#page-behavior-designer-pro-extending-the-editor)
    - [Control Types](#page-behavior-designer-pro-extending-the-editor-control-types)
    - [Node Views](#page-behavior-designer-pro-extending-the-editor-node-views)
  - [API](#page-behavior-designer-pro-api)
  - [Networking](#page-behavior-designer-pro-networking)
  - [Repository](#page-behavior-designer-pro-repository)
  - [Resources](#page-behavior-designer-pro-resources)
  - [Integrations](#page-behavior-designer-pro-integrations)
    - [A* Pathfinding Project](#page-behavior-designer-pro-integrations-astar-pathfinding-project)
    - [Animal Controller](#page-behavior-designer-pro-integrations-animal-controller)
    - [Atlas](#page-behavior-designer-pro-integrations-atlas)
    - [Curvy Splines](#page-behavior-designer-pro-integrations-curvy-splines)
    - [Dialogue System](#page-behavior-designer-pro-integrations-dialogue-system)
    - [DOTS Survivors](#page-behavior-designer-pro-integrations-dots-survivors)
    - [Easy Build System](#page-behavior-designer-pro-integrations-easy-build-system)
    - [Feel](#page-behavior-designer-pro-integrations-feel)
    - [Juicy Actions](#page-behavior-designer-pro-integrations-juicy-actions)
    - [Love/Hate](#page-behavior-designer-pro-integrations-love-hate)
    - [PlayMaker](#page-behavior-designer-pro-integrations-playmaker)
    - [Quest Machine](#page-behavior-designer-pro-integrations-quest-machine)
    - [Sensor Toolkit 2](#page-behavior-designer-pro-integrations-sensor-toolkit-2)
    - [Simple Waypoint System](#page-behavior-designer-pro-integrations-simple-waypoint-system)
    - [State Designer](#page-behavior-designer-pro-integrations-state-designer)
    - [Ultimate Character Controller](#page-behavior-designer-pro-integrations-ultimate-character-controller)
    - [Ultimate Inventory System](#page-behavior-designer-pro-integrations-ultimate-inventory-system)

---

<a id="page-behavior-designer-pro"></a>

# Behavior Designer Pro

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/)

Behavior Designer Pro is a visual behavior-tree editor for Unity. Use it to build reactive AI and other decision-making logic from reusable Tasks, then inspect the active branch and values while the game is running.

You do not need prior DOTS or ECS experience to begin. Behavior Designer Pro uses Entities internally, while the ordinary GameObject Task workflow works with familiar Unity components and scene objects.

## Start here

1. Confirm the supported Unity and Entities versions on [Requirements](https://opsive.com/support/documentation/behavior-designer-pro/requirements/).
2. Follow [Getting Started](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/) to import the samples and recognize the main editor surfaces.
3. Build [Your First Behavior Tree](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/first-behavior-tree/) and verify its Console output in Play Mode.
4. Open the [Sample Scenes](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/sample-scenes/) catalog and choose the next scene by outcome and difficulty.

If behavior trees are new to you, read [What Is a Behavior Tree?](https://opsive.com/support/documentation/behavior-designer-pro/concepts/what-is-a-behavior-tree/) before the first-tree tutorial.

## Build behavior

- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/) explains Actions, Conditionals, Composites, Decorators, and Events and provides the searchable built-in Task reference.
- [Common Behaviors](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/) combines Tasks into recognizable patterns such as patrol and chase, cooldowns, retries, event reactions, and fallback behavior.
- [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) explains how a tree reevaluates higher-priority decisions while another branch is running.
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) explains how Tasks share values and how Graph, GameObject, Scene, and Project scopes differ.
- [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) extracts and reuses complete branches.

## Choose a runtime workflow

Start with [GameObject or Entity Tasks](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/) when you are unsure which Task family to select. GameObject Tasks are the recommended first route for component-based projects. Entity Tasks are intended for data-oriented behavior that already needs ECS scale.

## Diagnose a tree

[Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/) starts with the Error Window, then covers Play Mode status, watched values, variables, disabled Tasks, and the most common reasons a tree does not start or choose the expected branch.

## Extend and integrate

- [New Tasks](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/) creates project-specific GameObject or Entity Tasks.
- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/) connects supported external systems.
- [Save/Load](https://opsive.com/support/documentation/behavior-designer-pro/save-load/), [Networking](https://opsive.com/support/documentation/behavior-designer-pro/networking/), and [API](https://opsive.com/support/documentation/behavior-designer-pro/api/) cover runtime ownership and code-facing workflows after the first tree works.

---

<a id="page-behavior-designer-pro-overview"></a>

# Overview

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/overview/)

Behavior Designer Pro is a visual behavior-tree editor and runtime for Unity. It carries the feature set of the original Behavior Designer onto a DOTS architecture: trees are traversed by Burst-compiled jobs over Entities, while authoring remains component-based. Building GameObject trees requires no ECS knowledge and no ECS gameplay code — see [GameObject or Entity Tasks](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/) for what the dependency does and does not require.

This page covers the editor itself: its regions, graph and connection commands, preferences, and shortcuts. [Concepts](https://opsive.com/support/documentation/behavior-designer-pro/concepts/) covers the behavior-tree model, and [What Is a Behavior Tree?](https://opsive.com/support/documentation/behavior-designer-pro/concepts/what-is-a-behavior-tree/) covers the four Task types — Action, Composite, Conditional, and Decorator — that the editor is organized around.

Open the editor from **Tools > Opsive > Behavior Designer > Editor**.

## Open the editor

![The Behavior Designer Pro editor shows an empty graph with its inspector and Shared Variables panels.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-empty-editor.webp?v=7d9c1dcee8ac)

## Understand the editor regions

There are four sections within Behavior Designer. From the screenshot below, section 1 is the graph area. It is where you'll be creating the behavior trees. Section 2 is the inspector panel. The inspector panel is where you'll be editing the task field values or creating new variables. Section 3 is the behavior tree operations toolbar. The final section, section 4, is the debug toolbar.

![Numbered labels identify the graph, inspector, Shared Variables, and toolbar regions.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-editor-regions.webp?v=84ba89909d51)

## Create a behavior tree

Section 1 is the main part of Behavior Designer that you'll be working in. Within this section you can create new tasks and arrange those tasks into a behavior tree. To start things off, you first need to add a Behavior Tree component. The Behavior Tree component will act as the manager of the behavior tree that you are just starting to create. You can create a new Behavior Tree component by right clicking within the graph area and clicking "Add Behavior Tree" or by clicking on the plus button within the operations area of section 3. Once a Behavior Tree has been added you can start adding tasks. Add a task by pressing the space bar or right click within the graph area and select "Create Task":

![The task selector is open to add a Composite task to the behavior tree.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-add-task-selector.webp?v=9a54a0b9b365)

Once a task has been added you'll see the following:

![A newly added Sequence appears below the automatically created Start node.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-sequence-with-start.webp?v=019978f9844c)

The Start event is added alongside the first Task and acts as the root of the tree. The Sequence shows a green border because it is a pure ECS Task, and an error because it has no children; connecting a child clears the error. Adding several more Tasks gives:

![An initial tree connects a Sequence to Selector branches and placeholder Actions.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-initial-tree.webp?v=bd89d65cbd97)

## Edit a task

You can connect the sequence and selector task by dragging from the bottom of the sequence task to the top of the selector task. Repeat this process for the rest of the tasks. If you make a mistake you can select a connection and delete it with the delete key. You can also rearrange the tasks by clicking on a task and dragging it around. Behavior Designer will execute the tasks in a depth first order. You can change the execution order of the tasks by dragging them to the left/right of their sibling. From the screenshot above, the tasks will be executed in the following order: SequenceA, SelectorA, SequenceB, ActionA, ActionB, ActionC, SelectorB, ActionD, ActionE

![A selected tree node displays its editable fields in the Task Inspector.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-selected-node-inspector.webp?v=914f79b96748)

Select the SelectorA node to open its Inspector. The Inspector renames the Task, adds a comment, and edits every serialized field the node declares, including assigning a field to a Shared Variable. Selector declares one serialized field, **Abort Type**. The Shared Variables panel at the bottom left creates values shared between Tasks, GameObjects, scenes, or projects. Both the Element Inspector and the Shared Variables panel can be rearranged and resized.

## Use the operations toolbar

![The operations toolbar provides tree selection, creation, removal, navigation, and settings controls.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-operations-toolbar.webp?v=d3396129b8df)

The top section within the Behavior Designer window is the operations toolbar. The operations toolbar is mostly used for selecting behavior trees as well as adding/removing behavior trees. The following operations are labeled:

-   Label 1: Navigate back from the last behavior tree that was opened.
-   Label 2: Navigate forward to the next behavior tree that was opened.
-   Label 3: Lists any GameObject within the scene that has the behavior tree component added to it.
-   Label 4: Lists any behavior trees that are attached to the GameObject that is selected from label 3.
-   Label 5: Exports the behavior tree to a Subtree ScriptableObject.
-   Label 6: Opens the find dialogue which can search your behavior tree.
-   Label 7: Keeps the current behavior tree active even if you have selected a different GameObject within the hierarchy or project window.

**Export** copies the complete graph into a Subtree asset without changing the source graph. To extract and replace only a selected branch, use **Save as Subtree** as described on the [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) page.

The bottom status bar contains the play, pause, and available step controls for runtime inspection. The error count opens the Error Window.

## Use the graph background menu

Right-click empty graph space to use graph-level commands:

| Command | Result |
| --- | --- |
| **Create Task** | Opens the task selector at the pointer. Space performs the same action. |
| **Create Group** | Creates an organizational group. When tasks are selected, the new group contains them. |
| **Paste** | Pastes compatible tasks, groups, and connections from the graph clipboard. |
| **Frame Selection** / **Frame All** | Fits the selected elements or the complete graph in the window. |
| **Focus > Selection Only / Connected Neighborhood / Off** | Dims unrelated elements without changing the saved behavior. |
| **Add Behavior Tree** | Adds another Behavior Tree component to the selected GameObject. |
| **Remove Behavior Tree** | Removes the selected component after confirmation. |

Task and group commands are documented with [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/). Shared Variable row commands are documented with [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/).

## Arrange connections and the graph view

Right-click a connection to use these editor-only layout commands:

- **Copy Transition** and **Paste Transition** copy compatible connection settings without replacing either endpoint.
- **Set Color** and **Reset Color** change its editor color.
- **Route > Bezier / Straight / Orthogonal** changes the drawing style.
- **Outgoing Anchor** and **Incoming Anchor** use **Auto**, **Top**, **Bottom**, **Left**, or **Right**.
- **Add Waypoint**, **Remove Waypoint**, and **Clear Waypoints** control manual bends.
- **Reset Layout** restores the connection's route, anchors, color, and waypoints.
- **Delete** removes the connection.

Use the **Panels** menu to show, hide, resize, or rearrange the Element Inspector and Shared Variables panel. **Reset Layout** restores the product layout when a panel is missing or unusably small. The graph also supports **Frame Selection**, **Frame All**, Connected Neighborhood focus, zoom-aware readability, and configurable mouse-wheel behavior.

## Inspect graph errors

Open **Tools > Opsive > Behavior Designer > Error Window**, select the status-bar error count, or press **Ctrl/Cmd+E**. Selecting an error briefly identifies its task in the graph. A clean Error Window means that the editor found no known structural or field errors; it does not replace a Play Mode test.

## Configure preferences

Open **Preferences > Behavior Designer** or **Tools > Opsive > Behavior Designer > Settings**.

| Preference | What it controls |
| --- | --- |
| **Show Hierarchy Icon** | Shows the Behavior Designer indicator in Unity's Hierarchy. |
| **Check For Errors** | Runs editor validation and updates the status-bar error count. |
| **Auto Save Prefab** | Saves prefab graph changes automatically. When off, use **Ctrl/Cmd+S** when prompted. |
| **Keep Graph Selected** | Keeps the current graph when the next Unity selection has no behavior tree. |
| **Panels** | Chooses the registered panels shown by default. |
| **Mouse Wheel Scrolls Graph** | Uses the wheel to scroll rather than perform the normal graph zoom action. |
| **Keep Selection On Graph Click** | Keeps selected elements when empty graph space is clicked. |
| **Grid Line Spacing / Transparency** | Controls the editor grid interval and opacity. |
| **Focus Mode** | Chooses the default focus view. |
| **Zoom-aware Readability** | Hides secondary detail when zoomed far out. |
| **Recent Entries** | Limits the Recent section in task selectors; `0` hides it. |
| **Show Node Icon / Description / Debug Info** | Chooses the information rendered on task nodes. |
| **Snap To Grid** | Aligns moved tasks to the editor grid. |
| **Flatten Injected Nodes** | Flattens tasks injected by a Subtree Reference in the editor view. |
| **Default Gizmos Color** | Sets the default Scene-view gizmo color. |

These settings affect authoring and presentation; they do not change task logic unless the setting explicitly controls saving or serialization.

## Use keyboard shortcuts

Open Unity's Shortcut Manager or select **Edit Bindings** in the shortcut preferences to rebind these defaults:

| Shortcut | Action |
| --- | --- |
| Space | Create Task |
| Ctrl/Cmd+F | Open Find |
| Ctrl/Cmd+Shift+F | Focus the next Find result |
| Ctrl/Cmd+G | Create a group from the selection |
| Ctrl/Cmd+Shift+G | Remove selected groups without deleting their tasks |
| Home | Focus the initial node |
| F / A | Frame Selection / Frame All |
| Shift+F | Toggle Connected Neighborhood focus |
| Ctrl/Cmd+0 | Reset zoom |
| C | Collapse or expand the selection |
| Enter | Focus the Element Inspector |
| Arrow keys / Shift+Arrow keys | Nudge by the normal or larger step |
| Ctrl/Cmd+E | Open the Error Window |
| Esc | Cancel the active operation or clear the applicable selection |

Standard Cut, Copy, Paste, Duplicate, Delete, and Save shortcuts apply whenever the matching graph command is available.

## Related pages

Behavior Designer Pro preferences are also reachable from the [Unity Preferences window](https://docs.unity3d.com/Manual/Preferences.html).

- [New Tasks](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/) covers adding project-specific Task logic.
- [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) covers how a running tree reacts when a Conditional changes status.
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) covers Shared Variables and their scopes.
- [Performance](https://opsive.com/support/documentation/behavior-designer-pro/performance/) covers execution cost and profiling.

---

<a id="page-behavior-designer-pro-requirements"></a>

# Requirements

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/requirements/)

Behavior Designer Pro requires Unity 2022.3.11 or newer and version 1.3.8 of the [Entities package](https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/getting-started-installation.html). The runtime uses Entities for efficient tree traversal, so the package is required even when every authored task uses the GameObject workflow. If it is missing, the Behavior Designer Welcome Window prompts you to install it.

## Platform support

Entities and Burst do not currently support WebGL, so Behavior Designer Pro cannot target WebGL. The original [Behavior Designer](/assets/behavior-designer) remains the WebGL-compatible option.

---

<a id="page-behavior-designer-pro-version-comparison"></a>

# Version Comparison

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/version-comparison/)

## Choose a version

Both Behavior Designer and Behavior Designer Pro are supported behavior-tree implementations from Opsive. The original Behavior Designer was released in 2014 and provides the established GameObject workflow. Behavior Designer Pro applies the lessons from that product to a newer [DOTS](https://unity.com/dots), UI Toolkit, Burst, and job-system architecture.

Behavior Designer Pro requires the Unity Entities packages, but you do not need prior DOTS experience to create GameObject behavior trees. Its authoring workflow remains familiar while adding new editor, runtime, and performance capabilities.

Choose **Behavior Designer Pro** for a new project or when you want its Pro-only features. Choose the original **Behavior Designer** when maintaining an existing project that already depends on its trees, tasks, or supported platforms.

Behavior trees are not automatically convertible between the two products because their serialized structures and runtime implementations differ. Custom tasks must also be updated for the target product, so make this choice before building a large tree library. A mature project can install both products side by side and migrate one tree at a time; see [Updating and Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/updating-and-migration/).

## Compare requirements and architecture

|  | Behavior Designer | Behavior Designer Pro |
| --- | --- | --- |
| **Supported Unity Versions** | 2021.3 and newer | 2022.3.11 and newer |
| **Runtime Backend** | Standard C# | DOTS |
| **Editor Backend** | IMGUI | UIElements |
| **Platform Restrictions** | None | WebGL not supported due to Burst |
| **Code Optimizations** | No heap allocations after initialization | No heap allocations after initialization plus Burst and job system support |
| **Development Status** | Maintenance Updates | Continuous Development |

## Compare features

At the feature level both Behavior Designer and Behavior Designer Pro are behavior tree implementations. With that said, Behavior Designer Pro has many advantages over Behavior Designer:

**Legend:** ✅ Included · ❌ Not included

|  | Behavior Designer | Behavior Designer Pro |
| --- | --- | --- |
| **[Atlas-assisted authoring](https://opsive.com/support/documentation/behavior-designer-pro/integrations/atlas/)** | ❌ | ✅ |
| **[Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/)** | ✅ | ✅ |
| **[Conditional Abort Callbacks](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/)** | ❌ | ✅ |
| **[Error Window](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)** | ✅ | ✅ |
| **[Event Branches](https://opsive.com/support/documentation/behavior-designer-pro/events/)** | ❌ | ✅ |
| **[Extensible Node Inspector](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/node-views/)** | ❌ | ✅ |
| **[Extensible Task Inspector](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/control-types/)** | ✅ | ✅ |
| **[GameObject & Scene Shared Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/)** | ❌ | ✅ |
| **[Generic Shared Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)** | ❌ | ✅ |
| **[Graph & Global Shared Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/)** | ✅ | ✅ |
| **[Node Groups](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)** | ❌ | ✅ |
| **[Package-Based Workflow](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/)** | ❌ | ✅ |
| **[Property Mappings](https://opsive.com/support/documentation/behavior-designer-pro/variables/property-binding/)** | ✅ | ✅ |
| **[Runtime Tree Replacement](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/)** | ❌ | ✅ |
| **[Save/Load](https://opsive.com/support/documentation/behavior-designer-pro/save-load/)** | ❌ | ✅ |
| **[Shared Variable Change Callback](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/)** | ❌ | ✅ |
| **[Source Repository Available](https://opsive.com/support/documentation/behavior-designer-pro/repository/)** | ❌ | ✅ |
| **[Subtree Overrides](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/)** | ❌ | ✅ |
| **[Task Delegates](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/)** | ❌ | ✅ |
| **[Visual Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)** | ✅ | ✅ |
| **[Watched Variables](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)** | ✅ | ✅ |

## Start a new project

Behavior Designer Pro is the recommended package if you are just starting your project or are not that far along. Even though it uses DOTS the workflow is similar for authoring your behavior tree and the GameObject-based tasks have a similar setup as the original Behavior Designer tasks. There is an upgrade discount between Behavior Designer and Behavior Designer Pro.

For an established project, coexistence is the lower-risk route: keep original Behavior Designer trees running while rebuilding and validating selected behaviors in Pro. The packages use separate GUIDs, namespaces, editor data, and runtime data. Follow [Updating and Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/updating-and-migration/) for the staged workflow and [Custom Task Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/task-migration/) for project-owned Task code.

---

<a id="page-behavior-designer-pro-getting-started"></a>

# Getting Started

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/)

The following overview introduces Behavior Designer Pro and its editor workflow.

<iframe width="100%" height="600" src="https://www.youtube.com/embed/Sy9JOZdrIME?rel=0&amp;showinfo=0" title="Behavior Designer Pro overview video" loading="lazy" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

If the embedded player is unavailable, [watch the Behavior Designer Pro Overview on YouTube](https://www.youtube.com/watch?v=Sy9JOZdrIME).

## Import the samples

Behavior Designer Pro includes 15 sample scenes that demonstrate core behavior-tree concepts and product features. Open the Sample Hub from **Tools > Opsive > Behavior Designer > Samples**.

1. Review the sample cards. Each card includes a preview, difficulty and topic labels, a description, and the packages that the scene requires.
2. Select **Import Samples** to create a project-local copy of the bundled content under `Assets/Samples/Opsive Behavior Designer/<version>/Sample`.
3. Install any dependency marked with an exclamation point before testing its scene.
4. After the import finishes, select **Open Scene** on a card to open that example. Use **Open Documentation** when the card provides a related guide.

If sample content from an earlier Behavior Designer Pro version is already in the project, the Sample Hub offers **Update Samples** instead. This imports the current package's sample content without treating the older version's folder as the active copy.

![The Behavior Designer Pro Samples Hub lists imported sample cards with preview images, dependency status, and enabled Open Scene buttons.](https://opsive.com/wp-content/uploads/2026/08/bdp-getting-started-sample-hub.webp?v=9be6fda3471e)

**Checkpoint:** the import notice is no longer shown, **Open Scene** is enabled for the imported examples, and the Console has no new dependency or compile errors.

## Open the editor and continue learning

Open the Behavior Designer editor from **Tools > Opsive > Behavior Designer > Editor**. Continue with [Your First Behavior Tree](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/first-behavior-tree/) for the shortest complete editor-to-Play-Mode workflow. The [Overview](https://opsive.com/support/documentation/behavior-designer-pro/overview/) then explains graph navigation and layout, [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/) covers task menus and the Task Palette, [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) covers Shared Variable row options, and [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) covers graph extraction and reuse.

If you are new to behavior trees, read [What Is a Behavior Tree?](https://opsive.com/support/documentation/behavior-designer-pro/concepts/what-is-a-behavior-tree/). Use [GameObject or Entity Tasks](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/) before choosing a runtime workflow, then browse the [Sample Scenes](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/sample-scenes/) in the recommended learning order. [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) explains how a tree reacts efficiently when conditions change.

The same **Tools > Opsive > Behavior Designer** menu opens **Welcome** for product links, **Samples** for the 15 scene cards, **Task Palette** for the dockable task browser, **Error Window** for graph validation, **Atlas** for assisted authoring, and **Integrations** or **Add-Ons** for optional packages. **Settings** opens the product preferences described in the Overview. **Upgrade Project Serialization** is a project-data migration command; follow [Updating and Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/updating-and-migration/) and back up or commit the project before using it.

## If the first tree does not run

Open the Error Window before changing the graph at random. [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/) provides a symptom-to-check-to-fix route for component selection, Start connections, disabled Tasks, invalid fields, task status, and runtime values.

If you have any questions, reach out on the [forum](/forum), [Discord](https://discord.gg/SD6SPWf7hW), or by [email](mailto:support@opsive.com). Once you announce or release a project using Behavior Designer Pro, please [let us know](mailto:support@opsive.com).

---

<a id="page-behavior-designer-pro-getting-started-first-behavior-tree"></a>

# Your First Behavior Tree

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/first-behavior-tree/)

Build a small behavior tree that writes two messages with a one-second pause between them. This is the shortest project-owned workflow from an empty GameObject to an observable Play Mode result.

## Before you begin

- Complete [Getting Started](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/) and confirm that the editor opens without compiler errors.
- Use a saved scene outside the imported sample folders.

## Create the owner

1. Create an empty GameObject and name it `FirstBehaviorTree`.
2. Open **Tools > Opsive > Behavior Designer > Editor**.
3. Keep `FirstBehaviorTree` selected in the Hierarchy.
4. Right-click empty graph space and select **Add Behavior Tree**. The same command is available from the add button in the operations toolbar.

When the editor first opens without an owner selected, it asks you to select a GameObject. Selecting `FirstBehaviorTree` replaces this empty state with the GameObject and its graph controls.

![The Behavior Designer Pro editor shows an empty graph with its inspector and Shared Variables panels.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-empty-editor.webp?v=7d9c1dcee8ac)

## Add the Tasks

1. Press **Space** over the graph and add **Sequence** from **Composites**.
2. Press **Space** again and add **Log** from **Actions**. Repeat so the graph has two Log Tasks.
3. Add **Wait** from **Actions**.
4. Connect the Start event to Sequence.
5. Connect the children beneath Sequence from left to right as the first Log, Wait, and second Log.

The Task selector can be searched by name. Clear an active filter if a known Task is missing from the results.

![The Behavior Designer Pro task selector is open to add a Composite task to the graph.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-add-task-selector.webp?v=9a54a0b9b365)

After Sequence is connected to Start, its missing-child error remains visible until at least one valid child is connected.

![A Sequence connected beneath Start reports an error until its required children are added.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-sequence-with-start.webp?v=019978f9844c)

Sequence runs its children from left to right and stops if a child fails. Both Log Tasks complete immediately; Wait remains Running for its configured duration.

## Configure the result

1. Select the left Log and set its message to `Behavior tree started`.
2. Select Wait and set its duration to `1` second.
3. Select the right Log and set its message to `Behavior tree finished`.
4. Open the Error Window from the status-bar error count or **Tools > Opsive > Behavior Designer > Error Window**.
5. Resolve every reported missing connection or invalid field.

Selecting a Task displays its fields in the Element Inspector. The gear menu resets the selected Task, while a field's watch icon shows its live value on the node.

![A selected Behavior Designer Pro node displays its editable fields in the Element Inspector.](https://opsive.com/wp-content/uploads/2026/08/bdp-overview-selected-node-inspector.webp?v=914f79b96748)

## Verify in Play Mode

1. Clear the Unity Console.
2. Enter Play Mode.
3. Keep the graph visible and watch the active highlight move from the first Log to Wait and then the second Log.
4. Confirm that the Console shows `Behavior tree started`, followed about one second later by `Behavior tree finished`.

The tree may finish too quickly to see both Log Tasks highlighted, but Wait should visibly report Running during the delay. The Error Window should be clean before Play Mode, and the Console should contain exactly the expected tutorial messages with no new exceptions.

## Make one controlled change

Change Wait to three seconds and test again. The message order should remain the same while the visible Running interval becomes longer. This verifies that the graph you edited, rather than a sample or another component, owns the runtime result.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| The editor shows no graph. | Confirm that `FirstBehaviorTree` is selected and owns a Behavior Tree component. | Select it from the operations toolbar or add the component again. |
| Sequence reports an error. | Check its Start connection and three child connections. | Connect Start to Sequence and order the children left to right. |
| The Console remains empty. | Check whether Play Mode is running, the component is enabled, and the first Log is enabled. | Enable the GameObject, component, and Tasks, then enter Play Mode again. |
| The second message appears immediately. | Check the Wait duration and child order. | Set Wait to `1` or more and place it between the Log Tasks. |
| A Task cannot be found. | Look for active selector filters or compiler errors. | Clear filters and resolve Console errors before reopening the selector. |

For additional diagnostics, use [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/).

## Continue learning

1. Read [Flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) to understand why Sequence continues after success and stops after failure.
2. Build [Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) to add a real decision and fallback.
3. Use [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) when two Tasks need the same target or value.
4. Use [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) when a complete branch should be shared by several agents.

---

<a id="page-behavior-designer-pro-getting-started-sample-scenes"></a>

# Sample Scenes

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/sample-scenes/)

Use the 15 sample scenes as a guided course rather than opening them in alphabetical order. Each scene demonstrates one behavior-tree idea in a working project context.

## Open a sample

1. Open **Tools > Opsive > Behavior Designer > Samples**.
2. Import or update the current sample content.
3. Confirm that every dependency on the selected card has a green check mark.
4. Select **Open Documentation** when it is available, then **Open Scene**.
5. Enter Play Mode and reproduce the observable result listed below before inspecting the tree.

![The Behavior Designer Pro Samples Hub lists imported sample cards with preview images, dependency status, and enabled Open Scene buttons.](https://opsive.com/wp-content/uploads/2026/08/bdp-getting-started-sample-hub.webp?v=9be6fda3471e)

## Recommended learning order

| Order | Sample | Level | What to observe | Continue with |
| --- | --- | --- | --- | --- |
| 1 | Event Branches | Beginner | An event branch reacts while the Start branch remains active. | [Events](https://opsive.com/support/documentation/behavior-designer-pro/events/) |
| 2 | Melee Combat | Beginner | Alternating Selector and Sequence branches choose combat behavior; two agents reuse one Subtree. | [Flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) and [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) |
| 3 | Conditional Aborts | Intermediate | A lower-priority branch is interrupted as soon as the enemy becomes visible. | [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) |
| 4 | Hide And Seek | Intermediate | Perception and distance conditions are reevaluated while patrol or chase is active. | [Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) |
| 5 | Events | Intermediate | A turret sends a global event and a medic sends a local event. | [Events](https://opsive.com/support/documentation/behavior-designer-pro/events/) |
| 6 | Subtrees | Intermediate | The same Subtree runs with different variable overrides on two sides of the scene. | [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) |
| 7 | Property Binding | Intermediate | A Shared Variable stays synchronized with a C# property. | [Property Binding](https://opsive.com/support/documentation/behavior-designer-pro/variables/property-binding/) |
| 8 | Save Load | Intermediate | Tree state, Transform data, and Animator state are restored from saved data. | [Save/Load](https://opsive.com/support/documentation/behavior-designer-pro/save-load/) |
| 9 | Animation Sync | Intermediate | NavMeshAgent direction drives Animator parameters outside the tree. | [Syncing Animations](https://opsive.com/support/documentation/behavior-designer-pro/syncing-animations/) |
| 10 | Persistent Scenes A and B | Intermediate | One behavior tree remains active while the project changes scenes. | [Save/Load](https://opsive.com/support/documentation/behavior-designer-pro/save-load/) |
| 11 | Utility Theory | Intermediate | Utility curves are reevaluated and the highest-valued branch is selected. | [Utility Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/utility-selector/) |
| 12 | Runtime Behavior | Advanced | A Subtree Reference is reevaluated and replaced at runtime. | [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) |
| 13 | Turn Based | Advanced | The tree is ticked only during the AI turn and stops after one decision. | [API](https://opsive.com/support/documentation/behavior-designer-pro/api/) |
| 14 | Entities | Advanced | Entity Tasks control a large swarm and a baked turret. | [Entity Baking](https://opsive.com/support/documentation/behavior-designer-pro/entity-baking/) |

Persistent Scenes A and B form one lesson, which is why 15 scene cards produce 14 rows in the learning order.

## Choose by goal

- **Understand tree traversal:** Event Branches, Melee Combat, and Conditional Aborts.
- **Build reactive AI:** Hide And Seek, Events, and Utility Theory.
- **Reuse behavior:** Subtrees and Runtime Behavior.
- **Connect Unity systems:** Animation Sync and Property Binding.
- **Preserve runtime state:** Save Load and Persistent Scenes A/B.
- **Scale or control execution manually:** Entities and Turn Based.

## Verify a sample before copying it

For every sample, first reproduce its described result without edits. Then select the active agent, open its tree, and identify the branch that produces the behavior. Copy only the graph pattern and the project-owned scripts or assets you understand; do not turn the imported sample folder into production content.

If a scene does not open or run, confirm its package checks, inspect the Console, and reimport the current sample version. Use [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/) after the scene loads and the issue is specific to tree execution.

---

<a id="page-behavior-designer-pro-getting-started-gameobject-or-entity-tasks"></a>

# GameObject or Entity Tasks

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/)

Choose GameObject Tasks for the first tree and most component-based projects. Choose Entity Tasks when the behavior already belongs in an ECS workflow or profiling shows that data-oriented execution is necessary at scale.

## What the Entities dependency does and does not require

Behavior Designer Pro requires Entities because its runtime traversal uses that package internally. This does not require your gameplay code, characters, or custom Tasks to use ECS.

Start with GameObject Tasks when you want to:

- reference GameObjects, Components, Animators, NavMeshAgents, or ordinary scene objects;
- call existing MonoBehaviour properties and methods;
- inspect Unity object references directly in the Element Inspector; or
- keep authoring cost low until profiling identifies a bottleneck.

Use Entity Tasks when you want to:

- read or write ECS component data;
- bake authoring data into entities;
- run the same behavior across many entities; or
- keep the behavior inside an existing data-oriented architecture.

## Compare the workflows

| Decision | GameObject Task | Entity Task |
| --- | --- | --- |
| Authoring cost | Component references configured in the Inspector | Authoring component, baking, and system setup |
| Primary data | GameObjects, Components, Shared Variables | Entities and ECS component data |
| Scene references | Direct or Shared Variable references | Authoring and baking workflow |
| Custom code route | [GameObject Task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/gameobject-task/) | [Entity Task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/entity-task/) |
| Runtime preparation | Behavior Tree component | Entity baking and entity-compatible Tasks |
| Best validation | Inspect the selected GameObject and active Tasks | Inspect baking, entity data, and active tree status |

The green border used by pure ECS Tasks identifies their execution capability; it is not an error and does not mean the surrounding tree must contain only Entity Tasks.

## Make the decision per behavior

A project may use GameObject behavior for a boss or player companion and Entity behavior for a large crowd. Choose according to data ownership and measured scale rather than converting every Task because Entities is installed.

[Entity Baking](https://opsive.com/support/documentation/behavior-designer-pro/entity-baking/) covers the authoring, baking, and spawning workflow that Entity Tasks require. [Performance](https://opsive.com/support/documentation/behavior-designer-pro/performance/) covers what each route actually costs at runtime.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| A familiar Component does not appear in an Entity Task. | The Task is using ECS data rather than a GameObject reference. | Use a GameObject Task or author the required ECS component and baking path. |
| The project has Entities installed but no ECS gameplay. | Entities is a Behavior Designer Pro runtime dependency. | Continue with GameObject Tasks; no gameplay conversion is required. |
| An Entity tree has no expected runtime data. | Check baking, SubScenes, entity components, and authoring references. | Follow [Entity Baking](https://opsive.com/support/documentation/behavior-designer-pro/entity-baking/) and verify the baked entity before debugging tree flow. |

---

<a id="page-behavior-designer-pro-getting-started-updating-and-migration"></a>

# Updating and Migration

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/updating-and-migration/)

Use this guide to update an existing Behavior Designer Pro project or adopt Behavior Designer Pro alongside the original Behavior Designer. The safest path is a staged migration with a recoverable baseline, a clean core-package checkpoint, and separate verification passes for graphs, custom Tasks, builds, add-ons, and integrations.

Behavior Designer and Behavior Designer Pro can coexist in the same Unity project. They use separate GUIDs, namespaces, editor data, and runtime data, so an existing project can leave stable Behavior Designer trees in place while new or performance-sensitive behavior moves to Behavior Designer Pro.

Behavior trees are not automatically converted between the products. Their serialized graphs and runtime implementations differ. Treat adopting Pro as a deliberate graph migration, not as an in-place package replacement.

## Choose the migration you are performing

| Starting point | Recommended route |
| --- | --- |
| An earlier Behavior Designer Pro 3 release | Update the core package on a recoverable branch, verify it alone, then update samples, add-ons, and integrations. |
| Original Behavior Designer in a mature project | Install Pro alongside the original package and migrate one tree at a time. Keep the original component and graph until the Pro replacement passes the same tests. |
| Original Behavior Designer in a small or early project | Rebuild the graphs in Pro, then port project-owned Tasks and validate the complete replacement before removing the original package. |
| A project moving to a newer Unity editor at the same time | Separate the changes when possible. First establish a working product baseline, then change either Unity or Behavior Designer Pro so a failure has one likely cause. |

The [Version Comparison](https://opsive.com/support/documentation/behavior-designer-pro/version-comparison/) covers architecture, platform, and feature differences. [Custom Task Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/task-migration/) maps the original Task API to the Pro API.

## Record a recoverable baseline

1. Commit or back up the complete Unity project, including `Packages`, `ProjectSettings`, graph assets, prefabs, scenes, project-owned Tasks, and any imported integration or add-on files.
2. Record the Unity editor version and the installed versions of Behavior Designer, Behavior Designer Pro, Graph Designer, Opsive Shared, add-ons, integrations, and the Entities packages.
3. Open the project before changing packages. Confirm that scripts compile, representative trees run, and a development build succeeds.
4. Save screenshots or notes for critical Shared Variable assignments, Subtree overrides, component references, and expected runtime branches.
5. Perform the migration in a project copy or source-control branch. Do not use the only copy of a production graph as the test asset.

This baseline is the rollback point and the comparison target. A backup created after a partial import is not a clean baseline.

## Update Behavior Designer Pro 3

1. Confirm that the Unity version is supported. Behavior Designer Pro requires Unity 2022.3.11 or newer. For Unity 6.3, use 6.3.5 or newer; Unity 6.3.0 through 6.3.4 cannot load the editor assembly correctly.
2. Resolve existing compiler errors before importing or changing the package. The `GRAPH_DESIGNER` scripting symbol is added automatically only when the editor can compile.
3. Update the Behavior Designer Pro core package and its required Opsive dependencies without importing optional add-ons, integrations, or samples in the same step.
4. Let Unity finish compiling. Open **Tools > Opsive > Behavior Designer > Editor**, create a disposable tree, and reopen one existing tree.
5. If the product exposes **Tools > Opsive > Behavior Designer > Upgrade Project Serialization**, commit or back up first, run it once, then review and save the resulting asset changes before continuing.
6. Open **Tools > Opsive > Behavior Designer > Samples**. Use **Update Samples** when the project contains sample content from an older Pro version; do not use an old sample folder as production content.
7. Update add-ons and integrations to releases intended for the installed Pro version. Add them one at a time and compile after each import.
8. Run the editor, Play Mode, and build checkpoints below before merging the update.

If the core package does not pass step 4, stop before adding optional content. Use [Import Errors](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/import-errors/) to resolve the compiler or Unity-version boundary first.

## Adopt Pro alongside the original Behavior Designer

The two products are intentionally separate. Installing Pro does not rewrite original Behavior Designer components, trees, variables, preferences, or runtime state.

For an incremental migration:

1. Keep the original Behavior Designer package and the existing tree on its current component.
2. Install Behavior Designer Pro and create a new Pro Behavior Tree on a disposable or duplicated agent.
3. Rebuild one representative graph. Recreate its Shared Variables, Subtrees, conditional-abort behavior, and event flow instead of copying serialized graph data.
4. Port only the custom Tasks that graph requires. Follow [Custom Task Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/task-migration/) for namespaces, attributes, generic Shared Variables, and lifecycle method changes.
5. Run the old and new implementations against the same scenario and compare their observable decisions, transitions, and side effects.
6. Move the Pro implementation onto the production agent only after it passes. Keep the original graph available for rollback until the complete feature is accepted.
7. Repeat by feature or agent. Remove the original package only when no scene, prefab, script, add-on, integration, or build target depends on it.

This route avoids an all-at-once graph rewrite. It also makes performance comparisons meaningful because each migrated behavior has an original baseline.

## Review serialized references after an update

Unity can preserve a serialized reference only while the receiving field remains compatible. When a release changes a Task field from a specific component type to a `GameObject`, or otherwise changes its serialized type, inspect that Task and reassign the intended object. Do not assume a graph that compiles retained every Inspector reference.

Review at least:

- Task fields that reference components, GameObjects, assets, or project-owned types;
- Shared Variable names, value types, scope, **Internal** state, and task assignments;
- Subtree assets and their parent-tree overrides;
- Start connections, conditional aborts, event branches, disabled Tasks, and Task delegates;
- custom Task scripts and Control Types; and
- add-on and integration Tasks that came from a separately downloaded package.

Open the Error Window after the serialization review. A graph with no compiler errors can still contain an unknown Task, a missing field assignment, or an invalid connection.

## Verify the migration

### Editor checkpoint

1. Restart Unity so the test includes a fresh domain reload.
2. Open a new graph, an existing graph, and a Subtree used by more than one agent.
3. Create, rename, reorder, assign, and delete a disposable Shared Variable. Save, close, and reopen the project and confirm that its name, type, scope, and task assignment persist.
4. Open the Error Window and resolve every new graph error.
5. Save the project and review the source-control diff. Expect intentional package and serialization changes; investigate unrelated prefab, scene, or graph churn.

### Play Mode checkpoint

1. Run a small tree and one production-sized tree.
2. Confirm that the expected branch runs, conditional aborts reevaluate, events arrive once, and Subtree overrides use the intended values.
3. Test at least two agents that share the same Subtree asset. Graph-scoped runtime values should remain local to each Behavior Tree component.
4. Exercise stop, disable, re-enable, scene change, pooling, and save/load flows used by the project.
5. Profile the representative scenario before and after the migration instead of assuming a package update changed performance in one direction.

### Build checkpoint

1. Make a development build for every supported backend or platform affected by Burst, Entities, managed stripping, or platform-specific integrations.
2. Start the build outside the editor and run the same representative behavior.
3. Treat a successful editor Play Mode run and a successful player build as separate requirements.

Behavior Designer Pro does not support WebGL because of its Burst-based runtime. Keep an original Behavior Designer implementation or choose another supported runtime when WebGL remains a project requirement.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Add-on scripts cannot find Behavior Tree types and `GRAPH_DESIGNER` is missing | The project had compiler errors when the core package or add-on was imported | Remove or isolate the optional add-on, fix the first compiler error, and let the core package add the symbol. Add the symbol manually only after confirming that the core packages are present. |
| Opening or interacting with the graph throws an `EventModifiers` `TypeLoadException` | Unity is 6.3.0 through 6.3.4 | Update Unity 6.3 to 6.3.5 or newer. See [Import Errors](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/import-errors/). |
| Existing graphs open but some Task references are empty | A serialized field type changed or an optional Task package is missing | Restore the matching add-on or integration, then reassign fields whose new type is not serialization-compatible with the old field. |
| The editor works until samples, an add-on, or an integration is imported | Optional content targets a different product release or has an unmet dependency | Return to the clean core checkpoint and import a matching release only after its dependencies compile. |
| An original Behavior Designer graph does not appear in Pro | The products use different graph formats and do not auto-convert | Keep the original package while rebuilding the graph in Pro. Port project-owned Tasks separately. |
| Shared Variable names or assignments do not survive reopening | Confirm the installed Pro version, whether a Subtree is assigned, and whether the asset remains reproducibly affected after restart | Update to the current release, preserve the affected graph or Subtree in version control, and send the smallest reproducible asset to support rather than rebuilding the only copy. |
| Two agents appear to share a Graph variable through a Subtree | Runtime ownership and pooling setup | Assign the same Subtree asset directly to separate Behavior Tree components. If using the pooling API, give every concurrently running component its own deserialized pooled instance. See [Scope](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/) and [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/). |
| A player build fails although the editor runs | Build-only assembly, stripping, Burst, Entities, or platform restrictions | Diagnose the first build error, verify the target platform is supported, and retest with optional integrations removed from the checkpoint. |

## Related pages

- [Import Errors](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/import-errors/) covers the scripting-symbol and Unity 6.3 assembly failures.
- [Custom Task Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/task-migration/) ports original Behavior Designer Tasks to Pro.
- [Version Comparison](https://opsive.com/support/documentation/behavior-designer-pro/version-comparison/) compares requirements, architecture, platforms, and features.
- [Scope](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/) explains runtime ownership and the Graph, GameObject, Scene, Project, Internal, and Dynamic choices.
- [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) covers direct asset reuse, variable overrides, reevaluation, and pooling.
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/) traces graph validation and runtime execution problems.

---

<a id="page-behavior-designer-pro-getting-started-import-errors"></a>

# Import Errors

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/import-errors/)

In most cases you will not receive any import errors after importing Behavior Designer Pro. However, there are two common situations where you may receive an import error.

## Graph Designer Definition

Behavior Designer Pro will not compile correctly if you import or switch platforms while the project already has compiler errors. A common situation is that one of the Behavior Designer Pro add-ons is imported before Behavior Designer Pro itself. In this situation you'll receive compiler errors similar to the output below even though Behavior Designer Pro is in your project.

```csharp
Assets\Opsive\BehaviorDesigner\Add-Ons\Shared\Demo\Scripts\ScenarioSelector.cs(91,16): error CS0246: The type or namespace name 'BehaviorTree' could not be found (are you missing a using directive or an assembly reference?)
```

The reason for this is because the GRAPH\_DESIGNER scripting symbol hasn't been defined. This symbol gets added automatically but it cannot if there are compiler errors within the project. To fix you can either fix the compiler errors (such as by removing the add-ons) or by adding the GRAPH\_DESIGNER symbol to the [Player Settings](https://docs.unity3d.com/Manual/class-PlayerSettings.html):

![Unity Player settings include GRAPH_DESIGNER in the Scripting Define Symbols list.](https://opsive.com/wp-content/uploads/2026/08/bdp-import-errors-graph-designer-symbol.webp?v=a702aa95af48)

## Unity 6.3.0-6.3.4 TypeTypeLoad Exception

If you are running Unity 6.3.0 - 6.3.4 and open the Behavior Designer Pro editor you'll receive this exception:

```csharp
TypeLoadException: Could not resolve type with token 010000d3 from typeref (expected class 'UnityEngine.EventModifiers' in assembly 'UnityEngine.IMGUIModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null')
Opsive.GraphDesigner.Editor.Views.GraphView.OnGeometryChanged (UnityEngine.UIElements.GeometryChangedEvent c) (at <bd9cf0b0ba5a4f9a855802b1ee8dd9d0>:0)
UnityEngine.UIElements.EventCallbackFunctor`1[TEventType].Invoke (UnityEngine.UIElements.EventBase evt) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.EventCallbackRegistry+DynamicCallbackList.Invoke (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.BaseVisualElementPanel panel, UnityEngine.UIElements.VisualElement target) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.EventDispatchUtilities.HandleEvent_BubbleUpCallbacks (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.BaseVisualElementPanel panel, UnityEngine.UIElements.VisualElement element) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.EventDispatchUtilities.HandleEventAtTargetAndDefaultPhase (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.BaseVisualElementPanel panel, UnityEngine.UIElements.VisualElement target) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.EventDispatchUtilities.SendEventDirectlyToTarget (UnityEngine.UIElements.EventBase evt, UnityEngine.UIElements.BaseVisualElementPanel panel, UnityEngine.UIElements.VisualElement target) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.VisualTreeLayoutUpdater.DispatchChangeEvents (System.Collections.Generic.List`1[T] changeEvents, System.Int32 currentLayoutPass) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.VisualTreeLayoutUpdater.Update () (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.VisualTreeUpdater.UpdateVisualTreePhase (UnityEngine.UIElements.VisualTreeUpdatePhase phase) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.Panel.UpdateForRepaint () (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEditor.UIElements.EditorPanel.UpdateForRepaint () (at <9a6866749bf64829b050cb97017b2ca9>:0)
UnityEngine.UIElements.Panel.Repaint (UnityEngine.Event e) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.UIElementsUtility.DoDispatch (UnityEngine.UIElements.BaseVisualElementPanel panel) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.UIElementsUtility.UnityEngine.UIElements.IUIElementsUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr, System.Boolean& eventHandled) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.UIEventRegistration.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.UIElements.UIEventRegistration+<>c.<.cctor>b__1_2 (System.Int32 i, System.IntPtr ptr) (at <0bcb90c459a2413a94634a44aeb1d754>:0)
UnityEngine.GUIUtility.ProcessEvent (System.Int32 instanceID, System.IntPtr nativeEventPtr, System.Boolean& result) (at <b589a158f82a4d0383d140f349b608e5>:0)
```

This is due to the Unity 6.3.0 - 6.3.4 assembly reference changing from prior versions. Unity fixed this in version 6.3.5. As a result if you are running Unity 6.3 you must use Unity 6.3.5 (or later).

## Related pages

- [Updating and Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/updating-and-migration/) provides the complete staged update workflow and verification checkpoints.
- [Custom Task Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/task-migration/) maps original Behavior Designer Task code to Behavior Designer Pro.
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/) starts after the project compiles and a graph opens but does not run as expected.

---

<a id="page-behavior-designer-pro-getting-started-task-migration"></a>

# Custom Task Migration

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/task-migration/)

Behavior trees authored in Behavior Designer version 1 cannot be converted to Behavior Designer Pro, but custom Tasks port with a contained set of changes. This page maps the version 1 API onto its Behavior Designer Pro equivalent.

## Review the original task

A representative version 1 Action:

```csharp
using UnityEngine;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using Tooltip = BehaviorDesigner.Runtime.Tasks.TooltipAttribute;

namespace MyNamespace
{
    [TaskCategory("Common")]
    [TaskIcon("Assets/MyIcon.png")]
    [TaskDescription("Logs to the console.")]
    public class MyTask : Action
    {
        [Tooltip("Text to output to the log")]
        public SharedString text;

        public override TaskStatus OnUpdate()
        {
            Debug.Log(text.Value);
            return TaskStatus.Success;
        }

        public override void OnReset()
        {
            // Reset the properties back to their original values
            text = "";
        }
    }
}
```

## Update namespaces

`BehaviorDesigner.Runtime` no longer exists. Its contents are split across the Behavior Designer and Graph Designer packages:

| Namespace | Contains |
| --- | --- |
| `Opsive.BehaviorDesigner.Runtime.Tasks` | The `TaskStatus` definition. |
| `Opsive.BehaviorDesigner.Runtime.Tasks.Actions` / `.Conditionals` | The parent `Action` and `Conditional` classes. |
| `Opsive.GraphDesigner.Runtime` | The node attributes. |
| `Opsive.GraphDesigner.Runtime.Variables` | The Shared Variable system. |

## Update attributes

| Version 1 | Behavior Designer Pro |
| --- | --- |
| `TaskIcon` | `NodeIcon`. Accepts an asset path or an asset GUID, and an optional second value used as the light-theme icon. |
| `TaskDescription` | `Opsive.Shared.Utility.Description`. |
| `TaskCategory` | `Opsive.Shared.Utility.Category`. |
| `HelpURL` | No longer used. |
| `Tooltip` | Unity's own `Tooltip` attribute. The version 1 alias is no longer required. |

`NodeDescription` also exists in `Opsive.GraphDesigner.Runtime` but is deprecated. Use `Opsive.Shared.Utility.Description` for new and migrated Tasks; it is what the included Tasks use.

## Update variables and method names

- **Shared Variables are generic.** Purpose-built types such as `SharedString` are no longer needed — declare `SharedVariable<string>` instead.
- **`OnReset` is now `Reset`.**

## Use the Behavior Designer Pro task

The same Task after migration:

```csharp
using UnityEngine;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using Opsive.GraphDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;

namespace MyNamespace
{
    [Opsive.Shared.Utility.Category("Common")]
    [NodeIcon("Assets/MyIcon.png")]
    [Opsive.Shared.Utility.Description("Logs to the console.")]
    public class MyTask : Action
    {
        [Tooltip("Text to output to the log")]
        [SerializeField] protected SharedVariable<string> m_Text;

        public override TaskStatus OnUpdate()
        {
            Debug.Log(m_Text.Value);
            return TaskStatus.Success;
        }

        public override void Reset()
        {
            // Reset the properties back to their original values
            m_Text = string.Empty;
        }
    }
}
```

The included Tasks declare their fields as `[SerializeField] protected` with an `m_` prefix rather than as public fields. Either form serializes; the convention above matches the rest of the package.

## Related pages

- [New Tasks](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/) for the full authoring reference.
- [GameObject Task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/gameobject-task/) for the component-based route.
- [Version Comparison](https://opsive.com/support/documentation/behavior-designer-pro/version-comparison/) for the product-level differences.

---

<a id="page-behavior-designer-pro-concepts"></a>

# Concepts

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/)

Behavior Designer concepts explain how a tree makes decisions, shares data, and combines reusable tasks into readable gameplay logic.

## Learn how a tree works

Start with [What Is a Behavior Tree?](https://opsive.com/support/documentation/behavior-designer-pro/concepts/what-is-a-behavior-tree/), then use [Flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) to understand traversal, task status, and the difference between sequential and alternative branches. [Blackboard](https://opsive.com/support/documentation/behavior-designer-pro/concepts/blackboard/) explains how Shared Variables pass information between tasks without tightly coupling them.

## Build with tasks and examples

[Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/) lists every native task and provides deeper guides for the task types that benefit from an editor workflow or runtime example. [Common Behaviors](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/) shows how several tasks fit together for outcomes such as wandering, patrolling, chasing, retrying, or reacting to an event.

---

<a id="page-behavior-designer-pro-concepts-what-is-a-behavior-tree"></a>

# What is a Behavior Tree?

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/what-is-a-behavior-tree/)

Behavior Trees are a decision-making technique commonly used in games to select actions based on conditions and priorities. They are especially well suited for reactive AI and complex gameplay logic that must continuously adapt to changing situations.

Behavior Trees first gained widespread attention after their use in [Halo 2](http://www.gamasutra.com/view/feature/130663/gdc_2005_proceeding_handling_.php), and they have since become a cornerstone of modern game AI. They combine ideas from several AI techniques, including hierarchical state machines, scheduling, planning, and action execution. One of their main advantages is that they are easy to understand and author using a visual editor, making complex decision logic easier to design and maintain.

<iframe width="100%" height="600" src="https://www.youtube.com/embed/6VBCXvfNlCM?rel=0&amp;showinfo=0" title="What is a behavior tree video" loading="lazy" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

If the embedded player is unavailable, [watch What Is a Behavior Tree? on YouTube](https://www.youtube.com/watch?v=6VBCXvfNlCM).

## Decision-making with Tasks

At their core, Behavior Trees are built from a collection of interconnected tasks arranged in a hierarchical structure. These tasks represent both the logic that checks conditions and the actions that an agent can perform.

Some tasks perform actions such as moving, attacking, or playing an animation. Others evaluate conditions such as whether an enemy can see the player or whether a target is within range. Additional tasks control the flow of execution by determining which tasks run next based on success or failure. Formally, these are categorized as action, conditional, composite, and decorator tasks, but the key idea is that they work together to model decision-making logic.

## How behavior trees execute

The [flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) page goes into more details, but behavior trees evaluate from top to bottom and left to right, moving through tasks based on whether each task succeeds or fails. Consider a simple tree that includes the following logic:

![A behavior tree connects a root composite to ordered action and conditional branches.](https://opsive.com/wp-content/uploads/2026/08/bdp-what-is-a-behavior-tree-structure.webp?v=4f52a0f08d05)

This is a simple behavior tree that packs a lot of functionality. An agent first checks whether it can see the player. If the player cannot be seen, the check fails and the tree moves to an alternative behavior, such as patrolling. If the player is seen, the tree continues into a sequence that causes the agent to seek the player and then attack.

Failure generally means “try another option,” while success allows execution to continue along the current branch. This structure allows agents to naturally prioritize behaviors and fall back to safer or simpler actions when higher-priority behaviors are not possible.

## Rapid iteration with visual editing

One of the biggest strengths of Behavior Trees is how naturally they map to a visual graph. Instead of writing long chains of nested conditionals, tasks can be rearranged, swapped, or extended visually. For example, if you want the agent to start seeking the player when they are within a certain distance rather than when they are visible, you can simply replace a **Can See Object** condition with a **Within Distance** condition.

![A modified behavior tree rearranges the same modular tasks into a different decision order.](https://opsive.com/wp-content/uploads/2026/08/bdp-what-is-a-behavior-tree-modified-structure.webp?v=13bdcc9dcfcb)

This small change instantly alters the decision logic without restructuring the entire system.

## Real-time debugging and inspection

Behavior trees also have an advantage during debugging - during runtime you can see the active task as well as inspect the values.

![A running behavior tree highlights the active branch and displays each task status.](https://opsive.com/wp-content/uploads/2026/08/bdp-what-is-a-behavior-tree-running.webp?v=2d1b7e83352b)

During runtime you can visually see which task is currently active, observe execution flow as it moves through the tree, and inspect or modify variable values in real time. The active task is highlighted, and each task displays its execution status, making it easy to understand exactly why a particular behavior is occurring. This visibility greatly reduces the time needed to diagnose and refine complex AI logic. The visual editor and debugger are the most prevalent advantages of behavior trees, and there are many other features that make behavior trees the cornerstone of AI.

[Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) includes a runtime state that makes an interruption visible, while [Choose the Highest-Priority Need](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/highest-priority-need/) shows values expanding on evaluator nodes during Play Mode.

## Where behavior trees excel

Behavior Trees work best for systems that require:

-   Continuous decision-making
-   Priority-based behavior selection
-   Reactive responses to changing conditions
-   Complex branching logic

They are particularly effective for AI characters that must constantly evaluate their environment and choose between multiple possible actions.

## Behavior trees in Behavior Designer Pro

Behavior Designer Pro packages these concepts into a visual editor and flexible API. It uses DOTS internally, but you do not need prior DOTS experience to build behavior with GameObject Tasks. The package includes 15 sample scenes, and the [Sample Scenes](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/sample-scenes/) page organizes them by outcome, difficulty, and dependency. Create project-specific behavior with [New Tasks](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/) when the built-in Task catalog does not cover the required gameplay.

## Continue

Start with [Your First Behavior Tree](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/first-behavior-tree/), then use [Flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) to understand how success, failure, and running status control traversal. Apply the same building blocks to a complete scenario from [Common Behaviors](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/). The following are additional behavior-tree resources:

-   [Opsive Character Controller Integration Explanation](https://opsive.com/support/documentation/behavior-designer/integrations/opsive-character-controllers/)
-   [Deathmatch AI Kit Implementation Explanation](https://opsive.com/support/documentation/deathmatch-ai-kit/behavior-tree-overview/)
-   [Awesome AI made Easy with Behavior Designer](https://thestrangeschool.vhx.tv/checkout/easy-awesome-ai-with-behavior-designer/purchase)
-   [Unity AI Guide: Create a Autonomous Game with Adaptive NPCs](https://www.udemy.com/course/unity-ai-guide-create-a-autonomous-game-with-adaptive-npcs/?referralCode=895A0356AC20743582B5)
-   [Recreating the FALSE KNIGHT Boss Fight](https://www.youtube.com/watch?v=X7VwAGvAOIw)
-   [Practical Guide to AI in Unity](https://www.udemy.com/course/ai-in-unity/)

---

<a id="page-behavior-designer-pro-concepts-behavior-trees-vs-finite-state-machines"></a>

# Behavior Trees vs Finite State Machines

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/behavior-trees-vs-finite-state-machines/)

Use the structure that makes the behavior easiest to understand and change. Behavior trees and finite state machines can solve many of the same problems, but they make different parts of the design visible.

A behavior tree emphasizes the Tasks that should be tried, their order, and what happens when a Task succeeds, fails, or keeps running. A finite state machine emphasizes the mode that is active and the transitions that can change it. Neither structure is automatically better or more advanced.

## Decide from the question you are asking

- Choose a behavior tree when the main question is, "Which action should be tried now, and what should happen if it cannot run?"
- Choose a finite state machine when the main question is, "Which mode is active, and what can move the system to another mode?"
- Use both only when separating broad modes from decisions makes the overall system clearer.

## Choose a behavior tree for ordered decisions

![A behavior tree connects a root composite to ordered action and conditional branches.](https://opsive.com/wp-content/uploads/2026/08/bdp-what-is-a-behavior-tree-structure.webp?v=4f52a0f08d05)

Behavior trees work well when several actions may be valid and the system should evaluate them in a deliberate order. Selectors, Sequences, Conditionals, and fallback branches express priority and react to changing context, and [conditional aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) let a higher-priority branch preempt a running one.

Typical scenarios include choosing between AI actions, trying a preferred behavior before a fallback, and running a sequence of Tasks that may succeed or fail. A behavior tree is a good fit when evaluation order matters more than naming one persistent mode.

The tradeoff is that deeply nested branches can make long-lived modes and their entry or exit rules harder to see. If the design is primarily about remaining in a mode until a specific transition occurs, a finite state machine may communicate it more directly.

## Choose a finite state machine for explicit modes

![A finite state machine connects discrete gameplay states with directed transitions.](https://opsive.com/wp-content/uploads/2026/08/bdp-behavior-trees-vs-fsm-state-machine.webp?v=8e6a0369a428)

Finite state machines work well when behavior has stable modes and each change should follow an explicit transition. They make entry, exit, and the currently active state easy to identify.

Typical scenarios include animation modes, gameplay phases, boss fight stages, and characters that move between clear states such as Patrol, Chase, and Attack. A state machine also suits designs where the allowed transitions are themselves part of the design and should be visible in the graph.

The tradeoff is that a graph with many states and cross-connections becomes difficult to follow. In that situation, divide the behavior into smaller responsibilities rather than adding every decision to one state machine.

## State Designer terms in this comparison

The terms **State**, **Transition**, **Action**, and **Condition** describe finite-state-machine concepts used by [State Designer](https://opsive.com/support/documentation/state-designer/overview/). They are included here for comparison. Behavior Designer organizes its graphs around **Tasks**, **Composites**, **Conditionals**, **Decorators**, and the **Success**, **Failure**, or **Running** statuses; those terms describe different roles and are not interchangeable.

## Compare the design emphasis

| Decision point | Behavior Designer behavior tree | State Designer finite state machine |
| --- | --- | --- |
| What is most visible? | The Task path, evaluation order, and fallback behavior | The active state and its possible transitions |
| What changes execution? | The result of a Task and the behavior of its parent branch | A transition Condition or event |
| What stays stable? | The traversal rules while Tasks are evaluated or running | The current state until a transition is allowed |
| Common strength | Priority, sequence, and context-driven action selection | Structured phases and explicit mode changes |
| Common warning sign | Too many nested branches or unclear long-lived modes | Too many states or cross-connections |

## Use both when ownership stays clear

![A behavior tree coordinates parallel gameplay decisions above a finite state machine.](https://opsive.com/wp-content/uploads/2026/08/bdp-behavior-trees-vs-fsm-parallelism.webp?v=ff53c52664a4)

A behavior tree can choose a goal while a state machine manages that goal's explicit phases, or a state machine can manage broad modes such as Patrol, Combat, and Disabled while a behavior tree chooses actions within Combat. The useful boundary is the one that lets each graph answer one clear question without duplicating control over the same behavior.

The [State Designer integration](https://opsive.com/support/documentation/behavior-designer-pro/integrations/state-designer/) covers running both products in one project.

## Related concepts

- Start with [What Is a Behavior Tree?](https://opsive.com/support/documentation/behavior-designer-pro/concepts/what-is-a-behavior-tree/) for the basic execution model.
- Learn how [Flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) controls traversal through Success, Failure, and Running.
- Learn how [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/) divide into Action, Composite, Conditional, and Decorator roles.
- Learn how [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) make a running tree reactive.

---

<a id="page-behavior-designer-pro-concepts-flow"></a>

# Flow

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/)

A behavior tree is traversed from top to bottom and left to right. Every Task returns Running, Success, or Failure, and that status determines which Task is reached next. The examples below use **Return Status** Actions so the traversal order is visible without any gameplay logic; the numeric comment on each node is the order in which it is reached.

## Follow Sequence order

![A Sequence traverses four child tasks from left to right until one fails.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-sequence-order.webp?v=25574be6d2ef)

**Sequence** runs its children left to right and continues only while each child returns Success. Here the Tasks commented "2" and "3" return Success and the Task commented "4" returns Failure. Sequence stops at that Failure and passes the status to its parent. There is no parent, so the tree ends.

## Follow Selector order

![A Selector traverses four child tasks from left to right until one succeeds.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-selector-order.webp?v=778aa26e8dee)

**Selector** traverses in the same order but stops on the first child that returns Success rather than the first that returns Failure. Sequence and Selector are both Composite Tasks: Tasks that have several children and control the order and stopping rule for those children.

## Combine composite tasks

![A Selector and nested Sequence show the numbered order in which their tasks are traversed.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-selector-sequence.webp?v=e6e910e7770f)

The same rules apply to a larger tree. Tasks "1" through "4" are evaluated until "4" returns Failure, which stops the inner Sequence and passes Failure up to the Selector commented "1". A Selector does not stop on Failure, so traversal continues into the branch containing "6", "7", "8", and "9". Those all return Success, so the Sequence commented "6" completes and returns Success to the Selector.

## Gate a branch with a Conditional

![A Conditional controls whether its Sequence continues to the following Action.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-conditional-branch.webp?v=d8325675b037)

A Conditional Task inspects game state without modifying it and returns only Success or Failure. Here **Can Execute?** returns Failure, so its branch does not run and the top Selector moves to the right branch.

## Change a result with a Decorator

![A Return Success decorator changes its child result before traversal continues.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-decorator-result.webp?v=8979f30dc144)

A Decorator has a single child and modifies that child's result or how often it runs. **Return Success** forces its branch to report Success regardless of the child's own status, which satisfies the top Selector and prevents traversal from continuing to the right branch. The traversal rules are unchanged; only the reported status differs.

## Run branches in parallel

![A Parallel starts several child tasks at the same time.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-parallel-branches.webp?v=4414d7ab0d67)

**Parallel** is a Composite that starts all of its children at once. Each branch still runs top to bottom and left to right internally; the difference is that sibling branches advance during the same tick instead of waiting for one another.

## Reevaluate an important condition

![A failed Can Execute Conditional leaves the lower-priority Idle branch running.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-conditional-abort-initial.webp?v=1c0272936c35)

Many behavior tree implementations reevaluate the entire tree every frame. Behavior Designer instead uses conditional aborts to reevaluate selected Conditionals only. In this tree **Can Execute?** is reevaluated while the lower-priority branch runs, so the branch can start as soon as its status changes:

![Can Execute is reevaluated and interrupts the previously running Idle branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-conditional-abort-reevaluated.webp?v=5ad9b46e4866)

When **Can Execute?** changes status it issues an abort that stops **Idle**. Traversal appears to move right to left here, but only because the abort re-entered a higher-priority branch. See [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) for the abort types and their scopes, and [Performance](https://opsive.com/support/documentation/behavior-designer-pro/performance/) for what reevaluation costs.

## Change child order

![A Random Sequence chooses a non-sequential child execution order.](https://opsive.com/wp-content/uploads/2026/08/bdp-flow-random-sequence-order.webp?v=b058d8397293)

Composites control the order in which their children run, and some deliberately depart from strict left-to-right traversal. **Random Sequence** shuffles its child order when it starts, so the first child reached here is the second from the left. It applies the Sequence stopping rule to that shuffled order. **Random Selector** does the same for Selector.

## Continue

- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/) lists every native Task by type.
- [Common Behaviors](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/) assembles these rules into complete gameplay patterns.
- [Sample Scenes](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/sample-scenes/) orders the included scenes by the concept each one demonstrates.

---

<a id="page-behavior-designer-pro-concepts-blackboard"></a>

# Blackboard

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/blackboard/)

## Share values through the blackboard

The blackboard is a fancy way of saying variable list. Behavior trees use blackboards in order to share values between tasks. You can think of each task as a modular piece of functionality and the blackboard helps share data throughout the entire tree. In Behavior Designer your blackboard can look similar to:

![The Shared Variables panel lists six values available to tasks in the behavior tree.](https://opsive.com/wp-content/uploads/2026/08/bdp-blackboard-variable-list.webp?v=85590aac6341)

This blackboard has six variables that are shared across the tree:

-   1 GameObject array.
-   3 GameObjects.
-   2 Integers.

## Assign the same variable to several tasks

These variables can then be used by individual tasks by referencing them within the Task Inspector:

![A task field is assigned to the Gather Animation Index Shared Variable.](https://opsive.com/wp-content/uploads/2026/08/bdp-blackboard-variable-assignment.webp?v=70d7d968b24a)

With this setup the **Gather Animation Index** variable will be set to the inspected task. This will then allow the task to reference the same value across multiple tasks. For example, another task could look like:

![A second task writes to the same Gather Animation Index Shared Variable.](https://opsive.com/wp-content/uploads/2026/08/bdp-blackboard-shared-value.webp?v=1364cbd2d026)

## Keep task data synchronized

Because both tasks reference the same blackboard variable, they share the same value. When **Set Int** writes 5 to **Gather Animation Index**, the other task reads that same value. See [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) for details about creating, scoping, and accessing shared data.

---

<a id="page-behavior-designer-pro-concepts-tasks"></a>

# Tasks

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)

## Choose a task type

Tasks are the building blocks of a behavior tree. Choose the task category that matches the job, then combine tasks into a tree that communicates the agent's decisions from top to bottom.

- [Actions](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/) do work, such as waiting, moving, sending an event, or changing a value.
- [Conditionals](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/) answer a question with success or failure.
- [Composites](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/) choose the order in which multiple children run.
- [Decorators](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/) change how one child runs or reports its result.
- [Events](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/event/) start a branch in response to something that happened.

## Learn the editor workflows

Use [Stacked Action](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/stacked-action/) for grouped commands, standalone Action choices, and component methods that perform work. Use [Stacked Conditional](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/stacked-conditional/) for grouped questions, standalone Conditional choices, and component methods that return a boolean result.

### Find and add a task

Press Space in the graph for the pointer-based selector, or open **Tools > Opsive > Behavior Designer > Task Palette** for a dockable browser. Search by task name or metadata, browse categories, and use **Favorites** for recurring entries. **Recent** keeps the last selected entries up to the limit in Preferences; a limit of `0` hides it. **Documentation** opens the entry's documentation when its capability supplies a URL.

The selector's **Filter** menu contains:

- **Kind > Built-in / Codebase** for curated task types or tasks generated from project code;
- **Member > Methods / Get Properties / Set Properties**;
- **Scope > Static / Instance**;
- **Returns** for a required return type;
- **Requires** for an installed package or integration dependency; and
- **Clear Filters** to remove every active constraint.

The number beside **Filter** is the active-filter count. A capability without the selected metadata is excluded, so an instance-member filter also hides curated task types. The dockable Task Palette requires an open Behavior Designer editor because it adds the selection to that window's active graph.

### Use task and group menus

Right-click one or more tasks or a group:

| Command | Result |
| --- | --- |
| **Cut / Copy / Duplicate / Delete** | Applies the standard graph operation to the complete selection. Compatible internal connections are retained when copied. |
| **Enable / Disable** | Includes or excludes the selected task from execution. |
| **Collapse / Expand** | Hides or shows child content where the task supports it. |
| **Set Color** | Adds an editor-only organizational color. |
| **Replace** | Changes the task type and preserves compatible serialized fields. Review the Inspector because unsupported fields cannot transfer. |
| **Edit Script / Locate Script** | Opens the task source or selects it in the Project window. |
| **Connect To > _event_** | Connects a compatible task to an offered behavior-tree event. |
| **Save as Subtree** | Extracts a valid selected branch using the workflow on [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/). |

The node hover toolbar exposes Enable/Disable, Collapse/Expand, adding a connected task, and **More**. **More** provides Replace, Set Color, Edit Script, and Locate Script without opening the full context menu.

### Use the Element Inspector

Selecting a task displays its serialized fields plus its custom name and comment. The gear menu provides **Edit Script**, **Locate Script**, and **Reset**; Reset restores task defaults and clears the custom name and comment. A field's watch icon displays its live value on the node without changing runtime behavior.

Stacked task lists support Enable/Disable, drag reordering, **+** to add, and **-** to remove. Right-click a stacked row for **Replace**, **Rename**, **Edit Script**, **Locate Script**, **Copy**, **Paste**, **Duplicate**, or **Delete**. Copy, Duplicate, and Delete can use a multi-row selection; Replace and Rename require one row. Dragging a GameObject or Component onto a supported Inspector area opens a filtered selector and assigns that object to the new task. Serialized editing commands are disabled in Play Mode.

## Build a complete behavior

For complete trees that solve familiar AI problems, browse [Common Behaviors](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/).

---

<a id="page-behavior-designer-pro-concepts-tasks-action"></a>

# Actions

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/)

## Understand Actions

Actions do work. They can finish immediately, remain running over several updates, or fail when the requested work cannot be completed. Examples include waiting, moving toward a target, changing a variable, and sending an event.

## Choose a task layout

Most small GameObject Actions can share one Stacked Action node. A standalone Action gets its own node when its timing, connections, or configuration should remain visually separate. See [Stacked Action](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/stacked-action/) for the complete editor workflow.

## Control Actions with Conditionals

Actions are not reevaluated by Conditional Aborts. Put the changing question in a [Conditional](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/), then use that Conditional to control when an Action branch starts or stops.

## Browse the built-in Actions

The illustrated guides remain visible in the menu. The compact reference below covers every other built-in Action without creating hundreds of description-only pages.

## Quick reference

Description-only tasks are collected here so you can compare them without opening hundreds of separate menu entries. Search this page with your browser, or use the Behavior Tasks selector in the editor to filter by task name and capability.

| Task | Description |
| --- | --- |
| **Abs Float** | Calculates the absolute value of a float. |
| **Acos Float** | Calculates the arc cosine (inverse cosine) of a value. Returns angle in radians. |
| **Add Element** | Adds the element to the list. |
| **Add Game Object To Array** | Adds the GameObject to the array. |
| **Add Game Object To List** | Adds the GameObject to the list. |
| **Align To Surface** | Aligns the Transform to a surface normal using raycasting. Returns Finished when aligned. |
| **Angle To Direction** | Converts an angle (in degrees) to a Vector2 direction. |
| **Animate Parameter Over Time** | Animates a parameter value over time with easing curves. |
| **Animation Crossfade** | Crossfades between animations on the Animation component. Optionally waits until the animation completes. |
| **Animation Play** | Plays an animation on the Animation component. Optionally waits until the animation completes. |
| **Animator Crossfade** | Crossfades between animations with duration, layer, and normalized time control. Optionally waits until the animation completes. |
| **Animator Play** | Plays an animation on the Animator component. Optionally waits until the animation completes. |
| **Application Quit** | Quits the application. |
| **Apply Explosion Force** | Applies explosion force with radius, upward modifier, and force mode. |
| **Apply Force At Position** | Applies force at specific position with mode and optional relative direction. |
| **Apply Force With Mode** | Applies force to Rigidbody with mode selection and optional relative direction. |
| **Apply Force2 D** | Applies force to Rigidbody2D with mode selection and optional relative direction. |
| **Apply Torque2 D** | Applies torque (rotational force) to Rigidbody2D with mode selection. |
| **Asin Float** | Calculates the arc sine (inverse sine) of a value. Returns angle in radians. |
| **Atan Float** | Calculates the arc tangent (inverse tangent) of a value. Returns angle in radians. |
| **Atan2 Float** | Calculates the arc tangent of y/x. Returns angle in radians. Useful for converting direction to angle. |
| **Audio Source Pool** | Manages audio source pooling with automatic cleanup. |
| **Blend** | Blends animations with weight control and optional time offset. |
| **Bool Flip** | Flips the value of the boolean. |
| **Bool Operator** | Performs a math operation on the two booleans. |
| **Bounce Between Points** | Bounces the Transform between two points. Returns Finished when bounce count is reached (or runs continuously if infinite). |
| **Break** | Pauses the editor when executed. Equivalent to setting a breakpoint. Only works in the Unity Editor. |
| **Burst** | Bursts particles with count, cycles, and interval control. |
| **Calculate Path** | Calculates NavMesh path with distance and corner count. |
| **Camera Look At With Constraints** | Looks at target with rotation constraints and smoothing. |
| **Cast Shape** | Performs box/sphere/capsule cast with direction, distance, and hit detection. |
| **Ceil Float** | Rounds a float up to the nearest integer. |
| **Check Ground** | Checks ground beneath CharacterController with distance, normal, and surface detection. |
| **Clamp Float** | Clamps a float value between a minimum and maximum value. |
| **Clamp01 Float** | Clamps a float value between 0 and 1. |
| **Clear** | Clears all elements from the list. |
| **Clone Game Object** | Clones a GameObject with optional position offset, rotation offset, scale multiplier, and component copying. |
| **Compare Float** | Compares two float values. Returns -1 if first is less, 0 if equal, 1 if first is greater. |
| **Compare Tag And Layer** | Compares GameObject tag and layer with multiple conditions. |
| **Concatenate String** | Concatenate two strings and store the result. |
| **Convert Bool To Float** | Converts a boolean value to a float value (true = 1.0, false = 0.0). |
| **Convert Bool To Int** | Converts a boolean value to an integer value (true = 1, false = 0). |
| **Convert Bool To String** | Converts a boolean value to a string value. |
| **Convert Color To Vector3** | Converts a Color to a Vector3 (R, G, B components, alpha is dropped). |
| **Convert Color To Vector4** | Converts a Color to a Vector4 (R, G, B, A components). |
| **Convert Component To Game Object** | Gets the GameObject from a Component. |
| **Convert Float To Bool** | Converts a float value to a boolean value (0.0 = false, non-zero = true). |
| **Convert Float To Int** | Converts a float value to an integer value. |
| **Convert Float To String** | Converts a float value to a string value. |
| **Convert Float To Vector2** | Converts a float to a Vector2 by setting X, Y, or both components to the float value. |
| **Convert Float To Vector3** | Converts a float to a Vector3 by setting X, Y, Z, or all components to the float value. |
| **Convert Game Object To Transform** | Converts a GameObject value to a Transform value. |
| **Convert Int To Bool** | Converts an integer value to a boolean value (0 = false, non-zero = true). |
| **Convert Int To Float** | Converts an integer value to a float value. |
| **Convert Int To String** | Converts an integer value to a string value. |
| **Convert Int To Vector2** | Converts an int to a Vector2 by setting X, Y, or both components to the int value. |
| **Convert Int To Vector3** | Converts an int to a Vector3 by setting X, Y, Z, or all components to the int value. |
| **Convert Quaternion To Float** | Converts a Quaternion to a float. Can extract X, Y, Z, W, or angle around an axis. |
| **Convert Quaternion To Vector3** | Converts a Quaternion to a Vector3. Can extract Euler angles or direction vectors (Forward, Right, Up). |
| **Convert Quaternion To Vector4** | Converts a Quaternion to a Vector4 (X, Y, Z, W components). |
| **Convert String To Bool** | Converts a string value to a boolean value. |
| **Convert String To Float** | Converts a string value to a float value. |
| **Convert String To Int** | Converts a string value to an integer value. |
| **Convert Transform To Game Object** | Converts a Transform value to a GameObject value. |
| **Convert Vector2 To Float** | Converts a Vector2 to a float value. Can extract magnitude, squared magnitude, X, or Y component. |
| **Convert Vector2 To Vector2 Int** | Converts a Vector2 to a Vector2Int by rounding each component to the nearest integer. |
| **Convert Vector2 To Vector3** | Converts a Vector2 to a Vector3. The Z component can be specified. |
| **Convert Vector3 To Color** | Converts a Vector3 to a Color (X=R, Y=G, Z=B, Alpha=1). |
| **Convert Vector3 To Float** | Converts a Vector3 to a float value. Can extract magnitude, squared magnitude, X, Y, or Z component. |
| **Convert Vector3 To Quaternion** | Converts a Vector3 to a Quaternion. Can use LookRotation (direction to rotation) or Euler angles. |
| **Convert Vector3 To Vector2** | Converts a Vector3 to a Vector2 by dropping one component (X, Y, or Z). |
| **Convert Vector3 To Vector3 Int** | Converts a Vector3 to a Vector3Int by rounding each component to the nearest integer. |
| **Convert Vector4 To Color** | Converts a Vector4 to a Color (X=R, Y=G, Z=B, W=A). |
| **Copy Transform** | Copies transform values (position, rotation, scale) from another Transform. Can be instant or smooth. |
| **Cos Float** | Calculates the cosine of an angle in radians. |
| **Counter** | Increments or decrements a counter and finishes when the threshold is reached. |
| **Crossfade Audio** | Crossfades between two audio sources with duration and volume control. |
| **Delete Player Prefs Key** | Deletes a PlayerPrefs key. |
| **Deserialize From Player Prefs** | Deserializes object from PlayerPrefs with type checking. |
| **Destroy** | Destroys a GameObject after a delay. Can optionally release pooled objects back to their pool instead of destroying them. |
| **Detect Collisions** | Detects CharacterController collisions with filtering, tag/layer checks, and collision reporting. |
| **Direction To Angle** | Converts a Vector2 direction to an angle in degrees. |
| **Dont Destroy On Load** | Marks the target GameObject to persist across scenes. |
| **Dont Destroy On Load Objects** | Marks multiple GameObjects to persist across scenes. |
| **Drag Control** | Sets linear and angular drag with smooth transition. |
| **Draw Line** | Draws a line between two points in the Scene view. Only visible in the editor or when Gizmos are enabled. |
| **Draw Ray** | Draws a ray from a position in a direction in the Scene view. Only visible in the editor or when Gizmos are enabled. |
| **Enable Disable** | Enables/disables CharacterController with optional smooth property transition. |
| **Fade** | Fades particle system in/out with duration control. |
| **Fade In Out** | Fades a GameObject in or out using CanvasGroup or Renderer alpha. Returns Finished when fade is complete. |
| **Fade Material Alpha** | Fades material alpha with duration and optional shader property name. |
| **Find Game Object By Name** | Finds a GameObject by name with search scope options (children, parent, scene, siblings). Can include inactive GameObjects and search recursively. |
| **Find Game Object By Tag** | Finds GameObject(s) by tag. Can find closest to a position, find all with tag, or search in children only. |
| **Find Game Object By Tag And Layer** | Finds GameObjects matching both tag and layer mask. |
| **Find Game Object By Type** | Finds GameObject(s) that have a specific component type. Can find closest to a position, find all with type, or search in children only. |
| **Float Operator** | Performs a math operation on the two floats. |
| **Floor Float** | Rounds a float down to the nearest integer. |
| **Follow Path** | Follows a path of waypoints. Returns Finished when the path is complete. |
| **Follow Path2 D** | Follows a path of waypoints using 2D physics-based movement with collision avoidance and smooth rotation. Returns Finished when the path is complete. |
| **Follow Target** | Follows a target GameObject with configurable distance, offset, and smoothing. Can optionally look at the target. |
| **Freeze Constraints** | Freezes/unfreezes specific constraints with smooth transition. |
| **Game Object Move In Direction** | Moves the Transform in a direction with acceleration. |
| **Game Object Set Enabled** | Enables or disables the specified component. |
| **Get Bool Variable** | Gets the value of a bool SharedVariable by name. |
| **Get Bounds** | Gets CharacterController bounds (center, extents, min, max, size) with world/local space options. |
| **Get Child By Index** | Gets a child GameObject by index with bounds checking. Supports negative indices (e.g., -1 for last child). |
| **Get Child By Name** | Gets a child GameObject by name. Can search recursively and use partial name matching. |
| **Get Children** | Gets all children of a GameObject and stores them in a list. |
| **Get Color Variable** | Gets the value of a Color SharedVariable by name. |
| **Get Component** | Gets a component from a GameObject using the string component type name. |
| **Get Component In Children** | Gets a component from a GameObject's children using the string component type name. |
| **Get Component In Parent** | Gets a component from a GameObject's parent hierarchy using the string component type name. |
| **Get Count** | Gets the count of elements in the list. |
| **Get Element** | Selects the element from the list. |
| **Get Element Index** | Gets the index of the element within the list. |
| **Get Float Variable** | Gets the value of a float SharedVariable by name. |
| **Get Game Object Index In Array** | Gets the index of the specified GameObject within the array. Returns -1 if not found. |
| **Get Game Object Variable** | Gets the value of a GameObject SharedVariable by name. |
| **Get Int Variable** | Gets the value of an int SharedVariable by name. |
| **Get Layer Name** | Gets layer name from layer index with validation. |
| **Get List Variable** | Gets the value of a list SharedVariable by name. |
| **Get Mouse Position** | Gets the mouse position in screen coordinates. |
| **Get Or Add Component** | Gets a component from a GameObject, or adds it if it doesn't exist. Outputs the GameObject reference. |
| **Get Parent Game Object** | Gets the parent GameObject from a GameObject or Transform. Can traverse up multiple levels. |
| **Get Parent Transform** | Gets the parent Transform from a GameObject or Transform. Can traverse up multiple levels. |
| **Get Player Prefs Float** | Gets a PlayerPrefs float value. |
| **Get Player Prefs Int** | Gets a PlayerPrefs integer value. |
| **Get Player Prefs String** | Gets a PlayerPrefs string value. |
| **Get Resource Path** | Gets resource path with validation. |
| **Get Root Game Object** | Gets the root GameObject (topmost parent) from a GameObject or Transform. |
| **Get Root Transform** | Gets the root Transform (topmost parent) from a GameObject or Transform. |
| **Get State** | Gets CharacterController state (grounded, velocity, bounds, properties) with validation. |
| **Get String Variable** | Gets the value of a string SharedVariable by name. |
| **Get Transform Variable** | Gets the value of a Transform SharedVariable by name. |
| **Get Vector2 Variable** | Gets the value of a Vector2 SharedVariable by name. |
| **Get Vector3 Variable** | Gets the value of a Vector3 SharedVariable by name. |
| **Get Vector4 Variable** | Gets the value of a Vector4 SharedVariable by name. |
| **Idle** | Returns a TaskStatus of running. The task will only stop when interrupted or a conditional abort is triggered. |
| **Ignore Collision** | Ignores collision between two colliders with optional duration. |
| **Impulse** | Applies impulse with direction, force, and optional relative space. |
| **Insert Element** | Inserts the element at the specified list index. |
| **Instantiate** | Instantiates a GameObject prefab with configurable delay, position, rotation, scale (or prefab scale), and parent. Can optionally auto-destroy after a duration. |
| **Int Operator** | Performs a math operation on the two integers. |
| **Invoke Unity Event** | Invokes a UnityEvent and returns success. |
| **Lerp Float** | Linearly interpolates between two float values based on a t value (0 to 1). |
| **Lerp Transform** | Linearly interpolates the Transform between two Transforms based on a t value (0 to 1). Returns Finished when t >= 1. |
| **Load Additive Scenes** | Loads multiple scenes additively with progress tracking. |
| **Load JSON Data** | Loads data from JSON file with type validation and error handling. |
| **Load Multiple Resources** | Loads multiple resources with progress tracking. |
| **Load Player Prefs Multiple** | Loads multiple PlayerPrefs values with default value fallback. |
| **Load Resource Async** | Loads resource asynchronously with progress tracking. |
| **Load Resource With Fallback** | Loads resource with fallback option and type validation. |
| **Load Scene Async With Progress** | Loads scene asynchronously with progress tracking and activation control. |
| **Log** | A simple task which will output the specified text and return success. It can be used for debugging. |
| **Match Transform** | Smoothly matches another Transform's position, rotation, and/or scale. Returns Finished when matched. |
| **Material Control** | Sets physics material properties (friction, bounciness, combine mode). |
| **Material Property Animation** | Animates material property with easing curves. |
| **Max Vector2** | Returns the component-wise maximum of two Vector2 values. |
| **Max Vector3** | Returns the component-wise maximum of two Vector3 values. |
| **Min Vector2** | Returns the component-wise minimum of two Vector2 values. |
| **Min Vector3** | Returns the component-wise minimum of two Vector3 values. |
| **Mouse Raycast** | Casts a ray from the mouse position through the camera into the world to detect objects. |
| **Move** | Moves the character using the Unity CharacterController component based on the input vector. The x component controls horizontal movement and the y component controls forward movement. |
| **Move To Parent** | Moves a GameObject to a new parent with optional smooth movement. Returns Finished when moved. |
| **Move Towards Float** | Moves a float value towards a target value by a maximum delta amount. |
| **Move Towards2 D** | Moves Rigidbody2D towards target with force application and arrival detection. |
| **Negate Float** | Negates a float value (multiplies by -1). |
| **Obstacle Avoidance** | Controls obstacle avoidance with quality and radius settings. |
| **Orbit Around** | Orbits the Transform around a target GameObject or position at a specified radius and speed. |
| **Oscillate Position** | Oscillates the Transform's position between two points using sine, cosine, or ping-pong oscillation. |
| **Oscillate Rotation** | Oscillates the Transform's rotation between two rotations using sine, cosine, or ping-pong oscillation. |
| **Oscillate Scale** | Oscillates the Transform's scale between two values using sine, cosine, or ping-pong oscillation. |
| **Overlap Circle2 D** | Performs 2D overlap circle detection with layer mask, tag filter, and result processing. |
| **Overlap Shape** | Performs box/sphere/capsule overlap check with layer mask, tag filter, and result collection. |
| **Particles Set Velocity** | Sets particle velocity with mode selection and variation. |
| **Patrol** | Uses the NavMeshAgent to patrol through a set of waypoints. |
| **Perlin Noise2 D** | Generates 2D Perlin noise value at the specified coordinates. |
| **Perlin Noise3 D** | Generates 3D Perlin noise value at the specified coordinates. Note: Unity's Mathf.PerlinNoise only supports 2D, so this uses a workaround combining multiple 2D samples. |
| **Physics Based Movement2 D** | Moves towards a target using physics forces with acceleration and deceleration curves. Returns Finished when the target is reached. |
| **Physics Set Velocity** | Sets Rigidbody velocity with smooth interpolation and optional constraints. |
| **Ping Pong Float** | Ping-pongs a float value between 0 and a specified length. |
| **Play Audio Sequence** | Plays multiple audio clips in sequence with delays and volume control. |
| **Play Audio With Fade** | Plays audio clip with fade in/out, volume control, and optional looping. |
| **Play Random Audio** | Plays random audio from array with pitch/volume variation. |
| **Play With Parameters** | Plays particle system with emission rate, color, and lifetime control. |
| **Pool** | Manages particle system pooling with automatic cleanup. |
| **Preload Resources** | Preloads multiple resources with progress tracking. |
| **Random Element** | Sets a random element value from the list. |
| **Random Game Object From Array** | Sets a random GameObject value from the GameObject array. |
| **Random Game Object From List** | Sets a random GameObject value from the GameObject list. |
| **Random Inside Unit Circle** | Generates a random Vector2 inside a unit circle. |
| **Random Inside Unit Sphere** | Generates a random Vector3 inside a unit sphere. |
| **Random On Unit Circle** | Generates a random Vector2 on a unit circle (normalized). |
| **Random On Unit Sphere** | Generates a random Vector3 on a unit sphere (normalized). |
| **Random Vector2** | Generates a random Vector2 value within a specified range. |
| **Random Vector3** | Generates a random Vector3 value within a specified range. |
| **Rate Limiter** | Limits how often an action can execute by enforcing a minimum time between executions. |
| **Raycast** | Performs a raycast with layer mask, tag filter, and hit result processing. |
| **Raycast2 D** | Performs 2D raycast with layer mask, tag filter, and hit result processing. |
| **Remove Element** | Removes the element from the list. |
| **Remove Game Object From Array** | Removes the GameObject from the array. |
| **Remove Game Object From List** | Removes the GameObject from the list. |
| **Reparent Children** | Reparents all children from a source GameObject to a new parent. Can filter by name pattern or tag, and maintain world positions. |
| **Restart Behavior Tree** | Restarts the specified behavior tree. |
| **Return Status** | The return status task will immediately return sucess or failure. |
| **Rigidbody Move Towards** | Moves Rigidbody towards target with force application and arrival detection. |
| **Rotate** | Rotates the Transform based on a Vector2 input. The x component controls yaw (horizontal rotation) and the y component controls pitch (vertical rotation). |
| **Rotate Axis** | Rotates the Transform around a specified axis (X, Y, or Z) based on a float input value. Useful for character rotation (Y axis) or camera panning (X axis). |
| **Rotate Towards** | Rotates the Transform to face a direction or a GameObject. If a GameObject is supplied, the direction is from this transform towards the target's position. Returns Finished when aligned. |
| **Round Float** | Rounds a float to the nearest integer. |
| **Round To Nearest Float** | Rounds a float to the nearest multiple of a specified value. |
| **Save JSON Data** | Saves data to JSON file with path validation and error handling. |
| **Save Player Prefs Multiple** | Saves multiple PlayerPrefs values (int, float, string) in one action. |
| **Scale Over Time** | Scales the Transform to a target scale over time. Returns Finished when scaled. |
| **Scene Transition** | Manages scene transition with fade/loading screen and progress. |
| **Screen To World Point** | Converts a screen position to a world position using the camera. |
| **Select Game Object From Array** | Selects the GameObject from the array. |
| **Select Game Object From List** | Selects the GameObject from the list. |
| **Send Event** | Sends an event to the behavior tree, returns success after sending the event. |
| **Serialize To Player Prefs** | Serializes object to PlayerPrefs with key prefix. |
| **Set Active** | Sets a GameObject active or inactive after a delay. Returns Finished when the state is changed. |
| **Set Active Scene** | Sets active scene with validation and optional callback. |
| **Set Agent Speed** | Sets agent speed with smooth transition and acceleration. |
| **Set Angular Velocity** | Sets angular velocity with constraint checking. |
| **Set Animation Speed** | Sets animation speed with smooth transitions and optional curve. |
| **Set Bool** | Set the boolean value. |
| **Set Bool Variable** | Sets the value of a bool SharedVariable by name. |
| **Set Clipping Planes** | Sets camera near/far clipping planes with smooth transition. |
| **Set Collision Layers** | Sets CharacterController collision detection layers (include/exclude) with validation. |
| **Set Color** | Set the Color value. |
| **Set Color Over Time** | Changes particle color over time with gradient support. |
| **Set Color Variable** | Sets the value of a Color SharedVariable by name. |
| **Set Constraints** | Sets Rigidbody constraints with freeze position/rotation and interpolation mode. |
| **Set Destination** | Sets NavMesh destination with path validation and arrival detection. |
| **Set Element** | Sets the element at the specified list index. |
| **Set Emission Rate** | Sets emission rate with smooth transition. |
| **Set Enabled Fade** | Enables/disables renderer with optional fade transition. |
| **Set Field Of View** | Sets camera FOV with smooth transition and optional curve. |
| **Set Float** | Set the float value. |
| **Set Float Variable** | Sets the value of a float SharedVariable by name. |
| **Set Frame Rate** | Sets target frame rate with smooth transition. |
| **Set Game Object Variable** | Sets the value of a GameObject SharedVariable by name. |
| **Set Gravity** | Sets global or local gravity with smooth transition. |
| **Set Int** | Set the integer value. |
| **Set Int Variable** | Sets the value of an int SharedVariable by name. |
| **Set Light Properties** | Sets light color, intensity, range, and type with smooth transition. |
| **Set List Variable** | Sets the value of a list SharedVariable by name. |
| **Set Mass** | Sets mass with smooth transition and optional center of mass adjustment. |
| **Set Material Property Over Time** | Changes material property (color, float, vector) over time with curve. |
| **Set Material Texture** | Sets material texture with optional tiling and offset. |
| **Set Mixer Group** | Sets audio source to mixer group with volume and pitch control. |
| **Set Parameters** | Sets multiple animator parameters (float, int, bool, trigger) with validation. |
| **Set Player Prefs Float** | Sets a PlayerPrefs float value. |
| **Set Player Prefs Int** | Sets a PlayerPrefs integer value. |
| **Set Player Prefs String** | Sets a PlayerPrefs string value. |
| **Set Properties** | Sets multiple CharacterController properties (height, radius, center, slope limit, step offset) with smooth transitions. |
| **Set Render Queue** | Sets material render queue with validation. |
| **Set Rigidbody2 D Properties** | Sets multiple Rigidbody2D properties including mass, drag, angular drag, gravity scale, and constraints. |
| **Set Shadow Settings** | Sets shadow type, strength, and resolution with validation. |
| **Set State** | Sets animator state by name or hash with transition duration and layer selection. |
| **Set String** | Set the string value. |
| **Set String Variable** | Sets the value of a string SharedVariable by name. |
| **Set Subtree** | Sets the specified subtree. |
| **Set Tag And Layer** | Sets the tag and layer for the GameObject. |
| **Set Time Scale** | Sets time scale with smooth transition and duration. |
| **Set Transform** | Set the Transform value. |
| **Set Transform From Components** | Sets the Transform's position, rotation, and/or scale from separate component values. Only updates specified components. |
| **Set Transform Variable** | Sets the value of a Transform SharedVariable by name. |
| **Set Vector2** | Set the Vector2 value. |
| **Set Vector2 Variable** | Sets the value of a Vector2 SharedVariable by name. |
| **Set Vector3** | Set the Vector3 value. |
| **Set Vector3 Variable** | Sets the value of a Vector3 SharedVariable by name. |
| **Set Vector4** | Set the Vector4 value. |
| **Set Vector4 Variable** | Sets the value of a Vector4 SharedVariable by name. |
| **Set Velocity With Constraints** | Sets velocity with constraint checking and smooth interpolation. |
| **Set Velocity2 D** | Sets Rigidbody2D velocity with smooth interpolation and optional constraints. |
| **Set Viewport** | Sets camera viewport rect with smooth transition. |
| **Shake** | Shakes camera with intensity, duration, and curve control. |
| **Shared Wait** | Wait a specified amount of time. The task will return running until the task is done waiting. It will return success after the wait time has elapsed. Uses the GameObject workflow. |
| **Sign Float** | Returns the sign of a float value (-1 for negative, 0 for zero, 1 for positive). |
| **Signed Angle** | Calculates the signed angle (in degrees) between two Vector3 values. Returns negative for clockwise, positive for counter-clockwise. |
| **Sin Float** | Calculates the sine of an angle in radians. |
| **Slow Motion Effect** | Creates slow motion effect with time scale and duration. |
| **Smooth Camera Follow** | Smoothly follows target with offset, damping, and look-ahead. |
| **Smooth Damp Float** | Smoothly dampens a float value towards a target value over time. |
| **Smooth Look At** | Smoothly rotates the Transform to look at a target GameObject or position. Returns Finished when aligned. |
| **Smooth Move To** | Smoothly moves the Transform to a target position with acceleration and deceleration. Returns Finished when arrived. |
| **Spatial Audio Control** | Controls 3D audio positioning, min/max distance, and spatial blend. |
| **Spawn At Position** | Spawns a GameObject prefab at a specified position with full configuration. Can optionally auto-destroy after a duration. |
| **Sqrt Float** | Calculates the square root of a float value. |
| **Start Behavior Tree** | Starts the specified behavior tree. |
| **Stop Behavior Tree** | Stops the specified behavior tree. |
| **Subtree Reference** | Loads the specified subtrees in at runtime. |
| **Subtree Reference Selector** | Selects a subtree based on the index value. |
| **Sync Animator Layers** | Synchronizes multiple animator layers with weight and time control. |
| **Tan Float** | Calculates the tangent of an angle in radians. |
| **Teleport** | Teleports CharacterController to position with validation, ground snapping, and rotation. |
| **Time Based Delay** | Delays action based on unscaled time (works during pause). |
| **Time Scale Curve** | Changes time scale over time using animation curve. |
| **Toggle Active** | Toggles a GameObject's active state. Can optionally delay the toggle. Returns Finished when toggled. |
| **Trail Control** | Controls particle trail with width, color, and lifetime. |
| **Transform Look At With Constraints** | Looks at a target GameObject or position with pitch and yaw angle constraints. |
| **Transform Move In Direction** | Moves the Transform in a direction with acceleration. |
| **Transform Move Towards** | Move towards the target position using Vector3.MoveTowards. The object can pass through walls with this action. The position can either be specified by a transform or position. If the transform is specified then the position will not be used. |
| **Transition** | Transitions between positions/rotations with duration and easing. |
| **Unity Objects Set Enabled** | This task is obsolete. Use Variables.SetGameObject instead. |
| **Unity Objects Set Game Object** | This task is obsolete. Use Variables.SetGameObject instead. |
| **Unload Scene Async** | Unloads scene asynchronously with progress tracking. |
| **Unload Unused Assets** | Unloads unused assets with progress callback. |
| **Variables Set Game Object** | Set the GameObject value. |
| **Vector2 Angle** | Calculates the angle (in degrees) between two Vector2 values. |
| **Vector2 Distance** | Calculates the distance between two Vector2 points. |
| **Vector2 Dot** | Calculates the dot product of two Vector2 values. |
| **Vector2 Int Operator** | Performs a component-wise arithmetic operation on two Vector2Int values. |
| **Vector2 Lerp** | Linearly interpolates between two Vector2 values based on a t value (0 to 1). |
| **Vector2 Magnitude** | Calculates the magnitude (length) of a Vector2. |
| **Vector2 Normalized** | Returns the normalized (unit length) version of a Vector2. |
| **Vector2 Project** | Projects a Vector2 onto another Vector2. |
| **Vector2 Reflect** | Reflects a Vector2 off a normal vector. |
| **Vector2 Rotate** | Rotates a Vector2 by an angle in degrees. |
| **Vector2 Scale** | Scales a Vector2 by another Vector2 (component-wise multiplication). |
| **Vector2 Slerp** | Spherically interpolates between two Vector2 values based on a t value (0 to 1). |
| **Vector2 Sqr Distance** | Calculates the squared distance between two Vector2 points. Faster than distance (no square root). |
| **Vector3 Angle** | Calculates the angle (in degrees) between two Vector3 values. |
| **Vector3 Cross** | Calculates the cross product of two Vector3 values. |
| **Vector3 Distance** | Calculates the distance between two Vector3 points. |
| **Vector3 Dot** | Calculates the dot product of two Vector3 values. |
| **Vector3 Int Operator** | Performs a component-wise arithmetic operation on two Vector3Int values. |
| **Vector3 Lerp** | Linearly interpolates between two Vector3 values based on a t value (0 to 1). |
| **Vector3 Magnitude** | Calculates the magnitude (length) of a Vector3. |
| **Vector3 Normalized** | Returns the normalized (unit length) version of a Vector3. |
| **Vector3 Project** | Projects a Vector3 onto another Vector3. |
| **Vector3 Reflect** | Reflects a Vector3 off a normal vector. |
| **Vector3 Rotate** | Rotates a Vector3 around an axis by an angle in degrees. |
| **Vector3 Scale** | Scales a Vector3 by another Vector3 (component-wise multiplication). |
| **Vector3 Slerp** | Spherically interpolates between two Vector3 values based on a t value (0 to 1). |
| **Vector3 Sqr Distance** | Calculates the squared distance between two Vector3 points. Faster than distance (no square root). |
| **Vector4 Operator** | Performs a component-wise arithmetic operation on two Vector4 values. |
| **Volume Over Time** | Smoothly changes audio volume over time with curve support. |
| **Wait** | Wait a specified amount of time. The task will return running until the task is done waiting. It will return success after the wait time has elapsed. |
| **Wait For Animation** | Waits until an animation completes. The action will return running until the animation finishes playing. |
| **Wait For Animator State** | Returns success as soon as the current Animator state ends. |
| **World To Screen Point** | Converts a world position to a screen position using the camera. |
| **Zoom** | Zooms camera with smooth interpolation and bounds checking. |

---

<a id="page-behavior-designer-pro-concepts-tasks-action-perform-interruption"></a>

# Perform Interruption

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/perform-interruption/)

Perform Interruption immediately stops one or more selected tasks. Use it when the tree should decide exactly when a running branch ends. A [Conditional Abort](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) is usually clearer when a changing condition alone controls that decision.

## Interrupting a parallel branch

![A Parallel runs Idle beside a branch that reaches Perform Interruption.](https://opsive.com/wp-content/uploads/2026/08/bdp-perform-interruption-parallel-tree.webp?v=e2be387ee39f)

The most common arrangement runs the long-lived task and the interrupting branch beneath a Parallel task. Select Perform Interruption, choose the target task in the Task Inspector, and confirm that the target highlights in orange.

![The Task Inspector identifies the task that Perform Interruption will stop.](https://opsive.com/wp-content/uploads/2026/08/bdp-perform-interruption-target-inspector.webp?v=7b6389348d24)

One Perform Interruption task can target multiple running tasks. Keep the targets close enough in the tree that the relationship is still understandable.

## Choosing the result

Enable **Interrupt Success** when the interrupted task should be treated as successful. Disable it when the interruption should propagate Failure to its parent.

![At runtime, the interrupted branch has stopped and Perform Interruption reports success.](https://opsive.com/wp-content/uploads/2026/08/bdp-perform-interruption-success-runtime.webp?v=af02aed0b9c2)

## Interrupting from an event branch

An event branch can interrupt a task even when the two branches do not share a Parallel parent:

![An event branch uses Perform Interruption to stop Idle on the Start branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-perform-interruption-event-tree.webp?v=ce5128aac055)

This is useful for explicit commands such as cancellation or damage reactions. [Timeout](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/timeout/) shows a timer-driven alternative.

## Used in common behaviors

- [Timeout](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/timeout/)

---

<a id="page-behavior-designer-pro-concepts-tasks-action-stacked-action"></a>

# Stacked Action

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/stacked-action/)

Use a Stacked Action to group short commands into one node while keeping meaningful phases and long-running work visible as standalone nodes.

![The Behavior Tasks selector lists tasks that can be added to the active tree.](https://opsive.com/wp-content/uploads/2026/08/bdp-taskobject-select-new-task-editor.webp?v=b3c4c7d610bc)

## Understand Action task choices

Many GameObject-facing Actions use the TaskObject model. TaskObject is not a separate node that you add: choose the Action that describes what the agent should do, then configure its GameObject, Component, constants, or Shared Variables.

Start with a built-in Action when it already describes the operation. Use a component method for a small command that already exists in project code. Create a custom Action when the operation has a multi-frame lifecycle, needs reusable validation, or deserves a clearer project-specific name.

## Create a Stacked Action

![A Stacked Action groups Face Target, Play Animation, and Spend Ammo in one node.](https://opsive.com/wp-content/uploads/2026/08/bdp-stacked-and-standalone-stacked-action-editor.webp?v=031b28d28b5e)

1. Open the Behavior Tasks selector and add **Stacked Action**.
2. Select the node and choose **Add Task** in the Task Inspector.
3. Add each built-in Action or compatible component method that belongs to the same visible step.
4. Drag rows to reorder them. Right-click a row to rename, replace, enable, disable, copy, duplicate, or remove it.
5. Choose **Sequence** when every Action must succeed in order. Choose **Selector** when the stack should try alternatives until one succeeds.

The stack stops at the first relevant Sequence failure or Selector success. A contained Action that returns Running keeps the Stacked Action active until that Action finishes or the branch is interrupted.

## Choose a standalone Action

![A standalone Wait for Door task has its own graph node and connection.](https://opsive.com/wp-content/uploads/2026/08/bdp-stacked-and-standalone-wait-node-editor.webp?v=552104a6db37)

Use a standalone node when the Action remains Running, needs a Decorator or separate connection, may be interrupted independently, or represents an important phase that should be visible at a glance. Wait, Subtree Reference, and event-related responses are common examples.

As a rule, group implementation details but keep decisions and meaningful phases visible. If a stack is difficult to debug, move one row to a standalone node temporarily so its runtime status can be inspected independently.

## Use a component method as an Action

A compatible Component method can become an Action without a separate task class. This is useful for a focused command such as `OpenDoor`, `PlayAlert`, or `SetDestination`.

1. Select a Stacked Action, or add a standalone Action.
2. Choose **Add Task** in the Task Inspector.
3. Find the Component type and select the method by its name and parameter list.
4. Assign the target GameObject. Leave it at **Self** only when the Component is on the same GameObject as the behavior tree.
5. Enter constants for branch-owned values, or select Shared Variables for values supplied by other tasks.

Behavior Designer selects the matching delegate task automatically. Each method parameter appears in the Inspector, and a compatible return value can be stored in a Shared Variable.

![The TransformPoint Action inspector accepts a local position and stores the returned World Point.](https://opsive.com/wp-content/uploads/2026/08/bdp-action-delegate-assign-parameter-editor.webp?v=698e063e745c)

For example, `FindCover(GameObject threat)` can read a Shared GameObject and store its returned position in a Shared Vector3. A later movement task can consume that result.

![At runtime, the Transform Point task and its Start node both show success.](https://opsive.com/wp-content/uploads/2026/08/bdp-action-delegate-return-value-runtime.webp?v=c2f792d6a0e9)

Keep a component-method Action small and predictable. A method that starts work lasting several updates is easier to understand as a custom Action with a visible Running state and an explicit interruption rule.

## Verify the workflow

In Play Mode, confirm the Action targets the intended GameObject, receives current Shared Variable values, and reaches the expected status. For a returned value, inspect the destination Shared Variable before the next Action reads it.

## Related pages

- [Actions](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/)
- [Stacked Conditional](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/stacked-conditional/)
- [Shared Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/)
- [Creating a GameObject Task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/gameobject-task/)

---

<a id="page-behavior-designer-pro-concepts-tasks-conditional"></a>

# Conditionals

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/)

## Understand Conditionals

Conditionals answer one question with success or failure: can the agent see the target, is health low, has an event arrived, or is a value inside a range? A conditional completes during the update in which it is checked; it does not remain running.

## Reevaluate a changing question

Conditionals are also the tasks that [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) reevaluate. This is what lets a patrol branch stop as soon as an enemy becomes visible, or a chase branch stop when sight is lost.

## Choose a task layout

Small GameObject Conditionals can share a Stacked Conditional node. Use a standalone Conditional when it needs its own connection or should be immediately visible in the tree. See [Stacked Conditional](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/stacked-conditional/).

## Quick reference

Description-only tasks are collected here so you can compare them without opening hundreds of separate menu entries. Search this page with your browser, or use the Behavior Tasks selector in the editor to filter by task name and capability.

| Task | Description |
| --- | --- |
| **Animation Is Animation Playing** | Checks if an animation is currently playing on the Animation component. |
| **Animator Is Animation Playing** | Checks if an animation is currently playing on the Animator. |
| **Bool Comparison** | Compares two boolean values. |
| **Compare Behavior Tree Status** | Checks if another behavior tree is in a specific status. |
| **Compare Layer** | Checks if a GameObject is on a specific layer using LayerMask. |
| **Compare Tag** | Checks if a GameObject has a specific tag. |
| **Counter** | Checks if a counter has reached a threshold. Supports greater than, less than, and equal to comparisons. |
| **Distance Comparison** | Compares the distance between two positions or GameObjects. |
| **Float Comparison** | Compares two float values. |
| **Float In Range** | Checks if a float value is within a min/max range. |
| **Game Object Comparison** | Compares two GameObject values. |
| **Has Entered Collision** | Returns success when a collision starts. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Entered Collision2 D** | Returns success when a 2D collision starts. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Entered Trigger** | Returns success when an object enters the trigger. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Entered Trigger2 D** | Returns success when an object enters the 2D trigger. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Exited Collision** | Returns success when a collision ends. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Exited Collision2 D** | Returns success when a 2D collision ends. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Exited Trigger** | Returns success when an object exits the trigger. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Exited Trigger2 D** | Returns success when an object exits the 2D trigger. This task will only receive the physics callback if it is being reevaluated (with a conditional abort or under a parallel task). |
| **Has Received Event** | Returns success as soon as the event specified by eventName has been received. |
| **Has Value** | Returns true if the specified variable has a value. |
| **Int Comparison** | Compares two integer values. |
| **Int In Range** | Checks if an integer value is within a min/max range. |
| **Is Behavior Tree Active** | Returns true if the specified behavior tree is active. |
| **Is Element In List** | Checks if an element is in the list. |
| **Is Element Not In List** | Checks if an element is not in the list. |
| **Is Empty** | Checks if the list is empty. |
| **Is Mouse Over Object** | Checks if the mouse is over a specific GameObject using a raycast from the camera. |
| **Is Not Empty** | Checks if the list is not empty. |
| **Is Not Null** | Checks if a SharedVariable value is not null. |
| **Is Null** | Checks if a SharedVariable value is null. |
| **Player Prefs Float Comparison** | Compares a PlayerPrefs float value with another value. |
| **Player Prefs Has Key** | Checks if a PlayerPrefs key exists. |
| **Player Prefs Int Comparison** | Compares a PlayerPrefs integer value with another value. |
| **Player Prefs String Comparison** | Compares a PlayerPrefs string value with another value. |
| **Random Probability** | The random probability task will return success when the random probability is below the succeed probability. It will otherwise return failure. |
| **Shared Random Probability** | The random probability task will return success when the random probability is below the succeed probability. It will otherwise return failure. |
| **String Comparison** | Compares two string values. |
| **Vector2 Comparison** | Compares two Vector2 values. |
| **Vector2 Int Comparison** | Compares two Vector2Int values. |
| **Vector3 Comparison** | Compares two Vector3 values. |
| **Vector3 Int Comparison** | Compares two Vector3Int values. |
| **Vector4 Comparison** | Compares two Vector4 values. |

---

<a id="page-behavior-designer-pro-concepts-tasks-conditional-stacked-conditional"></a>

# Stacked Conditional

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/stacked-conditional/)

Use a Stacked Conditional to group several short questions into one node. Keep a changing decision standalone when it needs its own connection or controls a Conditional Abort.

## Create a Stacked Conditional

1. Open the Behavior Tasks selector and add **Stacked Conditional**.
2. Select the node and choose **Add Task** in the Task Inspector.
3. Add each built-in Conditional or compatible boolean component method that belongs to the same decision.
4. Drag rows to reorder them. Right-click a row to rename, replace, enable, disable, copy, duplicate, or remove it.
5. Choose **Sequence** when every contained Conditional must succeed. Choose **Selector** when any one success should make the stack succeed.

A Sequence stops at the first failure. A Selector stops at the first success. Keep methods free of side effects because a Conditional may be reevaluated repeatedly.

## Choose a standalone Conditional

Use a standalone Conditional when its result should remain visible in the graph, when it needs a separate connection, or when a parent Composite reevaluates it for a [Conditional Abort](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/). Standalone placement makes its runtime status and abort relationship easier to inspect.

## Use a component method as a Conditional

A Component method that returns `bool` can become a Conditional. Use this for a focused question such as `CanSeeEnemy`, `HasAmmo`, or `IsDoorOpen`.

1. Select a Stacked Conditional, or add a standalone Conditional.
2. Choose **Add Task** and select a method that returns `bool`.
3. Assign the target GameObject and each parameter.
4. Place the Conditional in a Sequence, Selector, or branch with a Conditional Abort.

`true` becomes Success and `false` becomes Failure.

![The CompareTag Conditional inspector compares against Untagged and stores its boolean result.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-delegate-assign-parameter-editor.webp?v=6422b5d75d16)

Use a standalone Conditional when a changing result should interrupt another branch. Configure the parent Composite's Abort Type, then test both outcomes in Play Mode.

![At runtime, the Compare Tag task is centered beneath the Start node and both show success.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-delegate-result-runtime.webp?v=366815b2cff8)

## Verify the workflow

In Play Mode, confirm the Conditional targets the intended GameObject and receives current Shared Variable values. Change the input in both directions and confirm the expected success or failure. For a Conditional Abort, also confirm that the correct running branch is interrupted.

## Related pages

- [Conditionals](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/)
- [Stacked Action](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/stacked-action/)
- [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/)
- [Shared Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Creating a GameObject Task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/gameobject-task/)

---

<a id="page-behavior-designer-pro-concepts-tasks-composite"></a>

# Composites

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/)

## Choose a traversal rule

Composites are parent tasks that decide which child runs next. A Sequence works like "and": every child must succeed. A Selector works like "or": it tries alternatives until one succeeds. Parallel, priority, random, and utility variants provide other traversal strategies.

## Order the children

Connect children from left to right in the order the Composite should consider them. The Composite remains Running while an active child is Running and derives Success or Failure from its traversal rule.

## Compare the built-in Composites

Composites always have their own node. Use the pages below to compare each traversal rule, then see [Common Behaviors](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/) for complete trees that combine them.

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-selector"></a>

# Selector

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/)

## Try children until one succeeds

The **Selector** is a common Composite task that is similar to an "or" operation. It will return success as soon as one of its child tasks return success. If a child task returns failure then it will sequentially run the next child task. If no child task returns success then it will return failure.

![The first Selector child has failed and the second child has succeeded.](https://opsive.com/wp-content/uploads/2026/08/bdp-selector-second-child-success-runtime.webp?v=c963305fb8e3)

In this example the first **Return Status** task returned failure. Because of the failure the **Selector** moved onto the next child, which returned success. Because a child returned success the **Selector** stopped traversing and returned a status of success.

## Stop at the first Success

![The first Selector child succeeds, so the remaining children stay inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-selector-first-child-success-runtime.webp?v=951d2127ea1d)

In this example the first child task returned success so there was no need for the **Selector** to run the second of third tasks.

## Fail after every child fails

![Every Selector child and the Selector itself have finished with Failure.](https://opsive.com/wp-content/uploads/2026/08/bdp-selector-all-children-fail-runtime.webp?v=3f98f240c11e)

With this last example the **Selector** traversed every child task but no child returned success. Because of this the **Selector** returned a status of failure.

## Used in common behaviors

- [Attack with Cooldown](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/attack-with-cooldown/)
- [Fallback Strategies](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/fallback-strategies/)
- [Flee at Low Health](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/flee-at-low-health/)
- [Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/)
- [Retry with Delay](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/retry-with-delay/)
- [Search After Losing a Target](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/search-after-losing-target/)
- [Switch Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/switch-subtrees/)

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-sequence"></a>

# Sequence

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/)

## Run children until one fails

The **Sequence** task is similar to an "and" operation. It will return failure as soon as one of its child tasks return failure. If a child task returns success then it will sequentially run the next child task. If all child tasks return success then it will return success.

![The first Sequence child succeeds and the second child fails, stopping traversal.](https://opsive.com/wp-content/uploads/2026/08/bdp-sequence-second-child-failure-runtime.webp?v=177a120c0281)

In this example the **Return Status** task first returned success. Because of the success the **Sequence** task moved onto its next child, the middle **Return Status** task. This task returned failure and the **Sequence** task stopped traversing and returned a status of failure.

## Stop at the first Failure

![The first Sequence child fails, so the remaining children stay inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-sequence-first-child-failure-runtime.webp?v=3a199cbe5eb2)

In order for the **Sequence** task to traverse its children the child tasks must return a success status. The first **Return Status** task returned failure, thus the **Sequence** task stopped traversing its children and returned a failure status.

## Succeed after every child succeeds

![Every Sequence child and the Sequence itself have finished with Success.](https://opsive.com/wp-content/uploads/2026/08/bdp-sequence-all-children-succeed-runtime.webp?v=ef94bec3e27c)

In this example all of the children returned a success status so the **Sequence** task was able to traverse all of its children. The **Sequence** task returned a success status.

## Used in common behaviors

- [Attack with Cooldown](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/attack-with-cooldown/)
- [Fallback Strategies](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/fallback-strategies/)
- [Flee at Low Health](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/flee-at-low-health/)
- [Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/)
- [React to an Event](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/react-to-event/)
- [Search After Losing a Target](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/search-after-losing-target/)
- [Switch Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/switch-subtrees/)

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-parallel"></a>

# Parallel

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/parallel/)

## Run every child together

Similar to the **Sequence** task, the **Parallel** task will run each child task until a child task returns failure. The difference is that the parallel task will run all of its children tasks simultaneously versus running each task one at a time. Like the **Sequence** task, the **Parallel** task will return success once all of its children tasks have return success. If one tasks returns failure the **Parallel** task will end all of the child tasks and return failure.

![Two Parallel children remain running after another child has succeeded.](https://opsive.com/wp-content/uploads/2026/08/bdp-parallel-children-running.webp?v=4ef9a50d33c9)

The **Return Status** task returned a success status while the two **Idle** tasks are returning a running status. The **Parallel** task will continue to run until all tasks have completed with a success status or a single task returns failure.

## Stop when one child fails

![A failed child stops the other running children and makes the Parallel fail.](https://opsive.com/wp-content/uploads/2026/08/bdp-parallel-child-failure-runtime.webp?v=5d1420ec8012)

In this example the **Return Status** task returned a failure status. Because a child task returned failure the **Parallel** task will stop all of its children and return failure.

## Resolve mixed results

![The Parallel fails because one child failed even though another child succeeded.](https://opsive.com/wp-content/uploads/2026/08/bdp-parallel-mixed-results-runtime.webp?v=6d9fa54d0511)

The middle **Return Status** task returned success but the right **Return Status** returned failure. It only takes a single task to return failure and stop all of the child tasks.

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-parallel-selector"></a>

# Parallel Selector

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/parallel-selector/)

## Run alternatives together

Similar to the **Selector** task, the **Parallel Selector** task will return success as soon as a child task returns success. The **Parallel Selector** task will run all of its children tasks simultaneously versus running each task one at a time. If one task returns success the parallel selector task will end all of the child tasks and return success. If every child task returns failure then the parallel selector task will return failure.

![A Parallel Selector runs all three child tasks at the same time.](https://opsive.com/wp-content/uploads/2026/08/bdp-parallel-selector-children-running.webp?v=717fb50691e7)

The **Parallel Selector** task will run all children at the same time, similar to the **Parallel** task.

## Continue after one child fails

![One Parallel Selector child has failed while the remaining children continue running.](https://opsive.com/wp-content/uploads/2026/08/bdp-parallel-selector-child-failure-runtime.webp?v=6c8ac6a0e2bd)

The **Return Status** task returned a status of running. Unlike the **Parallel** task, if the child of a **Parallel Selector** task returns failure then the rest of the children will continue to execute.

## Stop when one child succeeds

![A successful child stops the other running children and makes the Parallel Selector succeed.](https://opsive.com/wp-content/uploads/2026/08/bdp-parallel-selector-child-success-runtime.webp?v=99e12c3c73d9)

The **Parallel Selector** task will return success as soon as a single child returns success. In this example the **Return Status** task returned success which aborts the two **Idle** tasks and the **Parallel Selector** then returns a status of success.

## Used in common behaviors

- [Timeout](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/timeout/)
- [Wander for a Limited Time](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/wander-for-a-limited-time/)

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-utility-selector"></a>

# Utility Selector

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/utility-selector/)

The **Utility Selector** task evaluates the child tasks using [Utility Theory AI](https://www.scaler.com/topics/artificial-intelligence-tutorial/utility-theory-in-artificial-intelligence/). The **Utility Selector** is based on the implementation suggested by the [Game AI Pro book](https://www.gameaipro.com/GameAIPro/GameAIPro_Chapter10_Building_Utility_Decisions_into_Your_Existing_Behavior_Tree.pdf). The task with the highest utility value will be selected and the existing running task will be aborted. The Utility Selector task reevaluates its children every tick.

![The Utility Selector runs the branch with the highest evaluator value.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-highest-utility-running.webp?v=6e2483e903ff)

The **Utility Variable Evaluate** returns a utility value based on a constant float value. In the example above the leftmost branch has a utility value of 1, middle has a value of 3, and rightmost has a utility value of 2. The middle branch is selected because it has the highest utility value.

![The highest-utility branch succeeds and the Utility Selector finishes with Success.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-highest-utility-success.webp?v=609493fbb5c2)

This is the same tree as the first image. The **Wait** task completed and return a status of success. The **Utility Selector** acts similar to the **Selector** task in that it will return success as soon as the first child returns success. Because the middle branch returned success the **Utility Selector** returned a success.

![The highest-utility branch has failed and the next-highest branch is running.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-fallback-running.webp?v=8bebd9a1638b)

This example is similar to the first tree, except instead of the middle branch returning success it returns failure. The middle branch executed first because of the utility value of 3, but because it returned failure the **Utility Selector** moved onto the next highest branch which is the rightmost branch.

![The next-highest utility branch succeeds after the preferred branch failed.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-fallback-success.webp?v=ea7850ff072a)

Continuing from the last image, the rightmost branch returns success after 1 second and because of that success the **Utility Selector** then returns success.

![All utility branches and the Utility Selector have finished with Failure.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-all-fail-runtime.webp?v=6d998dbad8ca)

Similar to the **Selector** task, if all of the children return failure then the **Utility Selector** will also return failure.

![The second branch runs because its current utility value is highest.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-second-branch-running.webp?v=452f911e1959)

The Utility Selector is a responsive task. In this screenshot the second branch is selected because it has the highest utility value of 3.

![The third branch takes over after its changing utility value becomes highest.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-third-branch-running.webp?v=a607df2fc89e)

Every tick the utility value of all of the branches update. The **Utility Curve Evaluator** will evaluate a curve based on the time elapsed. With each tick the utility value will update and after 10 seconds the third branch has a higher utility value than the second branch. The third branch aborts the second branch even though it hasn't completed because it has a higher utility value. This is the default functionality but on the **Utility Evaluator** task you can select **Block During Execution** which will prevent the branch from being aborted even if another branch returns a higher utility value.

![The first branch takes over after its changing utility value becomes highest.](https://opsive.com/wp-content/uploads/2026/08/bdp-utility-selector-first-branch-running.webp?v=ce176f9b8c34)

The utility value doesn't stop updating until the **Utility Selector** ends. The first branch aborts the third branch because its utility value eventually gets to be higher than the third branch.

## Utility Value

Behavior Designer includes two **Utility Evaluators**:

-   **Utility Variable Evaluator**: Returns a utility value based on a float SharedVariable.
-   **Utility Curve Evaluator**: Returns a utility value based on a curve.

If you want to return a different utility value based on another evaluator you can inherit the **Utility Evaluator** abstract class. The only method that you need to implement is the `GetUtilityValue` method:

```csharp
using Opsive.BehaviorDesigner.Runtime.Tasks.Decorators;

public class MyUtilityEvaluator : UtilityEvaluator
{
   /// <summary>
   /// Returns the utility of the decorator. The higher the utility the more likely the task will run next.
   /// </summary>
   /// <returns>The utility of the decorator.</returns>
   public override float GetUtilityValue() { return 5; }
}
```

The sample class overrides the `GetUtilityValue` and returns a constant 5 value.

## Used in common behaviors

- [Choose the Highest-Priority Need](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/highest-priority-need/)
- [Fallback Strategies](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/fallback-strategies/)

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-priority-selector"></a>

# Priority Selector

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/priority-selector/)

[//]: # (Generated by scripts/docgen. Do not edit this file manually.)

The Priority Selector task orders its children by their reported priority values and evaluates the highest-priority child first. It returns success as soon as a child succeeds, continues to the next child when one fails, and returns failure if every child fails.

## Use Priority Selector

Add this task from the **Composites** list and connect its children in the order they should be considered. The composite controls which child runs next and derives its own status from those children.

## Choosing the highest-priority branch

Each child starts with a Priority Variable Evaluator. The evaluator reports the value of its assigned Shared Variable, and the Priority Selector sorts the branches from highest to lowest before starting a child. The visual position of a branch does not determine its priority.

In Play Mode, each Priority Variable Evaluator expands to display its current `Value`. This is the value that the Priority Selector uses to order the branches, so the runtime label is useful for confirming why one branch was selected before another.

![A Priority Selector with three Priority Variable Evaluator branches, each leading to a Wait task.](https://opsive.com/wp-content/uploads/2026/08/bdp-priority-selector-highest-priority-editor.webp?v=61a2e4041e95)

In this example every branch can succeed. The selector starts the branch with the highest value and returns success when that branch's Wait task completes successfully; the lower-priority branches are not run.

## Trying the next priority after a failure

![At runtime, the highest-priority branch has failed and the next-highest branch is running.](https://opsive.com/wp-content/uploads/2026/08/bdp-priority-selector-fallback-running.webp?v=7c70e2d91d0a)

The right branch adds a Return Failure decorator around its Wait task. Its priority value is 3, so the selector starts it first. In the runtime screenshot, that branch's Wait has succeeded, Return Failure has converted the result to failure, and the priority-2 branch is now running. A later success ends the selector immediately.

## When every branch fails

![All three branches and their Priority Selector show settled failure, with Start inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-priority-selector-all-branches-failed.webp?v=dd348636153d)

Here every branch is wrapped by Return Failure. The runtime screenshot shows that each Wait succeeded, each decorator converted that success to failure, and the Priority Selector failed after exhausting all three branches.

## Creating a custom priority evaluator

Use the built-in Priority Variable Evaluator when a float Shared Variable already represents the priority. For a calculated priority, create a task that inherits `PriorityEvaluator` and override `GetPriorityValue()`. Higher values run before lower values.

```csharp
using Opsive.BehaviorDesigner.Runtime.Tasks.Decorators;
using Opsive.GraphDesigner.Runtime.Variables;
using UnityEngine;

public class LowHealthPriorityEvaluator : PriorityEvaluator
{
    [SerializeField] private SharedVariable<float> m_Health;

    public override float GetPriorityValue()
    {
        return 100f - m_Health.Value;
    }
}
```

Add the custom evaluator directly above the single child task or branch that it scores, in the same position as a Priority Variable Evaluator. This example gives a higher priority to a branch when health is lower. When the Priority Selector starts, it compares the evaluator values and tries the highest-priority branch first. In Play Mode, the custom evaluator also displays its current `Value` on the node.

## Related examples

- [Choose the Highest-Priority Need](/support/documentation/behavior-designer-pro/concepts/common-behaviors/highest-priority-need/)
- [Fallback Strategies](/support/documentation/behavior-designer-pro/concepts/common-behaviors/fallback-strategies/)

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-random-selector"></a>

# Random Selector

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/random-selector/)

[//]: # (Generated by scripts/docgen. Do not edit this file manually.)

The Random Selector task shuffles its children when execution begins, then evaluates them one at a time in that randomized order. It returns success as soon as a child succeeds, continues to the next child when one fails, and returns failure if every child fails.

## Use Random Selector

Add this task from the **Composites** list and connect its children in the order they should be considered. The composite controls which child runs next and derives its own status from those children.

## Choosing a random fallback order

Random Selector shuffles its children, then behaves like a Selector: it tries children until one succeeds and fails only when every child fails.

![A Random Selector offers three valid idle variation branches.](https://opsive.com/wp-content/uploads/2026/08/bdp-random-selector-tree-editor.webp?v=d0dee14dacb2)

Use it for interchangeable choices such as idle animations, patrol directions, or flavor responses. Every child should remain a valid outcome; do not put required safety or priority behavior behind a random order.

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-random-sequence"></a>

# Random Sequence

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/random-sequence/)

[//]: # (Generated by scripts/docgen. Do not edit this file manually.)

The Random Sequence task shuffles its children when execution begins, then evaluates them one at a time in that randomized order. It continues after each child succeeds, returns failure as soon as any child fails, and returns success after every child succeeds.

## Use Random Sequence

Add this task from the **Composites** list and connect its children in the order they should be considered. The composite controls which child runs next and derives its own status from those children.

## Varying an ordered routine

Random Sequence shuffles its children, then behaves like a Sequence: every child must succeed, and the first failure stops the composite.

![A Random Sequence contains three inspection steps that may run in any order.](https://opsive.com/wp-content/uploads/2026/08/bdp-random-sequence-tree-editor.webp?v=15a9762bda43)

Use it only when the actions are independent enough to run in any order. If one step must prepare another, keep those steps together inside a normal Sequence and randomize between complete branches instead.

---

<a id="page-behavior-designer-pro-concepts-tasks-composite-selector-evaluator"></a>

# Selector Evaluator

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector-evaluator/)

[//]: # (Generated by scripts/docgen. Do not edit this file manually.)

The Selector Evaluator task reevaluates its children every tick and runs the highest-priority child that can remain running. If a higher-priority child becomes eligible, it interrupts the currently running lower-priority child. It returns success when a child succeeds. This behavior is similar to a conditional abort, but the children do not need to be conditional tasks.

## Use Selector Evaluator

Add this task from the **Composites** list and connect its children in the order they should be considered. The composite controls which child runs next and derives its own status from those children.

## Reconsidering the preferred branch

Selector Evaluator repeatedly reevaluates its children so that a higher-priority child can replace the branch that is currently running.

![A Selector Evaluator shows its preferred branch failed while Chase Enemy runs.](https://opsive.com/wp-content/uploads/2026/08/bdp-selector-evaluator-runtime.webp?v=e4a8489d10cc)

Order children from highest to lowest priority and begin each reactive branch with a clear availability check. In the runtime example the first branch has failed, so Chase Enemy is running. If the first branch becomes available during execution, Selector Evaluator can interrupt Chase and move back to that higher-priority choice. Use it when the branch order is fixed but availability changes. Use Priority Selector or Utility Selector when the order itself comes from calculated values.

---

<a id="page-behavior-designer-pro-concepts-tasks-decorator"></a>

# Decorators

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/)

## Change one child's behavior

Decorators sit directly above one child. They can change the child's final status, limit when it is allowed to run, repeat it, or provide a value used by a priority or utility composite.

## Keep the relationship visible

Keep the decorator centered over its child so the relationship is unmistakable. When several branches use decorators, leave enough horizontal space for runtime values and long task labels.

Decorators always have their own node. Their pages explain both the child status they receive and the status or behavior they produce.

## Quick reference

Description-only tasks are collected here so you can compare them without opening hundreds of separate menu entries. Search this page with your browser, or use the Behavior Tasks selector in the editor to filter by task name and capability.

| Task | Description |
| --- | --- |
| **Priority Variable Evaluator** | Sets the priority value to the specified SharedVariable float value. |
| **Return Failure** | The return failure task will always return failure except when the child task is running. |
| **Return Success** | The return success task will always return success except when the child task is running. |
| **Until Failure** | The until failure task will keep executing its child task until the child task returns failure. |
| **Until Success** | The until success task will keep executing its child task until the child task returns success. |
| **Utility Curve Evaluator** | Sets the utility value to the evaluated curve value. |
| **Utility Variable Evaluator** | Sets the utility value to the specified SharedVariable float value. |

---

<a id="page-behavior-designer-pro-concepts-tasks-decorator-conditional-evaluator"></a>

# Conditional Evaluator

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/conditional-evaluator/)

## Gate a child with a Conditional

Conditional Evaluator checks a configured Conditional before allowing its single child to run. If the condition fails, the child remains inactive and the decorator immediately returns Failure. If the condition succeeds, the child runs and its final status becomes the decorator's status.

![The Conditional Evaluator and its Bool Comparison show failure while the Wait child remains inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-evaluator-condition-failure.webp?v=31a393c834df)

In this example the selected Bool Comparison is false, so Wait never starts.

## Inspect the configured condition

![The Conditional Evaluator inspector contains a Bool Comparison with unequal values.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-evaluator-failure-inspector.webp?v=e6ae7083591b)

When the configured condition succeeds, the child is allowed to run:

## Let the child run

![The Conditional Evaluator and its Wait child show success after the condition passed.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-evaluator-success-runtime.webp?v=35b0183c1fe6)

The decorator does not force success. A child failure still becomes a decorator failure:

## Preserve the child's result

![The Conditional Evaluator shows failure after its allowed child failed.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-evaluator-child-failure.webp?v=ec58ce380b28)

## Choose one-time or continuous evaluation

Use this Decorator for a one-time gate. Use a Conditional Abort when the condition must keep being reevaluated while another branch is Running.

---

<a id="page-behavior-designer-pro-concepts-tasks-decorator-cooldown"></a>

# Cooldown

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/cooldown/)

Cooldown waits for the configured duration after its child finishes, then returns the child's original Success or Failure status. During the cooldown the child is inactive while the decorator remains active.

![The Cooldown remains active after its child has completed.](https://opsive.com/wp-content/uploads/2026/08/bdp-cooldown-active-runtime.webp?v=a058c0b327ed)

After the duration, Cooldown reports the stored child result:

![The Cooldown reports failure while another execution is blocked by the cooldown period.](https://opsive.com/wp-content/uploads/2026/08/bdp-cooldown-failure-runtime.webp?v=25aed527eecc)

Place it directly above the behavior it limits. [Attack with Cooldown](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/attack-with-cooldown/) shows how a cooldown branch fits into a larger Selector.

## Used in common behaviors

- [Attack with Cooldown](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/attack-with-cooldown/)

---

<a id="page-behavior-designer-pro-concepts-tasks-decorator-iterator"></a>

# Iterator

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/iterator/)

## Run a child for every list value

Iterator runs its child once for each value in a list. On each iteration it assigns the current list value to the configured Element variable, which the child can read.

![The Iterator inspector maps a GameObject list to its current Element variable.](https://opsive.com/wp-content/uploads/2026/08/bdp-iterator-element-inspector.webp?v=9d3ae280b56a)

## Follow the current element

For a list containing three GameObjects, a Log Value child receives them one at a time:

```text
FirstElement (UnityEngine.GameObject)
SecondElement (UnityEngine.GameObject)
ThirdElement (UnityEngine.GameObject)
```

## Plan for the child's status

Iterator does not change the child's status. Design the child so its Success or Failure has a clear meaning for each item, and ensure the list contains at least two values when iteration is expected.

---

<a id="page-behavior-designer-pro-concepts-tasks-decorator-inverter"></a>

# Inverter

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/inverter/)

## Reverse Success and Failure

Inverter changes child Success to Failure and child Failure to Success. It remains Running for as long as the child remains Running.

![An Inverter reports success because its Return Status child failed.](https://opsive.com/wp-content/uploads/2026/08/bdp-inverter-child-failure-success.webp?v=757fd25b543a)

## Use a positive condition where possible

Use it when the positive form of a condition is clearer and only one branch needs the opposite meaning. If many pages need the negative form, a purpose-named Conditional such as `IsTargetNotVisible` may be easier to read.

---

<a id="page-behavior-designer-pro-concepts-tasks-decorator-repeater"></a>

# Repeater

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/repeater/)

Repeater starts its child again for the configured number of repetitions, or indefinitely. It can optionally stop when the child fails.

![A Repeater at the root keeps the main behavior branch running.](https://opsive.com/wp-content/uploads/2026/08/bdp-repeater-tree-root.webp?v=8f558cfc52dd)

Use an infinite Repeater at the root only when the entire behavior should restart after completion. Use a smaller Repeater around one task when only that operation should loop. [Retry with Delay](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/retry-with-delay/) shows how to prevent a failing operation from retrying every update.

## Used in common behaviors

- [Retry with Delay](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/retry-with-delay/)
- [Wander for a Limited Time](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/wander-for-a-limited-time/)

---

<a id="page-behavior-designer-pro-concepts-tasks-event"></a>

# Events

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/event/)

## Start a branch from an event

Event tasks start a branch when a Unity or Behavior Designer event occurs. They are useful when a response should begin immediately instead of being polled by the main Start branch.

## Keep the response independent

Place an event at the top of its own branch and connect the response beneath it. Event branches can run independently of the Start branch, which makes them a natural fit for reactions, messages, collision callbacks, and explicit interruptions.

Use [React to an Event](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/react-to-event/) for a complete example.

## Respond to tree lifecycle changes

Use **On Behavior Tree Stopping** after a stop is requested but before the tree stops. Use **On Behavior Tree Pausing** after a pause is requested but before execution pauses, and **On Behavior Tree Unpausing** when a paused tree resumes. These event branches provide a final in-tree cleanup or notification opportunity; code that must run regardless of graph structure can subscribe to the corresponding behavior-tree lifecycle events instead.

## Quick reference

Description-only tasks are collected here so you can compare them without opening hundreds of separate menu entries. Search this page with your browser, or use the Behavior Tasks selector in the editor to filter by task name and capability.

| Task | Description |
| --- | --- |
| **On Behavior Tree Pausing** | Invoked after a behavior tree pause is requested and before the tree is paused. |
| **On Behavior Tree Stopping** | Invoked after a behavior tree stop is requested and before the tree is stopped. |
| **On Behavior Tree Unpausing** | Invoked when a paused behavior tree resumes execution. |
| **On Collision Enter** | Invoked when the agent causes a collision. |
| **On Collision Enter2 D** | Invoked when the agent causes a 2D collision. |
| **On Collision Exit** | Invoked when the agent leaves a collision. |
| **On Collision Exit2 D** | Invoked when the agent leaves a 2D collision. |
| **On Interrupt** | EventNode that is invoked when an interrupt occurs. |
| **On Received Event** | Invoked when the specified event is received. |
| **On Trigger Enter** | Invoked when the agent enters a trigger. |
| **On Trigger Enter2 D** | Invoked when the agent enters a 2D trigger. |
| **On Trigger Exit** | Invoked when the agent exits a trigger. |
| **On Trigger Exit2 D** | Invoked when the agent exits a 2D trigger. |

---

<a id="page-behavior-designer-pro-concepts-common-behaviors"></a>

# Common Behaviors

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/)

## Solve a gameplay goal

Common Behaviors show how several tasks work together to solve a recognizable AI problem. Each page pairs an editor screenshot with a nontechnical explanation of the tree structure, branch order, interruption, and task statuses. When runtime behavior is important, the **How it runs** section explains the relevant state changes alongside the scenario instead of separating them into another reference section.

## Choose a scenario

- [Wander for a Limited Time](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/wander-for-a-limited-time/) runs movement and a time limit together.
- [Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) switches between patrol and pursuit when perception changes.
- [Retry with Delay](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/retry-with-delay/) waits before trying a failed branch again.
- [Timeout](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/timeout/) stops work that takes too long.
- [Attack with Cooldown](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/attack-with-cooldown/) limits how often an attack branch can run.
- [React to an Event](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/react-to-event/) interrupts normal behavior when an event arrives.
- [Search After Losing a Target](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/search-after-losing-target/) transitions from pursuit to searching and then patrol.
- [Flee at Low Health](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/flee-at-low-health/) gives survival behavior priority over combat and patrol.
- [Fallback Strategies](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/fallback-strategies/) tries alternatives in a deliberate order.
- [Switch Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/switch-subtrees/) selects reusable behavior assets for different agent roles.
- [Choose the Highest-Priority Need](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/highest-priority-need/) compares changing needs before selecting a branch.

## Adapt each tree

Each example uses descriptive task names so you can adapt the structure to your own movement, combat, perception, and animation tasks. The example tasks themselves do not need to match a particular controller implementation.

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-wander-for-a-limited-time"></a>

# Wander for a Limited Time

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/wander-for-a-limited-time/)

## Goal

Use this pattern when the agent should wander until a timer ends, even though the Wander task would otherwise continue.

## Tree structure

![A Parallel Selector runs Wander beside Wait N Seconds.](https://opsive.com/wp-content/uploads/2026/08/bdp-wander-for-a-limited-time-tree-editor.webp?v=a9a2d09b772a)

## How it runs

Add Wander and Wait N Seconds beneath a Parallel Selector, then set Wait to the desired duration. Both branches start together: Wander continues while the timer counts down, and when Wait succeeds, the Parallel Selector succeeds and stops Wander. The Wander node represents the movement task supplied by your controller or movement add-on.

## Variations

If Wander succeeds each time it reaches a destination, place a Repeater above it so the branch remains active for the full period. Use an ordinary Parallel when every branch must finish successfully instead of allowing the timer to end the behavior.

## Tasks used in this tree

[Parallel Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/parallel-selector/), **Wait** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/), and [Repeater](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/repeater/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-patrol-and-chase-an-enemy"></a>

# Patrol and Chase an Enemy

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/)

## Goal

Use this pattern when Patrol is the fallback behavior and Chase should take over whenever the agent can see an enemy.

## Tree structure

![A Selector places a Can See Enemy and Chase Enemy sequence before Patrol.](https://opsive.com/wp-content/uploads/2026/08/bdp-patrol-and-chase-an-enemy-tree-editor.webp?v=682a18ed655f)

## How it runs

A Selector considers its children from left to right, so it tries the chase Sequence before falling back to Patrol. Set the Sequence's **Abort Type** to **Both**. While Patrol is running, the Lower Priority abort reevaluates Can See Enemy and interrupts Patrol when an enemy becomes visible. While the chase branch is running, the Self abort reevaluates the same Conditional and returns control to Patrol when the agent loses sight of the enemy.

![Can See Enemy has succeeded and Chase Enemy is running while Patrol is inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-patrol-and-chase-an-enemy-chase-running.webp?v=95dc2aa3c05f)

Keep perception inside the Can See Enemy Conditional and movement inside the Chase Enemy Action. This makes the abort rule easy to understand and lets the same sight check control other behaviors. Can See Enemy is supplied by your game; Patrol and Chase Enemy can be your own movement Actions or equivalent tasks from a movement add-on.

## Variations

Add a Search branch between Chase and Patrol when the agent should investigate the last known position. Use separate sight and target-validity conditions when losing visibility should not immediately discard the target.

## Tasks used in this tree

[Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/), [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/), and [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-retry-with-delay"></a>

# Retry with Delay

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/retry-with-delay/)

## Goal

Use this pattern when an Action may fail temporarily and should be attempted again without retrying every update.

## Tree structure

![A Repeater retries an action after a Wait Before Retry branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-retry-with-delay-tree-editor.webp?v=479aec34a0c3)

## How it runs

Try Action runs first. A success ends the Selector successfully. On failure, the fallback Sequence waits and then returns Failure; that result tells the Repeater to begin another attempt.

## Variations

Set a repeat limit when the operation should eventually give up. For an endless environmental behavior, leave it repeating but ensure Try Action is inexpensive and the delay prevents constant work.

## Tasks used in this tree

[Repeater](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/repeater/), [Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/), and **Wait** plus **Return Status** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-timeout"></a>

# Timeout

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/timeout/)

## Goal

Use a timeout when a long-running task must stop after a fixed limit.

## Tree structure

![A Parallel Selector runs a long action beside a timeout branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-timeout-tree-editor.webp?v=0d851b205240)

## How it runs

Create a Parallel Selector with the Action to limit as one child. Add a Sequence as the other child, then place Wait for Timeout and Return Success under that Sequence. Set Wait to the allowed duration. The structural tasks are built in; Long Running Action represents the game-specific Action being limited.

Both branches start together. If the Action succeeds first, the Parallel Selector succeeds and stops the timer. If Wait finishes first, its branch succeeds and the Parallel Selector stops the Action.

![The timeout wait has succeeded and Return Success is running beside the long-running action.](https://opsive.com/wp-content/uploads/2026/08/bdp-timeout-timeout-branch-running.webp?v=6a35dc9d09e1)

Here Wait for Timeout has completed, so Return Success ends the parallel race and stops Long Running Action.

## Variations

If timing out should count as Failure, put a Return Failure decorator above the timer branch and use a Parallel or an explicit [Perform Interruption](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/perform-interruption/) branch. Decide whether the timeout is a successful fallback or an error that a parent should handle.

## Tasks used in this tree

[Parallel Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/parallel-selector/), **Wait** and **Return Status** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/), and [Perform Interruption](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/perform-interruption/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-attack-with-cooldown"></a>

# Attack with Cooldown

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/attack-with-cooldown/)

## Goal

Use this pattern when an attack may run only after its cooldown is ready, while another behavior remains available between attacks.

## Tree structure

![A Selector tries an in-range attack with Cooldown before its fallback behavior.](https://opsive.com/wp-content/uploads/2026/08/bdp-attack-with-cooldown-tree-editor.webp?v=398dfbeb728e)

## How it runs

The Selector tries the attack branch before the fallback. The range Conditional fails when there is no valid target, and Cooldown fails while the attack is unavailable. Either result sends the Selector to Approach or Idle. Attack runs only when the target is in range and the cooldown is ready.

![The Cooldown has failed, so the Selector runs Approach or Idle instead of Attack.](https://opsive.com/wp-content/uploads/2026/08/bdp-attack-with-cooldown-fallback-running.webp?v=54951f755284)

Here Cooldown has failed, so the fallback branch is running while Attack remains inactive.

Selector, Sequence, and Cooldown are built in. Is Target in Range and Attack represent game-specific tasks, while Approach or Idle can use whichever movement or idle task suits the character; that task may come from a movement add-on.

## Variations

Keep Cooldown beside the Action it protects so the timing rule remains visible. Use **Rate Limiter** from the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/) when the limit is based on how often an Action may be requested rather than a Decorator around one child.

## Tasks used in this tree

[Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/), [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/), [Cooldown](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/cooldown/), and **Rate Limiter** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-react-to-event"></a>

# React to an Event

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/react-to-event/)

## Goal

Use an Event branch when a reaction should begin because something happened, without polling in the main Start branch.

## Tree structure

![An On Received Event branch faces the event source and plays a reaction.](https://opsive.com/wp-content/uploads/2026/08/bdp-react-to-event-tree-editor.webp?v=3e2f42ef7237)

## How it runs

In the editor, add **On Received Event** as an Event task and give it the same event name used by the sender. Connect a Sequence containing the actions that should run in response. In this example, the agent first faces the event source and then plays its reaction.

When a matching event arrives, it starts the response Sequence while the ordinary Start branch can continue independently. **On Received Event** and **Sequence** are built-in tasks; **Face Event Source** and **Play Reaction** represent game-specific actions such as turning, playing an animation or sound, or changing state.

## Variations

Use **Send Event** from the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/) when another behavior tree should trigger the reaction. Use **Has Received Event** from the [Conditionals reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/) when the event should be checked as part of normal Selector flow instead of starting an independent branch.

## Tasks used in this tree

**On Received Event** in the [Events reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/event/), **Send Event** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/), **Has Received Event** in the [Conditionals reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/), and [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-search-after-losing-target"></a>

# Search After Losing a Target

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/search-after-losing-target/)

## Goal

Use this pattern to keep searching for a short time after sight is lost, then return to normal behavior.

## Tree structure

![A Selector chooses Chase, Search at the last known position, or Patrol.](https://opsive.com/wp-content/uploads/2026/08/bdp-search-after-losing-target-tree-editor.webp?v=94469102ffc4)

## How it runs

Place Chase first, Search second, and Patrol last. Store the target's last known position in a Shared Variable while the target is visible. Set the Chase Sequence's Abort Type to **Both** so losing sight stops Chase, while seeing the target again interrupts Search or Patrol immediately.

After sight is lost, the Selector enters Search and moves the agent to the stored position.

![Can See Target has failed, so the Search branch waits at the last known position while Patrol remains inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-search-after-losing-target-search-running.webp?v=38e5c70b27d3)

The highlighted path shows the tree searching after the Chase branch has stopped. Clear the stored position when the search finishes so Patrol becomes the fallback.

Selector, Sequence, Shared Variables, and conditional aborts are built in. The perception and last-known-position tasks are specific to your game, while movement, searching, and patrolling can use your own actions or tasks supplied by a movement integration.

## Variations

Keep Search finite with a Wait, repeat count, or timeout. Add several search points when the movement system can generate a local investigation pattern.

## Tasks used in this tree

[Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/), [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/), **Wait** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/), and [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-flee-at-low-health"></a>

# Flee at Low Health

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/flee-at-low-health/)

## Goal

Use this pattern when survival should interrupt ordinary combat as soon as health falls below a threshold.

## Tree structure

![A low-health Flee sequence has higher priority than Combat and Patrol.](https://opsive.com/wp-content/uploads/2026/08/bdp-flee-at-low-health-tree-editor.webp?v=6b15ae4a752f)

## How it runs

Place Flee first under the Selector so it has priority over Combat and Patrol. Select the Flee Sequence and set its Abort Type to Both.

While Combat or Patrol is running, the Lower Priority abort keeps checking Is Health Low. When health drops below the threshold, it stops the lower-priority branch and starts Flee. While Flee is running, the Self abort keeps checking the same condition and ends the branch after health recovers.

![Is Health Low has succeeded and Flee from Threat is running while Combat and Patrol remain inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-flee-at-low-health-flee-running.webp?v=7a8a34c575d4)

Here the low-health condition has stopped normal behavior and activated Flee from Threat.

The Selector, Sequence, and abort setting are built in. Is Health Low, Flee from Threat, Combat, and Patrol represent game-specific tasks; use your own tasks or equivalent tasks from the movement and combat integrations available to your project.

## Variations

Use separate values for starting and stopping the behavior. For example, start below 25 percent but stop above 40 percent. This prevents rapid switching near one boundary.

## Tasks used in this tree

[Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/), [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/), and [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-fallback-strategies"></a>

# Fallback Strategies

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/fallback-strategies/)

## Goal

Use a Selector to express preference: try the best option first and move right only when an option fails.

## Tree structure

![A Selector orders Use Nearby Cover, Move Away, and Idle Safely as fallbacks.](https://opsive.com/wp-content/uploads/2026/08/bdp-fallback-strategies-tree-editor.webp?v=046644d2e7d6)

## How it runs

The Selector evaluates its children from left to right, so order the alternatives from most desirable to most dependable. When an option is only valid under certain conditions, make that branch a Sequence containing the condition followed by the Action. For example, a Has Nearby Cover condition can run before Use Nearby Cover.

Each unavailable branch must return Failure so the Selector can try the next one. If Use Nearby Cover remains Running when no cover exists, the Selector never reaches Move Away from Threat.

![Use Nearby Cover has failed, so Move Away from Threat is running and Idle Safely remains inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-fallback-strategies-move-away-running.webp?v=f3eeb6573238)

This runtime state confirms that the failed first option allowed the next fallback to run.

Put an inexpensive, dependable behavior such as Idle Safely on the far right so the Selector always has a useful final option.

Selector and Sequence are built-in structural tasks. The cover, movement, and safe-idle Actions represent game-specific behavior that can come from your own tasks or a compatible movement add-on.

## Variations

Use a Priority Selector when the order should be calculated at startup, or a Utility Selector when changing values should be able to redirect execution.

## Tasks used in this tree

[Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/), [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/), [Priority Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/priority-selector/), and [Utility Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/utility-selector/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-switch-subtrees"></a>

# Switch Subtrees

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/switch-subtrees/)

## Goal

Use subtree tasks when several agents share a high-level tree but need different reusable behavior assets.

## Tree structure

![A Selector chooses a combat or civilian subtree according to the agent role.](https://opsive.com/wp-content/uploads/2026/08/bdp-switch-subtrees-tree-editor.webp?v=7487b98d6373)

## How it runs

Create and test the Combat and Civilian behavior assets independently, then assign each asset to its Subtree Reference. In the Task Inspector, map the Shared Variables that each subtree needs by purpose so both assets receive the correct values from the parent tree.

The Selector tries the Combatant Branch first. When Is Combatant succeeds, the Combat Subtree Reference runs and reports the result of its behavior asset. When Is Combatant fails, the Selector skips that branch and runs the Civilian Subtree Reference instead.

## Variations

Use **Subtree Reference** when the asset is known in advance, **Subtree Reference Selector** when a value chooses among several assets, and **Set Subtree** when another branch changes that value before the reference runs.

## Tasks used in this tree

**Subtree Reference**, **Subtree Reference Selector**, and **Set Subtree** in the [Actions reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/), plus [Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/selector/) and [Sequence](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/sequence/).

---

<a id="page-behavior-designer-pro-concepts-common-behaviors-highest-priority-need"></a>

# Choose the Highest-Priority Need

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/highest-priority-need/)

## Goal

Use priority or utility selection when branch order should be calculated from the current situation instead of fixed from left to right.

## Tree structure

![A Utility Selector compares Safety, Hunger, and Fatigue evaluator branches.](https://opsive.com/wp-content/uploads/2026/08/bdp-highest-priority-need-tree-editor.webp?v=6325acdce0ea)

## How it runs

Place one evaluator directly above each single child branch, then configure it to read the variable or curve that represents that need. At runtime, each evaluator expands to display its current **Value**, so leave enough horizontal space between the branches for those values to remain readable.

The branch with the highest utility runs first. For example, Safety at `0.9`, Hunger at `0.6`, and Fatigue at `0.3` selects Seek Safety.

![Safety has utility 0.9 and runs Seek Safety ahead of Hunger at 0.6 and Fatigue at 0.3.](https://opsive.com/wp-content/uploads/2026/08/bdp-highest-priority-need-safety-running.webp?v=a0cfd2298c18)

The displayed values confirm that Safety is highest, so Seek Safety is the running branch. If Hunger later rises above Safety, the Utility Selector can redirect execution to Eat. Enable **Block During Execution** when the current branch must finish before a newly preferred branch can start.

The Utility Selector and evaluator Decorators are built in. The safety, hunger, and fatigue values and their child Actions represent game-specific behavior.

## Variations

Use a [Priority Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/priority-selector/) for values that establish an order when traversal begins. Use a [Utility Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/utility-selector/) when values continue changing and may redirect execution.

## Tasks used in this tree

[Utility Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/utility-selector/), **Utility Variable Evaluator** and **Utility Curve Evaluator** in the [Decorators reference](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/decorator/), and [Priority Selector](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/composite/priority-selector/).

---

<a id="page-behavior-designer-pro-new-tasks"></a>

# New Tasks

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/)

## Choose a task workflow

Behavior Designer supports tasks that use the GameObject architecture as well as tasks that use Entities within the [DOTS architecture](https://unity.com/dots). The GameObject tasks inherit the Task abstract class which has an API similar to the MonoBehaviour class. Entity tasks implement various interfaces in order to ensure they provide the correct functionality. The list below contains the advantages of each approach: **GameObject Advantages**:

## GameObject task advantages

-   Easy to create. The workflow is extremely similar to a MonoBehaviour component with OnStart, OnUpdate, and the other task callbacks.
-   Can reference objects. This is an inherit limitation of Entities in that they can only pass objects by value.
-   Can use Shared Variables. Shared Variables are classes shared between objects which means they cannot be used with the Entity workflow.
-   Can use any existing Unity system. Unity is still working on updating all of their systems to use DOTS, which means that for some situations you have to use the GameObject approach.
-   Still uses DOTS to traverse the tree. Behavior Designer still uses DOTS in order to traverse the tree.

## Entity task advantages

-   Can use [Burst](https://docs.unity3d.com/Manual/com.unity.burst.html). The Entity tasks use structs which allows the code to be burstable.
-   Can use the [job system](https://docs.unity3d.com/Manual/job-system.html) in parallel. This allows for extremely fast execution across multiple threads.
-   Extremely performant. If you want to have hundreds of thousands of entities on the screen you are going to need to use all Entity tasks.

## Start with GameObject tasks

As a general rule if you only have under ~50 behavior tree agents and don't have any computationally heavy tasks it is recommended that you use the GameObject approach. The behavior tree traversal will still be quick and you won't notice much difference by switching to Entity based tasks. GameObject tasks still have many advantages over Entity tasks. If you've later profiled your project and notice that a particular task is causing a bottleneck you can then switch that task to an Entity-based task.

---

<a id="page-behavior-designer-pro-new-tasks-gameobject-task"></a>

# GameObject Task

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/gameobject-task/)

A GameObject Task is the default route for project-specific Task logic. Move a Task to the [Entity](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/entity-task/) route only when profiling a build shows that its execution is a bottleneck at the agent counts the project needs — see [Performance](https://opsive.com/support/documentation/behavior-designer-pro/performance/).

<iframe width="100%" height="600" src="https://www.youtube.com/embed/gQQzQeXkvf8?rel=0&amp;showinfo=0" title="Creating a GameObject task video" loading="lazy" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

If the embedded player is unavailable, [watch Creating a GameObject Task on YouTube](https://www.youtube.com/watch?v=gQQzQeXkvf8).

The lifecycle mirrors the MonoBehaviour callbacks:

```csharp
/// <summary>
/// Callback when the behavior tree is initialized.
/// </summary>
public virtual void OnAwake()

/// <summary>
/// Callback when the behavior tree is enabled.
/// </summary>
public virtual void OnEnable()

/// <summary>
/// Callback when the task is started.
/// </summary>
public virtual void OnStart()

/// <summary>
/// Executes the task logic. Returns a TaskStatus indicating how the behavior tree flow should proceed.
/// </summary>
/// <returns>The status of the task.</returns>
public virtual TaskStatus OnUpdate()

/// <summary>
/// Callback when the task stops.
/// </summary>
public virtual void OnEnd()

/// <summary>
/// Callback when the behavior tree is disabled.
/// </summary>
public virtual void OnDisable()

/// <summary>
/// Callback when the behavior tree is destroyed.
/// </summary>
public virtual void OnDestroy()

```

A Conditional Task can also implement `OnReevaluateUpdate` to take a different path when a conditional abort is reevaluating it:

```csharp
/// <summary>
/// Reevaluates the task logic. Returns a TaskStatus indicating how the behavior tree flow should proceed.
/// </summary>
/// <returns>The status of the task during the reevaluation phase.</returns>
public virtual TaskStatus OnReevaluateUpdate()
```

To receive a physics callback, override the corresponding receive property:

```csharp
ReceiveCollisionEnterCallback
ReceiveCollisionExitCallback
ReceiveCollisionEnter2DCallback
ReceiveCollisionExit2DCallback
ReceiveTriggerEnterCallback
ReceiveTriggerExitCallback
ReceiveTriggerEnter2DCallback
ReceiveTriggerExit2DCallback
ReceiveControllerColliderHitCallback
```

A Task receives a physics callback only after opting in through the matching property, which keeps the cost off Tasks that do not need it. The Conditional Task example at the end of this page returns Success once a specific object enters a trigger.

Each Task can also participate in the save/load system and declare what should persist. See [Save/Load](https://opsive.com/support/documentation/behavior-designer-pro/save-load/) for the full workflow.

```csharp
/// <summary>
/// Specifies the type of reflection that should be used to save the task.
/// </summary>
/// <param name="index">The index of the sub-task. This is used for the task set allowing each contained task to have their own save type.</param>
public virtual MemberVisibility GetSaveReflectionType(int index)

/// <summary>
/// Returns the current task state.
/// </summary>
/// <param name="world">The DOTS world.</param>
/// <param name="entity">The DOTS entity.</param>
/// <returns>The current task state.</returns>
public virtual object Save(World world, Entity entity)

/// <summary>
/// Loads the previous task state.
/// </summary>
/// <param name="saveData">The previous task state.</param>
/// <param name="world">The DOTS world.</param>
/// <param name="entity">The DOTS entity.</param>
public virtual void Load(object saveData, World world, Entity entity)
```

## Create an action task

An [Action Task](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/action/) derives from either `Action` or `ActionNode`. `Action` Tasks are stacked with other Action Tasks; `ActionNode` Tasks are not. Derive from `Action` unless the Task must stay separate from everything else, as the Subtree Reference Task does.

The example below moves the agent to a random point within a radius of a center point, at a configurable speed. It uses [Shared Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) so the values can be shared with other Tasks, and implements Save and Load so the chosen point survives a save.

Create a new script in the project. Behavior Designer uses [assembly definitions](https://docs.unity3d.com/6000.0/Documentation/Manual/assembly-definitions-intro.html), so reference the `Opsive.BehaviorDesigner.Runtime` assembly. Start with `OnStart`, which chooses the destination:

```csharp
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using UnityEngine;
public class MoveTowardsRandomPoint : Action
{
    [Tooltip("The center point of the random position.")]
    public SharedVariable<Vector3> m_Center;
    [Tooltip("The radius that contains the random position.")]
    public SharedVariable<float> m_Radius = 10;

    private Vector3 m_Destination;

    /// <summary>
    /// Callback when the task is started.
    /// </summary>
    public override void OnStart()
    {
        m_Destination = m_Center.Value + Random.insideUnitSphere * Random.Range(0, m_Radius.Value);
    }
}
```

This block chooses a new random destination when the Task starts, using a `Vector3` Shared Variable for the center point and a `float` Shared Variable for the radius. `Opsive.GraphDesigner.Runtime.Variables` contains the Shared Variable system, and `Opsive.BehaviorDesigner.Runtime.Tasks.Actions` contains the parent `Action` class. With a destination selected, add the movement:

```csharp
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using UnityEngine;

public class MoveTowardsRandomPoint : Action
{
    [Tooltip("The center point of the random position.")]
    public SharedVariable<Vector3> m_Center;
    [Tooltip("The radius that contains the random position.")]
    public SharedVariable<float> m_Radius = 10;
    [Tooltip("The speed that the agent should move towards the destination.")]
    public SharedVariable<float> m_MoveSpeed = 5;

    private Vector3 m_Destination;

    /// <summary>
    /// Callback when the task is started.
    /// </summary>
    public override void OnStart()
    {
        m_Destination = m_Center.Value + Random.insideUnitSphere * Random.Range(0, m_Radius.Value);
    }

    /// <summary>
    /// Executes the task logic. Returns a TaskStatus indicating how the behavior tree flow should proceed.
    /// </summary>
    /// <returns>The status of the task.</returns>
    public override TaskStatus OnUpdate()
    {
        // The agent has arrived when they get close to the destination.
        if (Vector3.Distance(transform.position, m_Destination) < 0.5f) {
            return TaskStatus.Success;
        }

        // The agent hasn't arrived yet. Keep moving towards the destination and return a running status.
        transform.position = Vector3.MoveTowards(transform.position, m_Destination, m_MoveSpeed.Value * Time.deltaTime);
        return TaskStatus.Running;
    }
}
```

This revision adds a namespace, the `m_MoveSpeed` variable, and `OnUpdate`. `OnUpdate` is called on each tick and its return value tells the tree how to proceed: `TaskStatus.Success` once the agent reaches the destination, and `TaskStatus.Running` while it is still moving. The Task is now functionally complete.

Two optional attributes improve how the Task presents in the editor. Selecting a node shows its description in the lower right, which comes from `Opsive.Shared.Utility.Description`, and `NodeIcon` supplies a node icon:

```csharp
using Opsive.GraphDesigner.Runtime;

[NodeIcon("Assets/MyIcon.png")]
[Opsive.Shared.Utility.Description("Moves the agent towards a random position within the specified radius.")]
public class MoveTowardsRandomPoint : Action
```

`NodeIcon` accepts an asset path or an asset GUID, plus an optional second value used as the light-theme icon.

The Task is complete at this point if the tree does not need saving. To support [Save/Load](https://opsive.com/support/documentation/behavior-designer-pro/save-load/), implement the following methods as well:

```csharp
    /// <summary>
    /// Specifies the type of reflection that should be used to save the task.
    /// </summary>
    /// <param name="index">The index of the sub-task. This is used for the task set allowing each contained task to have their own save type.</param>
    public override MemberVisibility GetSaveReflectionType(int index)
    {
        // Do not use reflection to save. This task will implement the Save and Load methods.
        return MemberVisibility.None;
    }

    /// <summary>
    /// Returns the current task state.
    /// </summary>
    /// <param name="world">The DOTS world.</param>
    /// <param name="entity">The DOTS entity.</param>
    /// <returns>The current task state.</returns>
    public override object Save(World world, Entity entity)
    {
        // Only save the destination.
        return m_Destination;
    }

    /// <summary>
    /// Loads the previous task state.
    /// </summary>
    /// <param name="saveData">The previous task state.</param>
    /// <param name="world">The DOTS world.</param>
    /// <param name="entity">The DOTS entity.</param>
    public override void Load(object saveData, World world, Entity entity)
    {
        // The saveData will only contain the objects specified by the Save method.
        m_Destination = (Vector3)saveData;
    }
```

The Unity.Entities namespace must be added in order for this code to compile. `GetSaveReflectionType` specifies how the variables should be saved using reflection:

-   `MemberVisibility.All`: Public and private variables will be saved with reflection.
-   `MemberVisiblity.Public`: Only public and serialized private variables will be saved with reflection.
-   `MemberVisiblity.None`: No variables will be saved with reflection. If this value is specified then the Save and Load methods need to be implemented.

Since `MemberVisiblity.None` was specified we need to implement the `Save` and `Load` methods. The `Save` method simply returns the value that we want to save (in this case the random destination), and the `Load` method will restore that value. The task is now complete. The entire task looks like:

```csharp
using Opsive.Shared.Utility;
using Opsive.GraphDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using UnityEngine;
using Unity.Entities;

[NodeIcon("Assets/MyIcon.png")]
[Description("Moves the agent towards a random position within the specified radius.")]
public class MoveTowardsRandomPoint : Action
{
    [Tooltip("The center point of the random position.")]
    public SharedVariable<Vector3> m_Center;
    [Tooltip("The radius that contains the random position.")]
    public SharedVariable<float> m_Radius = 10;
    [Tooltip("The speed that the agent should move towards the destination.")]
    public SharedVariable<float> m_MoveSpeed = 5;

    private Vector3 m_Destination;

    /// <summary>
    /// Callback when the task is started.
    /// </summary>
    public override void OnStart()
    {
        m_Destination = m_Center.Value + Random.insideUnitSphere * Random.Range(0, m_Radius.Value);
    }

    /// <summary>
    /// Executes the task logic. Returns a TaskStatus indicating how the behavior tree flow should proceed.
    /// </summary>
    /// <returns>The status of the task.</returns>
    public override TaskStatus OnUpdate()
    {
        // The agent has arrived when they get close to the destination.
        if (Vector3.Distance(transform.position, m_Destination) < 0.5f) {
            return TaskStatus.Success;
        }

        // The agent hasn't arrived yet. Keep moving towards the destination and return a running status.
        transform.position = Vector3.MoveTowards(transform.position, m_Destination, m_MoveSpeed.Value * Time.deltaTime);
        return TaskStatus.Running;
    }

    /// <summary>
    /// Specifies the type of reflection that should be used to save the task.
    /// </summary>
    /// <param name="index">The index of the sub-task. This is used for the task set allowing each contained task to have their own save type.</param>
    public override MemberVisibility GetSaveReflectionType(int index)
    {
        // Do not use reflection to save. This task will implement the Save and Load methods.
        return MemberVisibility.None;
    }

    /// <summary>
    /// Returns the current task state.
    /// </summary>
    /// <param name="world">The DOTS world.</param>
    /// <param name="entity">The DOTS entity.</param>
    /// <returns>The current task state.</returns>
    public override object Save(World world, Entity entity)
    {
        // Only save the destination.
        return m_Destination;
    }

    /// <summary>
    /// Loads the previous task state.
    /// </summary>
    /// <param name="saveData">The previous task state.</param>
    /// <param name="world">The DOTS world.</param>
    /// <param name="entity">The DOTS entity.</param>
    public override void Load(object saveData, World world, Entity entity)
    {
        // The saveData will only contain the objects specified by the Save method.
        m_Destination = (Vector3)saveData;
    }
}
```

## Create a conditional task

A [Conditional Task](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/) uses the same API as an Action Task, plus `OnReevaluateUpdate` for conditional aborts. It derives from `Conditional`, which is stacked with other Conditionals, or `ConditionalNode`, which is not. The example below returns Success once a matching object enters the agent's trigger.

```csharp
public class HasEnteredTrigger : Conditional
{
    [Tooltip("The tag of the GameObject that the trigger should be checked against.")]
    [SerializeField] protected SharedVariable<string> m_Tag;

    protected override bool ReceiveTriggerEnterCallback => true;

    private bool m_EnteredTrigger;

    /// <summary>
    /// Returns true when the agent has entered a trigger.
    /// </summary>
    /// <returns>True when the agent has entered a trigger.</returns>
    public override TaskStatus OnUpdate()
    {
        return m_EnteredTrigger ? TaskStatus.Success : TaskStatus.Failure;
    }

    /// <summary>
    /// The agent has entered a trigger.
    /// </summary>
    /// <param name="other">The trigger that the agent entered.</param>
    protected override void OnTriggerEnter(Collider other)
    {
        if (!string.IsNullOrEmpty(m_Tag.Value) && !other.gameObject.CompareTag(m_Tag.Value)) {
            return;
        }
        m_EnteredTrigger = true;
    }
}
```

A lot of the same concepts from the action task applies to conditional tasks. Compared to the action task from above this conditional task:

-   Implements the **Conditional** base class.
-   Overrides the `ReceivedTriggerEnterCallback` property.
-   Implements `OnTriggerEnter`. If `ReceivedTriggerEnterCallback` was not overridden with a true status then this method would not be called.

Conditional tasks are special in that they can be reevaluated with conditional aborts. By default conditional aborts will call the `OnUpdate` method, but you can also implement a separate callback that has logic specific to the reevaluation:

```csharp
    /// <summary>
    /// Reevaluates the task logic. Returns a TaskStatus indicating how the behavior tree flow should proceed.
    /// </summary>
    /// <returns>The status of the task during the reevaluation phase.</returns>
    public override TaskStatus OnReevaluateUpdate()
    {
        return (m_EnteredTrigger && string.Equals(m_Tag.Value, "BlueTeam")) ? TaskStatus.Success : TaskStatus.Failure;
    }
```

This is a contrived example but it illustrates the point well that the reevaluation update can be different from the regular update. In this example in order for the conditional abort to trigger the agent must enter the trigger and the tag must match the "BlueTeam" tag. In most cases you will not need to implement a separate `OnReevaluateUpdate` callback.

## Composite & Decorator Tasks

The composite and decorator tasks are very similar. Composite tasks should implement the `CompositeNode` base class, and decorator tasks should implement `DecoratorNode`. Composite and decorator tasks cannot be stacked. Composite tasks can implement two extra properties:

```csharp
/// <summary>
/// The maximum number of child tasks that can be parented to the current task.
/// </summary>
public virtual int MaxChildCount { get => int.MaxValue; }

/// <summary>
/// Returns the index of the next active task index.
/// </summary>
public virtual ushort NextChildIndex { get => (ushort)(Index + 1); }
```

The `MaxChildCount` property will be checked during edit time when tasks are being added to the tree. `NextChildIndex` is called at runtime in order to determine the next task that should start. This property is only called if the task has a status of running. If the task is not running then the child is not running. Decorators implement these two properties but their values are restricted because decorators can only have a single child. Therefore you do not need to implement these methods for a decorator task.

---

<a id="page-behavior-designer-pro-new-tasks-entity-task"></a>

# Entity Task

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/entity-task/)

An Entity Task executes as Burst-compiled job code rather than managed code, which is what makes it suited to large agent counts. The tradeoff is structure: an Entity Task cannot inherit a base class, so each part is written explicitly. This page covers the Behavior Designer-specific structure and assumes working knowledge of DOTS. See [Performance](https://opsive.com/support/documentation/behavior-designer-pro/performance/) for when this route is worth the additional structure.

<iframe width="100%" height="600" src="https://www.youtube.com/embed/UVt8IREJ3h0?rel=0&amp;showinfo=0" title="Creating an Entity task video" loading="lazy" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

If the embedded player is unavailable, [watch Creating an Entity Task on YouTube](https://www.youtube.com/watch?v=UVt8IREJ3h0).

An Entity Task has these parts:

| Part | Responsibility |
| --- | --- |
| **Authoring object** | Created when the Task is added to the tree. Holds no runtime logic; it creates the required components, systems, and flags at runtime. |
| **Component struct** | The runtime data traversed by the system logic. |
| **System logic** | The runtime logic. May schedule a job to run in parallel. |
| **Job logic** (optional) | Created by the system to execute the runtime logic in parallel. |
| **Reevaluation system logic** (optional) | Used by Conditional Tasks to reevaluate under a conditional abort. |
| **Reevaluate system job** (optional) | Lets the reevaluation run in parallel rather than inside the system. |

The example builds a Conditional Task that checks whether an origin is within a distance of a point. It is deliberately small so the structure stays visible, and it is a Conditional so the reevaluation path can be shown. Every Task type follows the same shape.

## Authoring object

The authoring object implements the interfaces that make it compatible with Behavior Designer:

- `ITreeLogicNode` exposes the parameters required for the Task to be added to a tree.
- `IAuthoringTask` supplies the properties and methods that add the correct components, systems, and flags at runtime.
- `IConditional` marks this as a Conditional Task. `IAction`, `IComposite`, and `IDecorator` mark the other types.
- `IReevaluateResponder` marks the Conditional as able to be reevaluated.

Implementing those interfaces gives:

```csharp
public struct WithinDistance : ITreeLogicNode, IAuthoringTask, IConditional, IReevaluateResponder
{
    // Required ITreeLogicNode parameters.
    [Tooltip("The index of the node.")]
    [SerializeField] ushort m_Index;
    [Tooltip("The parent index of the node. ushort.MaxValue indicates no parent.")]
    [SerializeField] ushort m_ParentIndex;
    [Tooltip("The sibling index of the node. ushort.MaxValue indicates no sibling.")]
    [SerializeField] ushort m_SiblingIndex;

    // Required ITreeLogicNode properties.
    public ushort Index { get => m_Index; set => m_Index = value; }
    public ushort ParentIndex { get => m_ParentIndex; set => m_ParentIndex = value; }
    public ushort SiblingIndex { get => m_SiblingIndex; set => m_SiblingIndex = value; }
    public ushort RuntimeIndex { get; set; }

    // Required IAuthoringTask properties.
    public ComponentType Flag { get => typeof(WithinDistanceFlag); }
    public System.Type SystemType { get => typeof(WithinDistanceTaskSystem); }

    // Required IReevaluateResponder properties.
    public ComponentType ReevaluateFlag { get => typeof(WithinDistanceReevaluateFlag); }
    public System.Type ReevaluateSystemType { get => typeof(WithinDistanceReevaluateTaskSystem); }

    /// <summary>
    /// Adds the IBufferElementData to the entity.
    /// </summary>
    /// <param name="world">The world that the entity exists.</param>
    /// <param name="entity">The entity that the IBufferElementData should be assigned to.</param>
    /// <param name="gameObject">The GameObject that the entity is attached to.</param>
    /// <returns>The index of the element within the buffer.</returns>
    public int AddBufferElement(World world, Entity entity)
    {
        DynamicBuffer<WithinDistanceComponent> buffer;
        if (world.EntityManager.HasBuffer<WithinDistanceComponent>(entity)) {
            buffer = world.EntityManager.GetBuffer<WithinDistanceComponent>(entity);
        } else {
            buffer = world.EntityManager.AddBuffer<WithinDistanceComponent>(entity);
        }

        buffer.Add(new WithinDistanceComponent()
        {
            Index = RuntimeIndex,
        });
        return buffer.Length - 1;
    }

    /// <summary>
    /// Clears the IBufferElementData from the entity.
    /// </summary>
    /// <param name="world">The world that the entity exists.</param>
    /// <param name="entity">The entity that the IBufferElementData should be cleared from.</param>
    public void ClearBufferElement(World world, Entity entity)
    {
        DynamicBuffer<WithinDistanceComponent> buffer;
        if (world.EntityManager.HasBuffer<WithinDistanceComponent>(entity)) {
            buffer = world.EntityManager.GetBuffer<WithinDistanceComponent>(entity);
            buffer.Clear();
        }
    }
}
```

A tree can contain several Tasks of the same type, so each component is stored in a `DynamicBuffer`. `AddBufferElement` and `ClearBufferElement` reference the `WithinDistanceComponent` struct, which is defined below.

Everything shown so far is required structure rather than Within Distance logic. Base classes supply that structure:

| Base class | Implements |
| --- | --- |
| `ECSActionTask<TSystem, TBufferElement, TComponentFlag>` | An Action Task with the specified system and component. |
| `ECSCompositeTask<TSystem, TBufferElement, TComponentFlag>` | A Composite Task with the specified system and component. |
| `ECSConditionalTask<TSystem, TBufferElement, TComponentFlag>` | A Conditional Task with the specified system and component. |
| `ECSDecoratorTask<TSystem, TBufferElement, TComponentFlag>` | A Decorator Task with the specified system and component. |

Using `ECSConditionalTask`, the authoring object above reduces to:

```csharp
public class WithinDistance : ECSConditionalTask<WithinDistanceTaskSystem, WithinDistanceComponent, WithinDistanceFlag>, IReevaluateResponder
{
    public ComponentType ReevaluateFlag { get => typeof(WithinDistanceReevaluateFlag); }
    public System.Type ReevaluateSystemType { get => typeof(WithinDistanceReevaluateTaskSystem); }

    /// <summary>
    /// Returns a new TBufferElement for use by the system.
    /// </summary>
    /// <returns>A new TBufferElement for use by the system.</returns>
    public override WithinDistanceComponent GetBufferElement()
    {
        return new WithinDistanceComponent()
        {
            Index = RuntimeIndex,
        };
    }
}
```

Before defining the component struct, add the Within Distance parameters:

```csharp
    // WithinDistance parameters.
    [Tooltip("The origin position to determine if the agent is within the distance of.")]
    [SerializeField] Vector3 m_Origin;
    [Tooltip("The target position to determine if the agent is within the distance of.")]
    [SerializeField] Vector3 m_Target;
    [Tooltip("Returns success when the agent is within the specified distance.")]
    [SerializeField] float m_Distance;
```

Set those parameters on the `WithinDistanceComponent` by modifying the `new WithinDistanceComponent` block inside `AddBufferElement`:

```csharp
    buffer.Add(new WithinDistanceComponent()
    {
        Index = RuntimeIndex,
        Origin = m_Origin,
        Target = m_Target,
        Distance = m_Distance
    });
```

The full task will be added at the end of the page.

## Component struct

The component struct is used at runtime by the system. This contains the actual data that is used within the behavior tree. This component is similar to the authoring component except it doesn't contain any of the behavior tree structure logic or the setup/cleanup code:

```csharp
/// <summary>
/// The DOTS data structure for the WithinDistance struct.
/// </summary>
public struct WithinDistanceComponent : IBufferElementData
{
    [Tooltip("The index of the node.")]
    public ushort Index;
    [Tooltip("The origin position to determine if the agent is within the distance of.")]
    public float3 Origin;
    [Tooltip("The target position to determine if the agent is within the distance of.")]
    public float3 Target;
    [Tooltip("Returns success when the agent is within the specified distance.")]
    public float Distance;
}

/// <summary>
/// A DOTS flag indicating when a WithinDistance node is active.
/// </summary>
public struct WithinDistanceFlag : IComponentData, IEnableableComponent { }
```

The `WithinDistanceComponent` contains the same logic parameters defined as the authoring component with the **Index** addition. When the behavior tree is initialized a `DynamicBuffer` of `TaskComponents` are added to the entity. The `TaskComponent` is an internal Behavior Designer structure that contains the information about the task, such as its execution status. The **Index** parameter within the `WithinDistanceComponent` specifies the index of the `TaskComponent` that corresponds to the Within Distance task. This is used so the status of the task can be changed. The `WithinDistanceFlag` specifies when the task is active. This is the same flag that is specified by the **Flag** property within the `WithinDistance` authoring component from above.

## System logic

The authoring component exposes a `SystemType` property returning `WithinDistanceTaskSystem`, which is the system that executes the runtime logic for the component. Create that system:

```csharp
/// <summary>
/// Runs the WithinDistance logic.
/// </summary>
[DisableAutoCreation]
public partial struct WithinDistanceTaskSystem : ISystem
{
    private EntityQuery m_Query;

    /// <summary>
    /// Creates the required objects for use within the job system.
    /// </summary>
    /// <param name="state">The current SystemState.</param>
    [BurstCompile]
    private void OnCreate(ref SystemState state)
    {
        m_Query = new EntityQueryBuilder(Allocator.Temp)
        .WithAllRW<TaskComponent>()
        .WithAll<BranchComponent>()
        .WithAll<WithinDistanceComponent, WithinDistanceFlag, EvaluateFlag>()
        .Build(ref state);
    }

    /// <summary>
    /// Updates the job.
    /// </summary>
    /// <param name="state">The current state of the system.</param>
    [BurstCompile]
    private void OnUpdate(ref SystemState state)
    {
        state.Dependency = new WithinDistanceJob().ScheduleParallel(m_Query, state.Dependency);
    }
}
```

The system stays small because `WithinDistanceJob` does the work. Task logic can run in the system directly or in a job; the included Tasks use whichever suits the situation. Note that the query uses `EvaluateFlag`, a Behavior Designer structure:

-   `EvaluateFlag`: Contains information about the behavior tree execution. If the behavior tree is disabled then this component will not exist on the entity allowing the system to skip processing that entity.

## Job logic

For this Task the job executes the Task logic:

```csharp
/// <summary>
/// Job which executes the task logic.
/// </summary>
[BurstCompile]
private partial struct WithinDistanceJob : IJobEntity
{
    /// <summary>
    /// Executes the idle logic.
    /// </summary>
    /// <param name="branchComponents">An array of BranchComponents.</param>
    /// <param name="taskComponents">An array of TaskComponents.</param>
    /// <param name="withinDistanceComponents">An array of WithinDistanceComponents.</param>
    [BurstCompile]
    public void Execute(ref DynamicBuffer<BranchComponent> branchComponents, ref DynamicBuffer<TaskComponent> taskComponents, ref DynamicBuffer<WithinDistanceComponent> withinDistanceComponents)
    {
        for (int i = 0; i < withinDistanceComponents.Length; ++i) {
            var withinDistanceComponent = withinDistanceComponents[i];
            var taskComponent = taskComponents[withinDistanceComponent.Index];
            var branchComponent = branchComponents[taskComponent.BranchIndex];

            if (!branchComponent.CanExecute || (taskComponent.Status != TaskStatus.Queued && taskComponent.Status != TaskStatus.Running)) {
                continue;
            }

            taskComponent.Status = math.distance(withinDistanceComponent.Origin, withinDistanceComponent.Target) < withinDistanceComponent.Distance ? TaskStatus.Success : TaskStatus.Failure;
            taskComponents[withinDistanceComponent.Index] = taskComponent;
        }
    }
}
```

The job loops through the `WithinDistanceComponent` buffer and finds the Task that should start running. Because this is a Conditional, it returns only Success or Failure, which the distance check supplies:

```csharp
taskComponent.Status = math.distance(withinDistanceComponent.Origin, withinDistanceComponent.Target) < withinDistanceComponent.Distance ? TaskStatus.Success : TaskStatus.Failure;
```

Once the status is set it must be stored back into the `TaskComponents` array. These components and systems form a complete Entity Task. The remaining piece is the reevaluation path, which a Conditional Task needs so conditional aborts can run it.

## Reevaluation system logic

A conditional abort runs a separate but similar system. The difference is the `BranchComponent` handling: a Task being reevaluated does not control the branch, so it must not set the branch's `NextIndex`. The rest of the logic matches. This example runs the work inside the system rather than in a job, to show the alternative structure.

```csharp
/// <summary>
/// A DOTS flag indicating when an WithinDistance node needs to be reevaluated.
/// </summary>
public struct WithinDistanceReevaluateFlag : IComponentData, IEnableableComponent
{
}

/// <summary>
/// Runs the WithinDistance reevaluation logic.
/// </summary>
[DisableAutoCreation]
public partial struct WithinDistanceReevaluateTaskSystem : ISystem
{
    /// <summary>
    /// Updates the reevaluation logic.
    /// </summary>
    /// <param name="state">The current state of the system.</param>
    [BurstCompile]
    private void OnUpdate(ref SystemState state)
    {
        foreach (var (taskComponents, withinDistanceComponents) in
SystemAPI.Query<DynamicBuffer<TaskComponent>, DynamicBuffer<WithinDistanceComponent>>().WithAll<WithinDistanceReevaluateFlag, EvaluateFlag>()) {
        for (int i = 0; i < withinDistanceComponents.Length; ++i) {
        var withinDistanceComponent = withinDistanceComponents[i];
        var taskComponent = taskComponents[withinDistanceComponent.Index];
        if (!taskComponent.Reevaluate) {
            continue;
        }

        var status = math.distance(withinDistanceComponent.Origin, withinDistanceComponent.Target) < withinDistanceComponent.Distance ? TaskStatus.Success : TaskStatus.Failure;
        if (status != taskComponent.Status) {
            taskComponent.Status = status;
            var buffer = taskComponents;
            buffer[taskComponent.Index] = taskComponent;
        }
    }
}
```

The `WithinDistanceReevaluateFlag` is similar to the `WithinDistanceFlag` except it is only used to specify when the task is being reevaluated, rather than when it is actually active. The `WithinDistanceReevaluateTaskSystem` is then similar to the setup for `WithinDistanceTaskSystem`. There are two key differences with this reevaluation system:

```csharp
        if (!taskComponent.Reevaluate) {
            continue;
        }
```

The original system compared `taskComponent.Status != TaskStatus.Queued`; this one instead determines whether the Task is being reevaluated. The second difference is that the assignment only happens when the status changed:

```csharp
        if (status != taskComponent.Status) {
            taskComponent.Status = status;
            var buffer = taskComponents;
            buffer[taskComponent.Index] = taskComponent;
        }
```

Skipping the write when nothing changed avoids unnecessary assignment. The conditional abort system compares the `TaskComponent` status against the original status and triggers an abort when they differ. With this system in place the Entity Task is complete.

## Complete script

The entire script is below with the namespaces and all of the comments.

```csharp
using Opsive.BehaviorDesigner.Runtime.Components;
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.GraphDesigner.Runtime;
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using UnityEngine;

[Opsive.Shared.Utility.Category("ECS Example")]
[Opsive.Shared.Utility.Description("Returns success when the agent is within distance of the specified position.")]
public class WithinDistance : ECSConditionalTask<WithinDistanceTaskSystem, WithinDistanceComponent, WithinDistanceFlag>, IReevaluateResponder
{
    public ComponentType ReevaluateFlag { get => typeof(WithinDistanceReevaluateFlag); }
    public System.Type ReevaluateSystemType { get => typeof(WithinDistanceReevaluateTaskSystem); }

    /// <summary>
    /// Returns a new TBufferElement for use by the system.
    /// </summary>
    /// <returns>A new TBufferElement for use by the system.</returns>
    public override WithinDistanceComponent GetBufferElement()
    {
        return new WithinDistanceComponent()
        {
            Index = RuntimeIndex,
        };
    }
}

/// <summary>
/// The DOTS data structure for the WithinDistance struct.
/// </summary>
public struct WithinDistanceComponent : IBufferElementData
{
    [Tooltip("The index of the node.")]
    public ushort Index;
    [Tooltip("The target position to determine if the agent is within the distance of.")]
    public float3 Origin;
    [Tooltip("The target position to determine if the agent is within the distance of.")]
    public float3 Target;
    [Tooltip("Returns success when the agent is within the specified distance.")]
    public float Distance;
}

/// <summary>
/// A DOTS flag indicating when a WithinDistance node is active.
/// </summary>
public struct WithinDistanceFlag : IComponentData, IEnableableComponent { }

/// <summary>
/// Runs the WithinDistance logic.
/// </summary>
[DisableAutoCreation]
public partial struct WithinDistanceTaskSystem : ISystem
{
    private EntityQuery m_Query;

    /// <summary>
    /// Creates the required objects for use within the job system.
    /// </summary>
    /// <param name="state">The current SystemState.</param>
    [BurstCompile]
    private void OnCreate(ref SystemState state)
    {
        m_Query = new EntityQueryBuilder(Allocator.Temp)
        .WithAllRW<TaskComponent>()
        .WithAll<BranchComponent>()
        .WithAll<WithinDistanceComponent, WithinDistanceFlag, EvaluateFlag>()
        .Build(ref state);
    }

    /// <summary>
    /// Updates the job.
    /// </summary>
    /// <param name="state">The current state of the system.</param>
    [BurstCompile]
    private void OnUpdate(ref SystemState state)
    {
        state.Dependency = new WithinDistanceJob().ScheduleParallel(m_Query, state.Dependency);
    }

    /// <summary>
    /// Job which executes the task logic.
    /// </summary>
    [BurstCompile]
    private partial struct WithinDistanceJob : IJobEntity
    {
        /// <summary>
        /// Executes the idle logic.
        /// </summary>
        /// <param name="branchComponents">An array of BranchComponents.</param>
        /// <param name="taskComponents">An array of TaskComponents.</param>
        /// <param name="withinDistanceComponents">An array of WithinDistanceComponents.</param>
        [BurstCompile]
        public void Execute(ref DynamicBuffer<BranchComponent> branchComponents, ref DynamicBuffer<TaskComponent> taskComponents, ref DynamicBuffer<WithinDistanceComponent> withinDistanceComponents)
        {
            for (int i = 0; i < withinDistanceComponents.Length; ++i) {
                var withinDistanceComponent = withinDistanceComponents[i];
                var taskComponent = taskComponents[withinDistanceComponent.Index];
                var branchComponent = branchComponents[taskComponent.BranchIndex];

                if (!branchComponent.CanExecute || (taskComponent.Status != TaskStatus.Queued && taskComponent.Status != TaskStatus.Running)) {
                    continue;
                }

                taskComponent.Status = math.distance(withinDistanceComponent.Origin, withinDistanceComponent.Target) < withinDistanceComponent.Distance ? TaskStatus.Success : TaskStatus.Failure;
                taskComponents[withinDistanceComponent.Index] = taskComponent;
            }
        }
    }
}

/// <summary>
/// A DOTS flag indicating when an WithinDistance node needs to be reevaluated.
/// </summary>
public struct WithinDistanceReevaluateFlag : IComponentData, IEnableableComponent
{
}

/// <summary>
/// Runs the WithinDistance reevaluation logic.
/// </summary>
[DisableAutoCreation]
public partial struct WithinDistanceReevaluateTaskSystem : ISystem
{
    /// <summary>
    /// Updates the reevaluation logic.
    /// </summary>
    /// <param name="state">The current state of the system.</param>
    [BurstCompile]
    private void OnUpdate(ref SystemState state)
    {
        foreach (var (taskComponents, withinDistanceComponents) in SystemAPI.Query<DynamicBuffer<TaskComponent>, DynamicBuffer<WithinDistanceComponent>>().WithAll<WithinDistanceReevaluateFlag, EvaluateFlag>()) {
            for (int i = 0; i < withinDistanceComponents.Length; ++i) {
                var withinDistanceComponent = withinDistanceComponents[i];
                var taskComponent = taskComponents[withinDistanceComponent.Index];
                if (!taskComponent.Reevaluate) {
                    continue;
                }

                var status = math.distance(withinDistanceComponent.Origin, withinDistanceComponent.Target) < withinDistanceComponent.Distance ? TaskStatus.Success : TaskStatus.Failure;
                if (status != taskComponent.Status) {
                    taskComponent.Status = status;
                    var buffer = taskComponents;
                    buffer[taskComponent.Index] = taskComponent;
                }
            }
        }
    }
}
```

---

<a id="page-behavior-designer-pro-new-tasks-event-node"></a>

# Event Node

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/event-node/)

## Start a branch from an event

Event Nodes are at the root of the branch and start the branch based on a condition. The most common event branch task is the **Start** task which automatically gets added when a task is added to the behavior tree.

![A Start event node connects to the first logic task in a behavior tree branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-event-node-start-branch.webp?v=cee48be20fce)

## Create an Event Node

Event nodes implement the `EventNode` base class. After implementing this base class, start the branch by calling `StartBranch` on the Behavior Tree component. This Event Node starts after the specified number of seconds:

```csharp
using Opsive.BehaviorDesigner.Runtime.Tasks.Events;
using Opsive.GraphDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using UnityEngine;

/// <summary>
/// Starts the branch after the specified amount of time.
/// </summary>
[AllowMultipleTypes]
public class StartBranchDelay : EventNode
{
    [Tooltip("Specifies when the brnach should start.")]
    [SerializeField] protected SharedVariable<float> m_StartDelay;

    /// <summary>
    /// Initializes the node to the specified graph.
    /// </summary>
    /// <param name="graph">The graph that is initializing the task.</param>
    public override void Initialize(IGraph graph)
    {
        base.Initialize(graph);

        m_BehaviorTree.Invoke("StartBranch", m_StartDelay.Value);
    }

    /// <summary>
    /// Starts the branch.
    /// </summary>
    private void StartBranch()
    {
        m_BehaviorTree.StartBranch(this);
    }
}
```

## Allow more than one event of the same type

Shared Variables can be used in the same way as regular behavior tree tasks. The **\[AllowMultipleTypes\]** attribute allows more than one instance of the Event Node to be added to the graph.

---

<a id="page-behavior-designer-pro-conditional-aborts"></a>

# Conditional Aborts

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/)

A conditional abort lets a running tree react to a change in a Conditional Task without reevaluating the whole tree each tick. The equivalent feature in Unreal Engine is the Observer Abort.

<iframe width="100%" height="600" src="https://www.youtube.com/embed/OhMdm7sGGWg?rel=0&amp;showinfo=0" title="Conditional aborts video" loading="lazy" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

If the embedded player is unavailable, [watch Conditional Aborts on YouTube](https://www.youtube.com/watch?v=OhMdm7sGGWg).

## How an abort interrupts a running branch

![Can See Object has failed and the Selector is running its lower-priority Idle branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-idle-running.webp?v=e6253a807e30)

**Can See Object** returns Failure because no object is in sight, so **Selector** runs its next child, **Idle**.

![Can See Object is marked for reevaluation while the lower-priority Idle branch runs.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-condition-reevaluated.webp?v=f9320d329f25)

While **Idle** runs, the object comes into sight and **Can See Object** changes to Success. With a conditional abort configured, **Can See Object** issues the abort, stops **Idle**, and traversal resumes normally from the reevaluated Conditional — here into **Seek**.

![Can See Object has changed to Success and interrupted the lower-priority Idle branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-condition-success.webp?v=b9dca7c1bfeb)

## Choose an abort type

Set **Abort Type** on the Composite that parents the Conditional. The available values are:

| Abort Type | Reevaluates while | Use it when |
| --- | --- | --- |
| **None** | Never. The Conditional is evaluated only when traversal reaches it. | The branch should run to completion once it is entered. |
| **Lower Priority** | Any Task to the right of the current branch is active. | The tree is ordered by priority and a higher-priority Conditional should preempt lower-priority work. |
| **Self** | Any Task within the current branch is active. | The branch should stop itself when its own entry condition stops holding. |
| **Both** | Any Task to the right of or within the current branch is active. | The branch should both preempt lower-priority work and stop itself. |

![A Sequence inspector has its Abort Type set to Lower Priority.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-lower-priority-inspector.webp?v=b473805810e9)

![A Sequence inspector has its Abort Type set to Both.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-both-inspector.webp?v=3360271f7d6b)

Two constraints apply to every abort type:

- Conditional aborts reevaluate Conditional Tasks only. An Action Task is never reevaluated by this system.
- An abort triggers when the Conditional changes status in either direction — Failure to Success, or Success to Failure.

Reevaluation is not free: each reevaluated Conditional runs on every tick that its abort scope is active. [Performance](https://opsive.com/support/documentation/behavior-designer-pro/performance/) covers the cost model and how **Evaluation Type** bounds the work performed per tick.

## Order a priority tree

A common structure alternates Selector and Sequence nodes, with the highest-priority branch on the far left and decreasing priority to the right. Lower Priority aborts then keep the higher-priority Conditionals live.

![Alternating Selector and Sequence branches place the highest-priority condition on the left.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-priority-layout.webp?v=1ddfe9d28544)

In this tree **Has Taken Damage** has the highest priority and is reevaluated whenever any branch to its right is active, which is set by the Lower Priority abort on its **Sequence**. If the agent has not taken damage, **Can See Object** is reevaluated while the **Within Distance** or **Patrol** branches run. **Within Distance** is in turn reevaluated for as long as **Patrol** is active.

A Conditional that is currently being reevaluated draws a circle around the execution-status icon in the upper right of the node:

![Two conditions are marked for reevaluation above a running lower-priority branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-nested-reevaluation.webp?v=dd604bbdfcd4)

## Nest aborts for either-or conditions

Aborts can be nested to run a branch when either of two Conditionals succeeds. Parent **Has Taken Damage** and **Within Distance** to a Selector with the Lower Priority abort type, then make the Action a sibling of that Selector under a Sequence. Set the Sequence to Lower Priority so both Conditionals continue to be reevaluated while an unrelated branch runs.

![Two Conditional branches can independently interrupt the lower-priority Action.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-two-conditions.webp?v=cf82b4a283b8)

To require that **both** Conditionals succeed before lower-priority branches abort, place them inside a [Stacked Conditional](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/conditional/stacked-conditional/) with a Sequence comparison type:

![A Stacked Conditional requires both contained conditions before interrupting the lower-priority branch.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-stacked-conditions.webp?v=49d4ff5a67d1)

## Run logic when an interrupt occurs

The On Interrupt [Event Task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/event-node/) runs a branch when an interrupt happens. Adding it to the first example gives:

![An On Interrupt event branch runs Log when a Conditional Abort stops Idle.](https://opsive.com/wp-content/uploads/2026/08/bdp-conditional-aborts-interrupt-event.webp?v=979415f36c38)

**On Interrupt** specifies the **Idle** Task, so **Log** runs when the conditional abort system interrupts **Idle**.

## See conditional aborts in a complete tree

[Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) uses Both aborts to leave Patrol when an enemy becomes visible and to leave Chase when visibility is lost. [Flee at Low Health](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/flee-at-low-health/) shows a higher-priority survival branch interrupting ordinary combat.

---

<a id="page-behavior-designer-pro-variables"></a>

# Variables

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/variables/)

## Share values between tasks

<iframe width="100%" height="600" src="https://www.youtube.com/embed/Lzdjb2odu84?rel=0&amp;showinfo=0" title="Behavior Designer Shared Variables video" loading="lazy" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>

If the embedded player is unavailable, [watch the Shared Variables video on YouTube](https://www.youtube.com/watch?v=Lzdjb2odu84).

Behavior tree tasks are loosely coupled: one task does not need a direct reference to another task in order to run. A Shared Variable lets those tasks intentionally exchange a value. For example, a Within Sight task can store the GameObject that it detected and a later Seek task can move toward that same object.

![Two loosely coupled tasks share a target through the same Shared Variable.](https://opsive.com/wp-content/uploads/2026/08/bdp-variables-task-sharing.webp?v=bfb928b5941a)

## Declare and create a Shared Variable

To share a value, the tasks declare a SharedVariable of the specified type:

```csharp
public SharedVariable<GameObject> m_Target;
```

With the field declared, create the matching variable in Behavior Designer. This example uses the **Graph** tab of the Shared Variables panel; see [Scope](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/) for the other tabs.

![The Shared Variables panel creates a graph variable with a selected type and name.](https://opsive.com/wp-content/uploads/2026/08/bdp-variables-create-shared-variable.webp?v=8b133e4bfb49)

Use **Add Variable** to create a value or **Add Group** to organize related rows. Drag variables and groups to reorder them. A group changes only the editor organization; it is not an additional runtime scope.

## Add a custom Shared Variable type

The Shared Variables panel can use a project-specific serializable value type or an explicit class derived from `SharedVariable<T>`. Add either custom type to **Tools > Opsive > Unit Options** after it compiles so it appears in the **Add Variable** type list.

C# rectangular arrays such as `int[,]` and jagged arrays such as `int[][]` are different types. The Behavior Designer editor does not automatically present either one as a two-dimensional grid. Use a flat serializable value when the existing array control should edit the values, or use a derived Shared Variable when the project needs a named, specialized variable type that will be populated from code or drawn by a custom Control Type.

### Wrap a grid in a serializable value

Store the cells in a one-dimensional array and translate each row and column into a flat index. Behavior Designer can draw the integer and array fields with its existing controls:

```csharp
using System;
using Opsive.GraphDesigner.Runtime.Variables;
using UnityEngine;

[Serializable]
public class IntGrid
{
    [Min(1)]
    [SerializeField] private int m_Columns = 1;
    [SerializeField] private int[] m_Values = Array.Empty<int>();

    public int Columns => m_Columns;
    public int Rows => m_Columns > 0 ? m_Values.Length / m_Columns : 0;

    public int this[int row, int column]
    {
        get => m_Values[(row * m_Columns) + column];
        set => m_Values[(row * m_Columns) + column] = value;
    }
}

public class UseIntGrid : Opsive.BehaviorDesigner.Runtime.Tasks.Actions.Action
{
    [SerializeField] protected SharedVariable<IntGrid> m_Grid;
}
```

Add `IntGrid` to Unit Options, then create an **Int Grid** Shared Variable. Keep the Values array length equal to the intended row count multiplied by Columns. Tasks can declare `SharedVariable<IntGrid>` fields and read a cell with `m_Grid.Value[row, column]`.

### Derive a named Shared Variable

An explicit Shared Variable class is useful when the variable itself should have a project-specific name or behavior. This valid declaration stores a jagged integer array:

```csharp
using Opsive.GraphDesigner.Runtime.Variables;

[System.Serializable]
public class IntGridVariable : SharedVariable<int[][]>
{
    public static implicit operator IntGridVariable(int[][] value)
    {
        return new IntGridVariable { Value = value };
    }
}
```

Add `IntGridVariable` to Unit Options, create an **Int Grid Variable**, and declare `IntGridVariable` fields on the tasks that use it. The inherited `Value` property contains the `int[][]` value:

```csharp
m_Grid.Value = new[] {
    new[] { 1, 2 },
    new[] { 3, 4 }
};

int cell = m_Grid.Value[row][column];
```

Because each row in a jagged array can have a different length, validate the row and column before indexing data supplied at runtime. The derived class makes the type available to the Shared Variable system; it does not add a nested-array editor. Prefer the flat `IntGrid` wrapper for the built-in UI, or create a [Control Type](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/control-types/) when authors need a purpose-built grid.

## Manage a variable from its row menu

Right-click a variable row in the Shared Variables panel to open its complete management menu.

| Command | When to use it |
| --- | --- |
| **Enable Property Binding / Disable Property Binding** | Connect the variable to a compatible C# property, or remove that connection. A bound variable cannot be moved to Project scope. |
| **Change Type** | Change the value type. Reassign task fields that are no longer compatible with the new type. |
| **Move To > Graph / GameObject / Scene / Project** | Move the value to another scope. Behavior Designer updates graph references, removes the row from its current group, and blocks a move that would create a destination name/type conflict. |
| **Internal** | Keep a Graph variable available to tasks in this graph while hiding it from the Behavior Tree component's configurable variables and from Subtree override lists. Runtime override lookup also ignores it. Select **Internal** again to make the variable externally configurable. |
| **Rename** | Rename the variable and update its references in this graph. |
| **Duplicate** | Create an independent copy that can be renamed or given a different value. |
| **Delete** | Remove the variable. Resolve any task fields that referred to the deleted row. |

**Internal** appears only on the **Graph** tab. It is useful for temporary counters, cached targets, and other implementation details that a Behavior Tree component or parent Subtree Reference should not override. It is not a security boundary and does not prevent tasks in the graph from reading or writing the value.

Right-click a group for **Rename**, **Duplicate**, or **Delete**. **Duplicate** creates a new empty group with a unique name; it does not duplicate the member variables. **Delete** removes only the group, and its variables remain available as ungrouped rows.

## Assign the variable to tasks

After the variable is created, assign it to a Task field. Select the Task and use the selector to the right of the field value.

![A task field is assigned to an existing graph Shared Variable.](https://opsive.com/wp-content/uploads/2026/08/bdp-variables-assign-shared-variable.webp?v=40464d795bd9)

## Reuse and expose variable types

Repeat the assignment on the **Seek** Task so both Tasks read the same value. [Accessing Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/) covers getting and setting the value from inside and outside a Task, and [Property Binding](https://opsive.com/support/documentation/behavior-designer-pro/variables/property-binding/) connects the same value to a property on a project component.

The **Add Variable** type list includes MonoBehaviours and common value types such as Int and Float. Register a project-specific type through **Tools > Opsive > Unit Options** to add it to that list.

![The Unit Options menu chooses whether a task uses GameObject or Entity data.](https://opsive.com/wp-content/uploads/2026/08/bdp-variables-unit-options.webp?v=d6d889b1b970)

Graph navigation and layout controls are documented in the [Overview](https://opsive.com/support/documentation/behavior-designer-pro/overview/). Task row menus, watched fields, and the Task Palette are documented with [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/).

Use [ECS Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/ecs/) when a Shared Variable must be registered and accessed from an ECS task.

## See Shared Variables in complete trees

[Choose the Highest-Priority Need](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/highest-priority-need/) uses values that change at runtime to choose a branch. [Patrol and Chase an Enemy](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/patrol-and-chase-an-enemy/) passes the detected enemy to the Chase task through a Shared Variable.

---

<a id="page-behavior-designer-pro-variables-accessing-variables"></a>

# Accessing Variables

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/)

## Read and write a value inside a task

Variables can be access both within the task and within your own script outside of Behavior Designer. In order to get and set the variable value within a task you can use the **Value** property. As an example:

```csharp
using Opsive.BehaviorDesigner.Runtime.Tasks;
using Opsive.BehaviorDesigner.Runtime.Tasks.Conditionals;
using Opsive.GraphDesigner.Runtime.Variables;
using UnityEngine;

public class WithinDistance : Conditional
{
    [Tooltip("The object that the agent is searching for.")]
    [SerializeField] protected SharedVariable<GameObject> m_Target;

    public override TaskStatus OnUpdate()
    {
        GameObject targetGameObject = m_Target.Value;
        if (targetGameObject == null) {
            m_Target.Value = GameObject.Find("Player");
        }
```

As long as the tasks are assigned to the same Shared Variable in the Task Inspector, the **Value** is shared across those tasks.

## Access a graph variable from a component

Variables can also be accessed by your own scripts by getting a reference to the `BehaviorTree` component:

```csharp
using Opsive.BehaviorDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using UnityEngine;

public class AccessVariable : MonoBehaviour
{
    public BehaviorTree m_BehaviorTree;

    public void Start()
    {
        SharedVariable<GameObject> target = m_BehaviorTree.GetVariable<GameObject>("Target");
        target.Value = gameObject;
    }
}
```

In the example above, the component gets the variable named **Target** and changes it through the `SharedVariable.Value` property.

## Select a variable scope

By default, `GetVariable` returns the variable that belongs to the graph. To get a variable from a different [scope](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/), add a second parameter:

```csharp
SharedVariable target = m_BehaviorTree.GetVariable("Target", SharedVariable.SharingScope.Scene);
```

The second `SharingScope` parameter is a convenient way to access variables of all of the scopes, but you can also get a reference to the `GameObjectSharedVariables`, `SceneSharedVariables`, or `ProjectSharedVariables`:

```csharp
using Opsive.BehaviorDesigner.Runtime;
using Opsive.GraphDesigner.Runtime.Variables;
using UnityEngine;

public class AccessVariable : MonoBehaviour
{
    public BehaviorTree m_BehaviorTree;
    public GameObjectSharedVariables m_GameObjectSharedVariables;
    public SceneSharedVariables m_SceneSharedVariables;

    public void Start()
    {
        var target = m_BehaviorTree.GetVariable<GameObject>("Target"); // Graph Scope.
        target = m_GameObjectSharedVariables.GetVariable<GameObject>("Target"); // GameObject Scope.
        target = m_SceneSharedVariables.GetVariable<GameObject>("Target"); // Scene Scope.
        target = ProjectSharedVariables.Instance.GetVariable<GameObject>("Target"); // Project Scope.
    }
}
```

---

<a id="page-behavior-designer-pro-variables-ecs"></a>

# ECS Variables

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/variables/ecs/)

SharedVariables can be used within ECS tasks as long as long as the SharedVariable type is unmanaged and at most 16 bytes. The steps below show how to use a SharedVariable within an ECS task. This variable will be a SharedVariable\<Entity>.

## Declare the Variable

Use the same SharedVariable\<T> pattern as non-ECS tasks. The biggest change from non-ECS tasks are that the variable must be registered within the ECSVariableRegistry. This registry is a parameter to the AddBufferElement method. The index is stored so the variable can be retrieved later on within the task.

```csharp
[Tooltip("The entity that should be targeted.")]
[SerializeField] SharedVariable<Entity> m_TargetEntity;

private ECSSharedVariableIndex<Entity> m_TargetEntityIndex;

/// <summary>
/// Registers the target SharedVariable and adds the buffer element to the entity.
/// </summary>
/// <param name="world">The world that the entity exists in.</param>
/// <param name="entity">The entity that the IBufferElementData should be assigned to.</param>
/// <param name="registry">The ECS variable registry for registering SharedVariable fields.</param>
/// <param name="gameObject">The GameObject that the entity is attached to.</param>
/// <returns>The index of the element within the buffer.</returns>
public override int AddBufferElement(World world, Entity entity, ECSVariableRegistry registry, GameObject gameObject)
{
   m_TargetEntityIndex = new ECSSharedVariableIndex<Entity>(registry.Register(m_TargetEntity));
   return base.AddBufferElement(world, entity, registry, gameObject);
}
```

## Store the Buffer Index

Systems need a stable integer index into SharedVariableElement. Persist it on your per-task component:

```csharp
public override FindTargetComponent GetBufferElement()
{
   return new FindTargetComponent()
   {
      Index = RuntimeIndex,
      TargetEntityVariableIndex = m_TargetEntityIndex.Index,
   };
}

/// <summary>
/// The DOTS data structure for the FindTarget struct.
/// </summary>
public struct FindTargetComponent : IBufferElementData
{
      [Tooltip("The index of the node.")]
      public ushort Index;
      [Tooltip("Buffer index into SharedVariableElement for the target entity.")]
      public int TargetEntityVariableIndex;
}
```

## Query the Buffer

Include DynamicBuffer\<SharedVariableElement> in the query (alongside your task buffer and flags). The variable can be read with buffer.Get\<T>(index) or written with buffer.Set(index, value):

```csharp
foreach (var (branchComponents, taskComponents, findTargetComponents, sharedVariables) in
SystemAPI.Query<DynamicBuffer<BranchComponent>, DynamicBuffer<TaskComponent>, DynamicBuffer<FindTargetComponent>, DynamicBuffer<SharedVariableElement>>().WithAll<FindTargetFlag, EvaluateFlag>()) {
   for (int i = 0; i < findTargetComponents.Length; ++i) {
      var fndTargetComponent = findTargetComponents[i];
      // ...
      // Store the found target in the shared variable buffer.
      if (foundAgent) {
         targetEntity = entities[index];
      }
      sharedVariables.Set(fndTargetComponent.TargetEntityVariableIndex, targetEntity);
```

---

<a id="page-behavior-designer-pro-variables-scope"></a>

# Scope

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/)

Variable scope determines who owns a Shared Variable value and which behavior trees can read or change it. Use Graph scope for per-agent runtime state, GameObject scope to share between trees on one object, Scene scope for one loaded scene, and Project scope for intentionally global data.

The Shared Variables panel exposes the four persistent scopes as tabs:

![The Shared Variables scope tabs are Graph, GameObject, Scene, and Project.](https://opsive.com/wp-content/uploads/2026/08/bdp-variable-scope-tabs.webp?v=cd55b08b7209)

## Choose the narrowest owner

| Scope | Runtime owner | Who can access it | Typical use |
| --- | --- | --- | --- |
| **Graph** | One Behavior Tree component's runtime graph instance | Tasks in that graph, including loaded Subtrees | Per-agent targets, counters, state, and other values that must not leak to another agent. This is the normal default. |
| **GameObject** | `GameObjectSharedVariables` on the same GameObject | Behavior trees that resolve that GameObject variable container | A locomotion tree and a combat tree on one NPC sharing the same current target. |
| **Scene** | `SceneSharedVariables` in the loaded scene | Behavior trees that resolve that scene container | A scene alarm, encounter phase, or shared objective that resets with the scene. |
| **Project** | `ProjectSharedVariables` ScriptableObject | Any behavior tree that resolves the project container | Deliberately global configuration or runtime state. Avoid it for per-agent values. |

By default, the Project asset is created below `Assets/Opsive/GraphDesigner/Resources/ProjectSharedVariables`. It can move, but it must remain below a `Resources` folder so the runtime can load it.

Prefer the narrowest scope that includes every real consumer. Moving a convenience value to Scene or Project scope can hide an ownership mistake by making unrelated agents share it.

## Keep a Graph variable internal

**Internal** is a visibility and override rule for a Graph variable, not a fifth persistent scope. Right-click the variable row and select **Internal** when the value is an implementation detail such as a temporary target, counter, or cached result.

An Internal Graph variable:

- remains available to Tasks in its graph;
- is hidden from the Behavior Tree component's configurable variable list;
- is omitted from Subtree override lists; and
- is ignored by external runtime override lookup.

Select **Internal** again to expose the variable. Use this instead of a Dynamic Variable when the graph needs a declared, strongly typed value that supports the normal variable selector and task tooling but should not invite configuration from the component Inspector.

The complete variable-row menu, including **Move To**, **Rename**, **Duplicate**, and **Delete**, is documented on [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/).

## Reuse a Subtree without sharing Graph values

A Subtree asset is reusable authoring data. Multiple Behavior Tree components can reference the same Subtree asset while keeping separate runtime Task and Graph-variable instances.

For the normal runtime-assignment route, assign the asset directly:

```csharp
behaviorTree.StopBehavior();
behaviorTree.Subgraph = npcDefinition.subtree;
behaviorTree.StartBehavior();
```

Do not instantiate and manually deserialize the Subtree for ordinary reuse. That API is for explicit pooling. If a project uses it, each concurrently running Behavior Tree must receive its own instance:

```csharp
var runtimeSubtree = Object.Instantiate(subtreeAsset);
runtimeSubtree.Deserialize();
runtimeSubtree.Pooled = true;
behaviorTree.Subgraph = runtimeSubtree;
```

Never assign one deserialized pooled instance to two concurrently running agents. See [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) for variable overrides, reevaluation, and the complete pooling example.

**Checkpoint:** run two NPCs that reference the same Subtree asset. Change a Graph-scoped value on one NPC and confirm that the other NPC's value does not change.

## Use Dynamic Variables for short-lived connections

Dynamic Variables do not appear as a tab in the Shared Variables panel. Create one from a compatible Task field's variable selector by choosing **Dynamic**, selecting its value type when the field is abstract, and entering a name.

![A task field menu selects Dynamic to create a temporary Shared Variable.](https://opsive.com/wp-content/uploads/2026/08/bdp-variable-scope-dynamic-selection.webp?v=048cf053ccc0)

![A Dynamic Shared Variable field is assigned a case-sensitive name.](https://opsive.com/wp-content/uploads/2026/08/bdp-variable-scope-dynamic-name.webp?v=a9986d51a89e)

Dynamic Variables are still strongly typed. Fields with the same case-sensitive Dynamic name share a value only when they use the same value type. Do not reuse the name of a declared variable, and do not use the same Dynamic name with different types.

Choose between Dynamic and Internal Graph variables by workflow:

| Need | Use |
| --- | --- |
| A short-lived connection between a few compatible Task fields, with no row in the Shared Variables panel | **Dynamic Variable** |
| Declared runtime state that should be easy to inspect, select, compare, and refactor but hidden from component and Subtree overrides | **Internal Graph variable** |
| A value that designers should override on a Behavior Tree component or parent Subtree Reference | Non-Internal **Graph variable** |

When a Conditional or Action expects an abstract `SharedVariable`, the current field control provides a value-type picker before the Dynamic name. A Task whose field is a concrete value type remains limited to that compatible type.

## Access an explicit scope from code

`GetVariable` reads Graph scope by default:

```csharp
SharedVariable<GameObject> target = behaviorTree.GetVariable<GameObject>("Target");
```

Pass an explicit sharing scope when the caller intends to read another owner:

```csharp
SharedVariable target = behaviorTree.GetVariable(
    "Target",
    SharedVariable.SharingScope.Scene);
```

You can also query `GameObjectSharedVariables`, `SceneSharedVariables`, or `ProjectSharedVariables.Instance` directly. [Accessing Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/) contains the complete examples.

Do not rely on an implicit search across several scopes. Make the owner explicit in code and keep names unique enough that a debugger can distinguish `Target` on the agent from `Target` in the scene.

## Verify scope and persistence

1. Create a Graph variable named `Target` on an NPC tree and mark it **Internal**.
2. Assign it to a producer Task and a consumer Task.
3. Run two NPCs that use the same graph or Subtree asset. Give them different targets and confirm that each tree retains its own value.
4. Confirm that `Target` is absent from the Behavior Tree component and Subtree override lists but visible in the graph's Shared Variables panel.
5. Move a disposable test value to GameObject scope and confirm that a second tree on the same GameObject can read it.
6. Save, restart Unity, and reopen the graph. Confirm that each declared variable keeps its name, value type, scope, Internal state, and Task assignments.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Every spawned NPC receives the same runtime value | The variable's scope and whether the project assigns one pooled runtime Subtree instance to several agents | Use Graph scope and assign the shared Subtree asset directly. For pooling, give every concurrent Behavior Tree its own deserialized pooled instance. |
| A Graph variable appears as an editable component value or Subtree override | The variable's **Internal** row option | Mark implementation-only Graph variables **Internal**. |
| A Task cannot select the intended Dynamic Variable | The field's value type and the Dynamic type picker | Choose a matching type. A concrete field accepts only its declared type; an abstract Shared Variable field requires a type selection. |
| Two Dynamic fields with the same name do not share a value | Name casing and value type | Use the exact same case-sensitive name and type on both fields. |
| A Dynamic name conflicts after deleting a declared variable | A declared variable or another Dynamic field still uses the same name | Use distinct names, save the graph, and restart the editor after changing the variable model. If the conflict remains reproducible in the current release, preserve the asset and report it. |
| Variable names or Task assignments disappear after saving or reopening | Installed product version, assigned Subtrees, and the smallest graph that reproduces the loss | Update to the current release, restore the last clean asset from version control, and send the affected graph or Subtree plus reproduction steps to support. Do not hide the issue by repeatedly creating numbered names. |
| A Scene or Project value unexpectedly affects unrelated agents | The value was placed in a broader owner than its consumers require | Move it to Graph or GameObject scope and update its Task assignments. |

## Related pages

- Variable setup and code access: [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/), [Accessing Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/), [Property Binding](https://opsive.com/support/documentation/behavior-designer-pro/variables/property-binding/), and [ECS Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/ecs/).
- Runtime reuse and upgrades: [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) and [Updating and Migration](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/updating-and-migration/).

---

<a id="page-behavior-designer-pro-variables-property-binding"></a>

# Property Binding

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/variables/property-binding/)

<div class="woocommerce-message docs-info">See the PropertyBinding sample scene for an example of using property bindings.</div>

## Bind a Shared Variable to a property

A property binding maps a Shared Variable to a C# property on a project component, so both the tree and the component read and write one value. Given this component:

```csharp
public class Health : MonoBehaviour
{
    [Tooltip("The starting health value")]
    [SerializeField] protected float m_StartHealth = 100;

    private float m_HealthAmount;

    public float HealthAmount { get => m_HealthAmount; set => m_HealthAmount = value; }
}
```

Right-click the Shared Variable row in the Shared Variables panel and select **Enable Property Binding**, then choose the object and property:

![A Shared Float named Health is bound to the Health property on a component.](https://opsive.com/wp-content/uploads/2026/08/bdp-property-bindings-health.webp?v=ab121286f6ec)

## Keep both sides synchronized

Once bound, reading or writing the variable's `Value` calls the bound property's getter or setter instead of using the variable's own stored value. No copy step or manual synchronization is required.

The binding is resolved when the Shared Variable initializes, and the getter and setter are cached as delegates rather than invoked through reflection on each access.

## Requirements

- The target must be a **public instance property**. Fields are not supported.
- The property must expose both a **public getter and a public setter**. A read-only or write-only property cannot be bound.
- The property type must match the Shared Variable type.
- A bound variable cannot be moved to Project scope.

If the bound type, property, getter, or setter cannot be resolved at initialization, Behavior Designer logs the reason and the variable falls back to its own stored value. Check the Console when a bound variable appears to hold a stale value.

## Related pages

- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Accessing Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/)
- [Scope](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/)

---

<a id="page-behavior-designer-pro-entity-baking"></a>

# Entity Baking

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/entity-baking/)

[Entity baking](https://docs.unity3d.com/Packages/com.unity.entities@1.3/manual/baking.html) converts authoring data into ECS runtime data. The Behavior Tree component includes a baker, so an enabled tree is baked with its GameObject or prefab; you do not need to convert its tasks manually.

## Choose when the tree starts

If **Start When Enabled** is enabled on the Behavior Tree component, a baked tree starts automatically when its entity becomes available. This is the usual choice for agents that should begin immediately after a subscene loads or a prefab is instantiated.

If **Start When Enabled** is disabled, the entity is created with a deferred start. Start that specific tree when your gameplay is ready:

```csharp
BehaviorTree.StartBakedBehaviorTree(world, entity);
```

The method returns `true` when it starts the deferred tree. Calling `EnableBakedBehaviorTreeSystem` is no longer required; baked startup now runs automatically.

## Spawn baked behavior tree prefabs

Put the Behavior Tree component on the prefab and reference that prefab from an authoring component in a subscene. Its baker can turn the prefab reference into an entity prefab:

```csharp
public override void Bake(EntitySpawner authoring)
{
    if (authoring.m_SpawnData == null || authoring.m_SpawnData.Prefab == null) {
        return;
    }

    var spawner = GetEntity(TransformUsageFlags.Dynamic);
    var prefab = GetEntity(authoring.m_SpawnData.Prefab, TransformUsageFlags.Dynamic);
    AddComponent(spawner, new EntitySpawnerPrefab { Prefab = prefab });
}
```

Your ECS system can then instantiate as many copies as it needs. Each copy already contains the baked behavior tree data:

```csharp
var entities = state.EntityManager.Instantiate(
    spawner.Prefab,
    spawner.SpawnCount,
    Allocator.Temp);
```

After instantiation, set any per-agent components such as position, movement speed, or team. Trees with **Start When Enabled** begin automatically. For a tree with deferred start, call `StartBakedBehaviorTree` for that entity after its setup is complete.

## Debug a baked tree

In the Unity Editor, Behavior Designer stores an editor-only link from each baked entity to its authoring graph. Select the running tree in the Behavior Designer window to inspect its execution just like a regular tree. This debugging metadata is removed from player builds.

The **Entities Scene** sample contains the complete `EntitySpawner` authoring component and system used by these examples.

---

<a id="page-behavior-designer-pro-events"></a>

# Events

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/events/)

## Send and receive an event in a tree

The event system within Behavior Designer allows your behavior trees to easily react to changes. This event system can trigger an event via code or through behavior tree tasks. Events can be invoked through the behavior tree with the **Send Event** and the **Has Received Event** tasks. The **Send Event** task should be used when the event should be invoked. The **Has Received Event** task is a conditional task and will return success as soon as the event has been received. An event name can be specified for both of these tasks. In order to properly receive the events the **Has Received Event** task should be reevaluated with conditional aborts. For example:

![Has Received Event is reevaluated after Send Event fires while another branch is running.](https://opsive.com/wp-content/uploads/2026/08/bdp-events-reevaluation-runtime.webp?v=7085f2cf6770)

During the first tick the **Has Received Event** task will fail because the event has not been received yet. The **Selector** will then move to the right branch and the **Wait** task will start. After a second the **Send Event** Task will send the event and then **Idle** is started to keep the tree active. During the next tick the **Has Received Event** task returns a status of success because of the previous event that was sent. In addition to being able to send events via the behavior tree tasks, events can be sent through code. The `EventHandler.ExecuteEvent` method will allow you to send an event to the specified object. For example:

## Send an event from code

```csharp
using Opsive.Shared.Events;

var behaviorTree = GetComponent<BehaviorTree>();
EventHandler.ExecuteEvent<object>(behaviorTree , "MyEvent", 5);
```

In this example the "MyEvent" event will be sent to the behavior tree component with a parameter value of 5. If the behavior tree contains the **Has Received Event** task then it will react accordingly. If the **Has Received Event** task is receiving event then the template type must be a valid of object: `EventHandler.ExecuteEvent<object>`. You are also able to receive events from outside the behavior tree. To continue with the "MyEvent" example, you can receive this event by using the `EventHandler.RegisterEvent` method. `EventHandler.UnregisterEvent` will stop listening for that event.

## Receive an event in code

```csharp
using Opsive.Shared.Events;

public void OnEnable()
{
   var behaviorTree = GetComponent<BehaviorTree>();
   EventHandler.RegisterEvent<object>(behaviorTree, "MyEvent", ReceivedEvent);
}

public void ReceivedEvent(object arg1)
{

}

public void OnDisable()
{
   var behaviorTree = GetComponent<BehaviorTree>();
   EventHandler.UnregisterEvent<object>(behaviorTree, "MyEvent", ReceivedEvent);
}
```

## See events in a complete tree

[React to an Event](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/react-to-event/) shows how a sender and an Event branch work together without polling the main Start branch.

---

<a id="page-behavior-designer-pro-subtrees"></a>

# Subtrees

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/)

Subtrees store the behavior tree data within a ScriptableObject allowing you to swap out behaviors on the same GameObject. Subtrees can also be nested within the behavior tree using the **Subtree Reference** task.

## Choose how to create the Subtree

Behavior Designer Pro exposes two different editor workflows:

| Workflow | Result |
| --- | --- |
| **Export** in the operations toolbar | Copies the entire current graph into a new Subtree asset. The source graph remains unchanged. Use this when the whole graph should become a reusable asset or be assigned to a Behavior Tree component. |
| Right-click a task selection and choose **Save as Subtree** | Extracts a branch into a new Subtree asset and replaces that branch with a Subtree Reference. Use this while refactoring part of an existing tree. |

### Save a selected branch as a Subtree

1. Select one or more logic tasks in the branch that should become reusable. Event nodes cannot be included.
2. Right-click the selection and choose **Save as Subtree**.
3. Choose the asset path and name.
4. Inspect the new Subtree Reference and its variable overrides, then open the Subtree asset to confirm the exported branch.

The selected tasks identify the branch root; they are not necessarily the exact set that will be exported. With multiple tasks selected, Behavior Designer finds their lowest common ancestor and saves that task plus all of its descendants. The command is available only when the selection has a common branch and contains at least one logic task.

After the save, the source branch is replaced by a Subtree Reference. Shared Variables that are externally configurable can be exposed as overrides on the reference. A Graph variable marked **Internal** remains usable inside the Subtree but is intentionally omitted from those override controls. See [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) for the **Internal** command.

**Checkpoint:** the parent tree contains one Subtree Reference where the branch used to be, opening the asset shows the expected ancestor and descendants, and the parent tree still reaches the same behavior through that reference.

## Subtree Reference Task

The **Subtree Reference** task allows you to specify one or more subtrees that should be loaded when the graph is initialized. By default the **Subtree Reference** task will load all of the subtrees specified within the **Subtrees** field. You can also achieve more dynamic functionality by either inheriting the `SubtreeReference` class or implementing the **ISubtreeReference** interface. Below is an example of a dynamic **Subtree Reference** task that will load a random subtree:

```csharp
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using Opsive.BehaviorDesigner.Runtime;
using Opsive.GraphDesigner.Runtime;
using UnityEngine;

public class RandomSubtreeReference : SubtreeReference
{
    private Subtree[] m_Selection;

    public override Subtree[] Subtrees => m_Selection != null ? m_Selection : m_Subtrees;

    /// <summary>
    /// Performs any runtime operations to evaluate the array of subtrees that should be returned.
    /// </summary>
    public override void EvaluateSubtrees()
    {
        if (m_Subtrees == null || m_Subtrees.Length == 0) {
            return;
        }

        m_Selection = new Subtree[] { m_Subtrees[Random.Range(0, m_Subtrees.Length)] };
    }
}
```

Before the subtree is retrieved the `EvaluateSubtrees` method is invoked allowing for a new subtree to be selected. The **Subtrees** property is then called to retrieve the subtree that should be loaded. In the example above the **m\_Selection** array is populated when `EvaluateSubtrees` is called and then that reference is returned when the **Subtrees** property is called.

## Variable Overrides

When a subtree is assigned to the **Subgraph** field of the Behavior Tree component the graph variables added to the subtree will automatically be added to your Behavior Tree component. This allows you to override the subtree variable with a value local to that graph. The variable name and type are not editable because it needs to match the same variable on the subtree.

![A Behavior Tree component exposes variables that can override values in its assigned subtree.](https://opsive.com/wp-content/uploads/2026/08/bdp-subtrees-variable-overrides-component.webp?v=d1f7a5aa2afa)

Variables can also be overridden using the **Subtree Reference** task. Within the **Subtree Reference** task inspector you'll have a similar override interface:

![A Subtree Reference task exposes the subtree variables that this branch can override.](https://opsive.com/wp-content/uploads/2026/08/bdp-subtrees-variable-overrides-task.webp?v=f4a33da98fdc)



## Reevaluation

When the behavior tree is loaded the **Subtree Reference** task replaced by the subtree nodes. If you have a **Subtree Reference** task that should switch out its functionality you can call the `BehaviorTree.ReevaluateSubtreeReferences` method and all **Subtree References** will have their `EvaluateSubtrees` method called and subsequently the **Subtrees** property in order to load the new subtrees.

<div class="woocommerce-message docs-info">See the RuntimeBehavior sample scene for an example of subclassing the SubtreeReference task and reevaluating the tree.</div>

## Pooling

Subtrees can be pooled for better performance when switching between many subtrees. When the subtree is instantiated the **Deserialize** method should be called to deserialize the tree. Ensure the **Pooled** property is also set to true after the tree is deserialized. This will ensure Behavior Designer knows that it should not duplicate any of the instantiated tasks. Pooled subtrees can then be assigned to the behavior tree component just like regular subtrees. For example:

Pooling is not required when several Behavior Tree components reuse the same authored Subtree asset. Assign that asset directly and each component receives its own runtime Task and Graph-variable state. Use the pooling API only when the project explicitly manages instantiated runtime Subtrees, and never give one pooled instance to two concurrently running Behavior Tree components.

```csharp
using Opsive.BehaviorDesigner.Runtime;
using UnityEngine;

public class SubtreePooler : MonoBehaviour
{
    [Tooltip("A reference to the behavior tree that the subtree should be assigned to.")]
    public BehaviorTree m_BehaviorTree;
    [Tooltip("The subtree that should be pooled.")]
    public Subtree m_Subtree;
    [Tooltip("Specifies how large the pool should be.")]
    public int m_PoolSize = 5;

    private Subtree[] m_SubtreePool;
    private int m_Index;

    /// <summary>
    /// Pools the subtrees.
    /// </summary>
    private void Awake()
    {
        m_SubtreePool = new Subtree[m_PoolSize];
        for (int i = 0; i < m_PoolSize; ++i) {
            m_SubtreePool[i] = Object.Instantiate(m_Subtree);
            m_SubtreePool[i].Deserialize();
            m_SubtreePool[i].Pooled = true;
        }
    }

    /// <summary>
    /// Assigns a new pooled subtree to the behavior tree.
    /// </summary>
    public void Assign()
    {
        m_BehaviorTree.Subgraph = m_SubtreePool[m_Index];
        m_Index = (m_Index + 1) % m_PoolSize;
    }
}
```

## See subtrees in a complete tree

[Switch Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/concepts/common-behaviors/switch-subtrees/) compares a fixed Subtree Reference with choosing or replacing a subtree at runtime.

For graph navigation, connection layout, panels, and shortcuts, see the [Overview](https://opsive.com/support/documentation/behavior-designer-pro/overview/). Task-specific row and Inspector controls are documented with [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/).

When a tree does not start or chooses the wrong branch, use [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/), which begins with the Error Window and continues through Play Mode status and variable inspection.

---

<a id="page-behavior-designer-pro-debugging"></a>

# Debugging

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

Use this guide when a behavior tree does not start, chooses the wrong branch, remains Running, or uses an unexpected value. Start with the Error Window, then diagnose execution status and data in Play Mode.

## Start with the Error Window

Open **Tools > Opsive > Behavior Designer > Error Window**, select the status-bar error count, or press **Ctrl/Cmd+E**. Select an error to identify its Task in the graph.

Resolve structural errors before entering Play Mode:

1. Confirm that Start connects to the intended root Task.
2. Connect required children to every Composite and Decorator.
3. Assign required fields and object references.
4. Confirm that referenced Subtrees and Shared Variables exist.
5. Clear Console compile errors, because an incomplete script can remove a Task type or field from the graph.

A clean Error Window means the editor found no known structural or serialized-field problem. It does not prove that the gameplay conditions or values are correct.

## Watch the tree in Play Mode

Keep the editor open while entering Play Mode. Task borders and status show which branch is active and whether a Task is Running, Success, or Failure.

![Can See Enemy has succeeded and Chase Enemy is running while Patrol is inactive.](https://opsive.com/wp-content/uploads/2026/08/bdp-patrol-and-chase-an-enemy-chase-running.webp?v=95dc2aa3c05f)

Read from the root toward the expected Task:

- If no Task activates, inspect the owner, component, and Start connection.
- If traversal stops early, inspect the first Task that reports Failure.
- If a later branch never runs, inspect the earlier Selector child that is succeeding or remaining Running.
- If a Sequence stops, inspect the child that failed.
- If a Task never finishes, inspect its completion condition and cancellation path.

Pause Play Mode when the relevant state is visible. Use the available step controls when the selected runtime supports them.

## Inspect values

Select the active Task and inspect its fields. Use a field's watch icon to show a supported live value on the node. Then inspect the Shared Variables panel and confirm:

- the expected variable name and type;
- the intended Graph, GameObject, Scene, or Project scope;
- whether the field is using a Shared Variable or a direct value;
- whether the variable is Internal, read-only, or dynamically resolved; and
- whether another Task, property binding, or script changes it before the decision.

Do not repair a value problem by duplicating similarly named variables. Follow [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) and [Variable Scope](https://opsive.com/support/documentation/behavior-designer-pro/variables/scope/) to identify the owner.

## Diagnose common symptoms

| Symptom | Check | Fix |
| --- | --- | --- |
| The graph never starts. | Selected GameObject, enabled Behavior Tree component, active GameObject, Start connection, and Console errors. | Select or enable the correct owner, connect Start, and resolve compilation errors. |
| The tree starts on the wrong object. | GameObject and Behavior Tree selections in the operations toolbar. | Choose the intended GameObject and component; use the lock control while inspecting other objects. |
| A Task is skipped. | Disabled state, parent Composite rules, and an earlier sibling's result. | Enable it and correct the parent flow or sibling order. |
| A Selector never reaches its fallback. | An earlier child remains Running or succeeds every tick. | Inspect that child's completion/result and reorder only when priority should change. |
| A Sequence stops before the final Action. | The first failed child. | Correct the failing condition or wrap optional work in the intended fallback structure. |
| A Conditional Abort does not react. | Abort type, reevaluation range, Shared Variable value, and whether the branch is eligible. | Follow [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) and watch the Conditional's live inputs. |
| A Subtree uses the wrong target. | Override mappings, source variable name/type, and runtime replacement. | Correct the mapping on the Subtree Reference and reopen the referenced asset. |
| A value differs between editor and runtime. | Scope, property binding, scene reload, and the script that writes the value. | Inspect the owning scope and binding before changing the Task. |
| The tree works in editor but not a build. | Scene/build inclusion, stripped types, baking, and referenced assets. | Reproduce in a development build and preserve the referenced Task, Subtree, and data assets. |

## Reduce the graph safely

When the source is still unclear, duplicate the owner or work in a test scene. Disable one branch at a time, replace a project Action with Log, and use fixed values instead of live variables. Stop when the smallest graph reproduces the issue.

Restore one dependency at a time. This distinguishes graph flow from component, input, animation, navigation, or networking behavior without destroying the original tree.

## Related pages

- [Overview](https://opsive.com/support/documentation/behavior-designer-pro/overview/) covers editor controls and status surfaces.
- [Flow](https://opsive.com/support/documentation/behavior-designer-pro/concepts/flow/) explains success, failure, and running traversal.
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/) routes to Task-specific behavior.
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/) and [Property Binding](https://opsive.com/support/documentation/behavior-designer-pro/variables/property-binding/) cover shared data.
- [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) covers reevaluation.
- [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) covers extraction, overrides, and runtime references.

---

<a id="page-behavior-designer-pro-performance"></a>

# Performance

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/performance/)

Behavior Designer Pro runs tree traversal as Burst-compiled jobs over Entities. This page covers what that architecture costs, which settings bound the per-tick work, and how to measure a result that reflects a player build rather than the Editor.

## How a tree is executed

Traversal is not performed by the Behavior Tree component. The component owns the graph data and an entity; the traversal systems evaluate that entity as part of the DOTS system groups.

| Stage | What runs | Threading |
| --- | --- | --- |
| Before traversal | Reevaluation of Conditionals marked by a conditional abort | Burst-compiled jobs |
| Traversal | Branch and Task status evaluation | Burst-compiled `IJobEntity` scheduled with `ScheduleParallel` |
| Task execution | GameObject Task logic | Managed code on the main thread |
| Cleanup | Entity command buffer playback and flag removal | Burst-compiled jobs |

Trees are evaluated in parallel across entities, so cost scales with the number of Tasks actually evaluated rather than with the number of agents alone. An agent whose tree is parked on a single Running Task is far cheaper than an agent reevaluating a wide branch each tick.

## Measure in the Editor and confirm in a build

The traversal, before-traversal, and cleanup systems are Burst-compiled in the Editor as well as in a player build, so Editor timings reflect the same compiled traversal code that ships.

The Editor still carries overhead that a build does not: collections and job safety checks, Entities journaling when enabled, and the graph window's own runtime rendering while a tree is open. Close the Behavior Designer window when taking measurements, and confirm final numbers in a development player build.

If traversal timings look unexpectedly slow, check that **Jobs > Burst > Enable Compilation** is on. Disabling it makes every Burst job fall back to managed execution.

## Bound the work with Evaluation Type

**Evaluation Type** on the Behavior Tree component determines how much of a tree may be traversed in one tick.

| Evaluation Type | Behavior | Use it when |
| --- | --- | --- |
| **Entire Tree** | Traversal continues until every branch returns Running or the tree completes. | The tree is small, or a decision must resolve within the same frame. |
| **Count** | Traversal stops after **Max Evaluation Count** Tasks have been evaluated and resumes on the next tick. | A large tree would otherwise produce a spike, or per-frame cost must stay bounded across many agents. |

**Max Evaluation Count** accepts `1` through `65535`. Setting Count mode spreads a deep traversal across several frames, which trades decision latency for a flatter frame time. Evaluation always ends early once all branches return Running, so Count mode adds no cost to a tree that is already parked.

## Control when a tree ticks

**Update Mode** selects between the two runtime cadences:

- **Every Frame** evaluates the tree on each system-group update.
- **Manual** evaluates only when project code calls `Tick()`. Calling `Tick()` while Update Mode is not Manual logs a warning and does nothing.

Manual mode is the most direct way to reduce cost for agents that do not need frame-rate decisions. Distant or inactive agents can be ticked on a timer, on a staggered schedule, or in response to a gameplay event rather than every frame.

## GameObject Tasks and Entity Tasks

Both routes use the same Burst-compiled traversal. They differ in what happens when a Task's own logic runs.

| | GameObject Task | Entity Task |
| --- | --- | --- |
| Task logic | Managed C# on the main thread | Burst-compiled job code |
| Shared Variable access | Values are synchronized between ECS and managed storage around execution | Read and written directly as component data |
| Best suited to | Component-based gameplay, moderate agent counts | Large agent counts and data-oriented gameplay |

The synchronization step is the main additional cost of a GameObject Task: ECS-backed Shared Variables are copied to their managed values before the Task runs and flushed back afterward. The sync happens once per entity per pass rather than once per Task, so a tree with several GameObject Tasks does not pay the cost repeatedly in the same pass.

This does not make GameObject Tasks a bad default. Choose them for ordinary component-based gameplay and move a behavior to Entity Tasks when profiling a build shows that its Task execution, not its traversal, is the bottleneck. [GameObject or Entity Tasks](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/) covers the authoring differences.

## Keep conditional aborts scoped

A conditional abort keeps its Conditional live: a Conditional under a Lower Priority abort is reevaluated on every tick that any branch to its right is active, and Both widens that to the branch itself. This is the intended cost of a reactive tree, but it is easy to apply more broadly than needed.

- Prefer the narrowest abort type that produces the required reaction. Self is cheaper than Both when lower-priority preemption is not needed.
- Put expensive Conditionals — raycasts, physics queries, large searches — behind a cheaper Conditional so the expensive one is reached less often.
- Use None on branches that should complete once entered.

[Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/) explains the reaction semantics that these choices control.

## Tree size and memory layout

Each tree entity stores its evaluation state as a bitmask sized from the Task count when the tree starts. The runtime selects one of five fixed-capacity components, so a tree crossing a size boundary moves to a larger archetype and fits fewer entities per chunk.

The smallest tier covers trees up to 191 Tasks, which is comfortably above a typical authored tree. Count mode reserves one additional element for the execution count, lowering that tier's ceiling to 127 Tasks. The larger tiers extend well beyond any practical tree size.

For a large behavior library, prefer several focused trees or [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) over one very large graph. That keeps the common agents in the smallest tier and makes the graphs easier to reason about.

## What to profile

1. Close the Behavior Designer window, then profile in the Editor for iteration and in a development player build for final numbers.
2. In the Profiler's Timeline view, confirm that the traversal jobs are spread across worker threads. A single-threaded traversal usually means only one tree is being evaluated.
3. Use the Entities **Systems** window to identify which Behavior Designer system is consuming time, and confirm that trees which should be idle are not scheduling work.
4. Check main-thread time separately. GameObject Task logic and the Shared Variable sync run there, so a main-thread spike points at Task implementations rather than traversal.
5. Compare a representative agent count rather than one agent. Parallel traversal shows its benefit only across many entities.

## Related pages

- [Conditional Aborts](https://opsive.com/support/documentation/behavior-designer-pro/conditional-aborts/)
- [GameObject or Entity Tasks](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/)
- [Entity Baking](https://opsive.com/support/documentation/behavior-designer-pro/entity-baking/)
- [Subtrees](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-syncing-animations"></a>

# Syncing Animations

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/syncing-animations/)

## Drive an Animator from the tree

Behavior Designer includes a set of Animator tasks which allow you to play animations within the tree. Consider the tree below:

![An Animator blend tree changes between Idle and Run using a Speed parameter.](https://opsive.com/wp-content/uploads/2026/08/bdp-syncing-animations-blend-tree.webp?v=744782c6af07)

This is an extremely simple Animator Controller that uses a blend tree to blend between the Idle and Run state based on the **Speed** parameter. If you'd like to then sync this blend tree with the **Seek** task your behavior tree would then look similar to:

![Set Float tasks change the Speed parameter before and after the movement task.](https://opsive.com/wp-content/uploads/2026/08/bdp-syncing-animations-speed-tasks.webp?v=49938adee04d)

## Keep animation logic outside the tree

Before the **Seek** task starts the **Speed** parameter is set to 1 so the blend tree can play the run animation. After the **Seek** task completes the **Speed** parameter is then set to 0 to play the Idle animation again. With a small behavior tree and Animator Controller this process works well. However, as the amount of animations grow for your agent this method starts to become extremely cumbersome. In addition, your behavior tree also starts to become extremely verbose with all of the Animator tasks and if you change a transition within your Animator Controller you'd have to rework the behavior tree to work with that Animator Controller change. There is a better way. The recommended approach to syncing animations within your behavior tree is to not sync the animations at all within the behavior tree. Instead your agent's character controller should do it for you. Using Unity's NavMeshAgent as an example, when the behavior tree sets the NavMeshAgent destination (such as with the **Seek** task) the NavMeshAgent's velocity will change to move towards the destination. The character controller should then use the velocity and translate the movements into parameters that the Animator Controller can understand. Unity's documentation contains a [recommended implementation](https://docs.unity3d.com/Packages/com.unity.ai.navigation@1.1/manual/CouplingAnimationAndNavigation.html) of this with the NavMeshAgent. The AnimationSync sample scene included with Behavior Designer includes a script similar to this. The advantage of this approach is that your behavior tree is then not aware of the animations at all and it can even work with [root motion](https://docs.unity3d.com/Manual/RootMotion.html). You also don't over-complicate your tree with Animator tasks and makes your tree a lot cleaner. The [Ultimate Character Controller](https://assetstore.unity.com/packages/slug/233710?aid=1100lGdc) uses this approach and for that asset we created a pretty large behavior tree. You can see the behavior tree on [this page](https://opsive.com/support/documentation/behavior-designer/integrations/opsive-character-controllers/) and you'll notice that there are no Animator tasks within the tree. A bridge component is linking the NavMeshAgent's velocity to the character controller's inputs which then allow the Ultimate Character Controller to take care of the animations.

---

<a id="page-behavior-designer-pro-referencing-scene-objects"></a>

# Referencing Scene Objects

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/referencing-scene-objects/)

## Understand why scene references disappear

As you are creating your tree it is common practice to reference objects within the scene from a Shared Variable or task. For example, use the **Can See Object** to determine if the Enemy GameObject can be seen:

![A Can See Object task references an Enemy GameObject from the current scene.](https://opsive.com/wp-content/uploads/2026/08/bdp-referencing-scene-objects-target.webp?v=6a2b3b4f9488)

As you are testing, you may make the agent a prefab so it can be reused. When that prefab is removed from the scene, its Enemy reference goes missing because project assets—including prefabs, subtrees, and project variables—cannot reference scene objects.

## Assign the reference at runtime

Populate the scene reference at runtime in one of these ways:

-   Add a task to your behavior tree which searches for the object. This can be done with something as basic as the `GameObject.Find` method or your own retrieval system.
-   Add the Behavior Tree component to your scene and use [Variable Overrides](https://opsive.com/support/documentation/behavior-designer-pro/subtrees/) to override the subtree variable value.
-   Assign the variable value through your own [initialization script](https://opsive.com/support/documentation/behavior-designer-pro/variables/accessing-variables/).

The Runtime Behavior and Subtrees sample scenes shows an example of using overrides. Each method has their own advantages and disadvantages so there's no one right way to assign the scene value.

---

<a id="page-behavior-designer-pro-save-load"></a>

# Save/Load

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/save-load/)

Behavior trees and their variables can be saved to a file allowing the the behavior tree to be restored at the same state later on. Individual behavior trees can be saved and loaded by calling `BehaviorTree.Save/Load`, or you can use the **Save Manager** if you want to save multiple behavior trees to the same file.

## Behavior Tree Save/Load

The script below demonstrates saving and loading a single behavior tree.

```csharp
using Opsive.BehaviorDesigner.Runtime;
using Opsive.BehaviorDesigner.Runtime.Utility;
using UnityEngine;

public class Saver : MonoBehaviour
{
    [Tooltip("The behavior tree that should be saved.")]
    public BehaviorTree m_BehaviorTree;
    [Tooltip("The location that the behavior tree should be saved.")]
    public string m_SaveLocation = "Assets/BehaviorTree.save";

    /// <summary>
    /// Saves the behavior tree.
    /// </summary>
    public void Save()
    {
        m_BehaviorTree.Save(m_SaveLocation, SaveManager.VariableSaveScope.GameObjectVariables | SaveManager.VariableSaveScope.SceneVariables); // Saves the behavior tree and the GameObject/scene variables.
    }

    /// <summary>
    /// Restores the behavior tree.
    /// </summary>
    public void Load()
    {
        m_BehaviorTree.Load(m_SaveLocation);
    }
}
```

The second parameter is a flag specifying what additional variables should be saved. The graph variable values will always be saved when the behavior tree is saved.

## Save Manager Save/Load

Multiple behavior trees can be saved to the same file using the Save Manager. The script below has the same functionality as Behavior Tree save script except it uses a behavior tree array.

```csharp
using Opsive.BehaviorDesigner.Runtime;
using Opsive.BehaviorDesigner.Runtime.Utility;
using UnityEngine;

public class Saver : MonoBehaviour
{
    [Tooltip("The behavior trees that should be saved.")]
    public BehaviorTree[] m_BehaviorTrees;
    [Tooltip("The location that the behavior trees should be saved.")]
    public string m_SaveLocation = "Assets/BehaviorTrees.save";

    /// <summary>
    /// Saves the behavior tree.
    /// </summary>
    public void Save()
    {
        SaveManager.Save(m_BehaviorTrees, m_SaveLocation, SaveManager.VariableSaveScope.GameObjectVariables | SaveManager.VariableSaveScope.SceneVariables); // Saves the behavior tree and the GameObject/scene variables.
    }

    /// <summary>
    /// Restores the behavior tree.
    /// </summary>
    public void Load()
    {
        SaveManager.Load(m_BehaviorTrees, m_SaveLocation);
    }
}
```

## Save Data

In the previous examples the behavior tree is saved and loaded from a file path. The raw save data can also be retrieved allowing you to use other methods in order to save the data. In the example below the behavior tree data is saved along with other agent data.

<div class="woocommerce-message docs-info">See the SaveLoad sample scene for a working example of the save load system.</div>

```csharp

    /// <summary>
    /// Stores all of the agent save data in one structure.
    /// </summary>
    private struct AgentSaveData
    {
        public SaveData BehaviorTreeSaveData; // The behavior tree save data.
        public Vector3 Position; // The Transform position.
        public Quaternion Rotation; // The Transform rotation.
    }

    /// <summary>
    /// Save the agent state.
    /// </summary>
    public void Save()
    {
        var saveData = m_BehaviorTree.Save();
        if (!saveData.HasValue) {
            return;
        }

        // Create the data structure which contains all of the values that should be saved.
        var agentSaveData = new AgentSaveData() { BehaviorTreeSaveData = saveData.Value, Position = m_Transform.position, Rotation = m_Transform.rotation };

        if (File.Exists(m_SaveLocation)) {
            File.Delete(m_SaveLocation);
        }
        try {
            if (!Directory.Exists(Path.GetDirectoryName(m_SaveLocation))) {
                Directory.CreateDirectory(Path.GetDirectoryName(m_SaveLocation));
            }
            var fileStream = File.Create(m_SaveLocation);
            using (var streamWriter = new StreamWriter(fileStream)) {
                streamWriter.Write(JsonUtility.ToJson(agentSaveData));
            }
            fileStream.Close();
        } catch (System.Exception e) {
            Debug.LogException(e);
            return;
        }
    }

    /// <summary>
    /// Load the agent state.
    /// </summary>
    public void Load()
    {
        if (!File.Exists(m_SaveLocation)) {
            return;
        }

        AgentSaveData agentSaveData;
        var fileStream = File.Open(m_SaveLocation, FileMode.Open);
        using (var streamReader = new StreamReader(fileStream)) {
            var fileData = streamReader.ReadToEnd();
            agentSaveData = JsonUtility.FromJson<AgentSaveData>(fileData);
        }
        fileStream.Close();

        // Restore the values.
        m_BehaviorTree.Load(agentSaveData.BehaviorTreeSaveData);

        m_Transform.SetPositionAndRotation(agentSaveData.Position, agentSaveData.Rotation);
    }
```

---

<a id="page-behavior-designer-pro-extending-the-editor"></a>

# Extending the Editor

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/)


Behavior Designer's editor can present custom task data and runtime state in a way that stays consistent with the built-in tasks.

## Add task controls

[Control Types](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/control-types/) explains how a field can use an appropriate editor control. Prefer a familiar control and a clear label so a tree author can configure the task without knowing how its editor code is implemented.

## Customize a node view

[Node Views](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/node-views/) covers visual information displayed directly on a task node. Use a custom view only when the value helps someone understand or debug the tree at a glance; keep detailed configuration in the Task Inspector.

---

<a id="page-behavior-designer-pro-extending-the-editor-control-types"></a>

# Control Types

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/control-types/)

**Control Types** are used to add the UIElement controls for various types and attributes. They are mainly used for the inspectors (such as the task or shared variable inspector) but can also be used to show content in other areas such as the within the node. As mentioned, there are two types of controls:

-   **Type Control**: Used to add controls for the C# types, from a basic int to more complex objects such as a Shared Variable.
-   **Attribute Control**: Used to add controls for C# attributes, such as the \[Header\] or \[Flags\] attribute.

**Control Types** are also used by the Ultimate Character Controller and the Ultimate Inventory System. If you've created a Control Type for one of those assets then it will also work with Behavior Designer.

## Type Control

The script below shows an example of creating a Control Type for the bool type.

```csharp
using Opsive.Shared.Editor.UIElements.Controls.Types;
using UnityEngine.UIElements;

[ControlType(typeof(bool))]
public class BoolControl : TypeControlBase
{
    /// <summary>
    /// Does the control use a label?
    /// </summary>
    public override bool UseLabel { get { return true; } }

    /// <summary>
    /// Returns the control that should be used for the specified ControlType.
    /// </summary>
    /// <param name="input">The input to the control.</param>
    /// <returns>The created control.</returns>
    protected override VisualElement GetControl(TypeControlInput input)
    {
        var toggle = new Toggle();
        toggle.value = (bool)input.Value;
        // Ensure the control is kept up to date as the value changes.
        if (input.Field != null) {
            System.Action<object> onBindingUpdateEvent = (object newValue) => toggle.SetValueWithoutNotify((bool)newValue);
            toggle.RegisterCallback<AttachToPanelEvent>(c =>
            {
                BindingUpdater.AddBinding(input.Field, input.ArrayIndex, input.Target, onBindingUpdateEvent);
            });
            toggle.RegisterCallback<DetachFromPanelEvent>(c =>
            {
                BindingUpdater.RemoveBinding(onBindingUpdateEvent);
            });
        }
        toggle.RegisterValueChangedCallback(c =>
        {
            if (!input.OnChangeEvent(c.newValue)) {
                toggle.SetValueWithoutNotify(c.previousValue);
            }
            c.StopPropagation();
        });
        return toggle;
    }
}
```

Some things to pay attention to:

-   The **\[ControlType\]** attribute specifies the object type that the control represents.
-   The class implements `TypeControlBase`. This base type is used for controls that display object types.
-   `UseLabel` is set to true. If this was set to false then no field label would be added to the UI.
-   The `BindingUpdater` is used to ensure the the UIElement is updated when the field value changes outside of the UI. Remember UIElements is a persistent UI solution so if the `BindingUpdater` didn't exist then the UI display would never change as the field value changes.

## Attribute Control

Attribute Controls are similar to Type Controls. The script below is an implementing of the Attribute Control for the \[Space\] Attribute.

```csharp
using Opsive.Shared.Editor.UIElements.Controls.Attributes;
using System.Reflection;
using UnityEngine.UIElements;

[ControlType(typeof(UnityEngine.SpaceAttribute))]
public class SpaceAttributeControl : AttributeControlBase
{
    /// <summary>
    /// Does the attribute override the type control?
    /// </summary>
    public override bool OverrideTypeControl { get { return false; } }

    /// <summary>
    /// Does the control use a label?
    /// </summary>
    public override bool UseLabel { get { return false; } }

    /// <summary>
    /// Returns the attribute control that should be used for the specified AttributeControlType.
    /// </summary>
    /// <param name="input">The input to the control.</param>
    /// <returns>The created control.</returns>
    protected override VisualElement GetControl(AttributeControlInput input)
    {
        var spaceAttribute = input.Field.GetCustomAttribute<UnityEngine.SpaceAttribute>();
        if (spaceAttribute == null) {
            return null;
        }

        var visualElement = new VisualElement();
        visualElement.style.height = spaceAttribute.height;
        return visualElement;
    }
}
```

Most of the concepts are the same as the Type Control. The only difference is that the `AttributeControlBase` has an `OverrideTypeControl` which allows the Attribute Control to replace the Type Control. If this property returns true then the Type Control will not be used for the object type that the attribute has been added to.

---

<a id="page-behavior-designer-pro-extending-the-editor-node-views"></a>

# Node Views

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/node-views/)

## Add runtime information to a node

Custom content can be added to an individual node view in the Behavior Designer editor through `TaskNodeViewControl`. The **Wait** Task uses this to display a progress bar showing how much of its duration has elapsed:

![A custom Wait node view displays its elapsed-time progress bar.](https://opsive.com/wp-content/uploads/2026/08/bdp-node-views-wait-progress.webp?v=ee197d5a8c9f)

This control is drawn with the script below:

```csharp
using Opsive.BehaviorDesigner.Editor.Controls.NodeViews;
using Opsive.BehaviorDesigner.Runtime;
using Opsive.BehaviorDesigner.Runtime.Components;
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
using Opsive.GraphDesigner.Editor;
using Opsive.GraphDesigner.Editor.Events;
using Opsive.GraphDesigner.Runtime;
using Opsive.Shared.Editor.UIElements.Controls;
using Unity.Entities;
using UnityEngine;
using UnityEngine.UIElements;

[ControlType(typeof(Wait))]
public class WaitNodeViewControl : TaskNodeViewControl
{
    private BehaviorTree m_BehaviorTree;
    private ILogicNode m_Node;
    private ushort m_WaitComponentIndex = ushort.MaxValue;
    private ProgressBar m_ProgressBar;

    /// <summary>
    /// Addes the UIElements for the specified runtime node to the editor Node within the graph.
    /// </summary>
    /// <param name="graphWindow">A reference to the GraphWindow.</param>
    /// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
    /// <param name="node">The node that the control represents.</param>
    public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
    {
        base.AddNodeView(graphWindow, parent, node);

        if (!Application.isPlaying) {
            return;
        }

        m_BehaviorTree = graphWindow.Graph as BehaviorTree;
        m_Node = node as ILogicNode;

        parent.RegisterCallback<AttachToPanelEvent>(c =>
        {
            GraphEventHandler.RegisterEvent(GraphEventType.WindowUpdate, UpdateWaitProgress);
        });
        parent.RegisterCallback<DetachFromPanelEvent>(c =>
        {
            GraphEventHandler.UnregisterEvent(GraphEventType.WindowUpdate, UpdateWaitProgress);
        });

        m_ProgressBar = new ProgressBar();
        parent.Add(m_ProgressBar);
    }

    /// <summary>
    /// Updates the wait progress bar.
    /// </summary>
    private void UpdateWaitProgress()
    {
        if (m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || m_Node.RuntimeIndex == ushort.MaxValue) {
            return;
        }

        var waitComponents = m_BehaviorTree.World.EntityManager.GetBuffer<WaitComponent>(m_BehaviorTree.Entity);
        if (m_WaitComponentIndex == ushort.MaxValue) {
            // Find the corresponding index of the WaitComponent.
            for (int i = 0; i < waitComponents.Length; ++i) {
                if (waitComponents[i].Index == m_Node.RuntimeIndex) {
                    m_WaitComponentIndex = (ushort)i;
                    break;
                }
            }

            if (m_WaitComponentIndex == ushort.MaxValue) {
                return;
            }
        }

        var waitComponent = waitComponents[m_WaitComponentIndex];
        m_ProgressBar.highValue = waitComponent.Duration;

        var taskComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskComponent>(m_BehaviorTree.Entity);
        var elapsed = -1f;
        if (taskComponents[m_Node.RuntimeIndex].Status == Runtime.Tasks.TaskStatus.Running) {
            elapsed = Mathf.Clamp(Time.time - (float)waitComponent.StartTime, 0, waitComponent.Duration);
            m_ProgressBar.value = elapsed;
        } else if (taskComponents[m_Node.RuntimeIndex].Status == Runtime.Tasks.TaskStatus.Success) {
            elapsed = waitComponent.Duration;
            m_ProgressBar.value = elapsed;
        } else if (taskComponents[m_Node.RuntimeIndex].Status == Runtime.Tasks.TaskStatus.Inactive) {
            m_ProgressBar.value = 0;
        }

        m_ProgressBar.title = (elapsed >= 0 ? System.Math.Round(elapsed, 2).ToString() + "/" : string.Empty) + waitComponent.Duration.ToString() + "s";
    }
}
```

## Keep the view updated

Node Views use the same Control Type system that adds the [type and attribute controls](https://opsive.com/support/documentation/behavior-designer-pro/extending-the-editor/control-types/). There are some things to pay attention to within this control:

-   When the view is attached to the panel it registers for the `GraphEventType.WindowUpdate` event. UIElements are persisted, so registering for the window update event keeps the progress bar current as the time changes.
-   Within `UpdateWaitProgress` the **m\_WaitComponentIndex** is retrieved. The **Wait** task is an [Entity task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/entity-task/) so the progress amount will be stored in an Entity component.
-   The `RuntimeIndex` is used instead of the regular **Index** of the node. This is done because the `RuntimeIndex` may be different depending on the behavior tree branch structure.

## Reference a GameObject task

If you are adding a Node View to a GameObject task, you can reference that task directly. `AddNodeView` would look something like:

```csharp
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
{
    base.AddNodeView(graphWindow, parent, node);

    var canSeeObjectTask = node as CanSeeObject;
```

With this setup you have a reference to the CanSeeObject task directly and do not need to search based on the `RuntimeIndex`.

---

<a id="page-behavior-designer-pro-api"></a>

# API

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/api/)

The Behavior Tree component is the main interface between Behavior Designer and the behavior tree data. It is also responsible for baking if the component is placed within an Entity subscene. The Behavior Tree component has the following API:

```csharp
/// <summary>
/// Starts the behavior tree.
/// </summary>
/// <returns>True if the behavior tree was started.</returns>
bool StartBehavior()

 /// <summary>
/// Stars the branch with the specified event task type.
/// </summary>
/// <param name="eventTaskType">The branch that should be started.</param>
/// <returns>True if the branch was started.</returns>
bool StartBranch(Type eventTaskType)

 /// <summary>
/// Starts the branch with the specified event task.
/// </summary>
/// <param name="eventTask">The branch that should be started.</param>
/// <returns>True if the branch was started.</returns>
bool StartBranch(IEventNode eventTask)

 /// <summary>
/// Returns the task at the specified index.
/// </summary>
/// <param name="index">The index of the task.</param>
/// <returns>The task at the specified index.</returns>
ILogicNode GetTask(int index)

 /// <summary>
/// Finds the task with the specified type.
/// </summary>
/// <returns>The first task found with the specified type (can be null).</returns>
T FindTask<T>() where T : Task

/// <summary>
/// Finds the tasks with the specified type. This method does not have any allocations.
/// </summary>
/// <param name="foundTasks">A pre-initialized array that will contain the found tasks.</param>
/// <returns>The number of tasks found with the specified type.</returns>
int FindTasks<T>(T[] foundTasks) where T : Task

 /// <summary>
/// Finds the tasks with the specified type.
/// </summary>
/// <returns>An array containing the found tasks.</returns>
T[] FindTasks<T>() where T : Task
 /// <summary>
/// Ticks the behavior tree. The UpdateMode must be set to Manual.
/// </summary>
void Tick()

 /// <summary>
/// Reevaluates the SubtreeReferences by calling the EvaluateSubtrees method.
/// </summary>
void ReevaluateSubtreeReferences()

 /// <summary>
/// Stops or pauses the behavior tree.
/// </summary>
/// <param name="pause">Should the behavior tree be paused?</param>
/// <returns>True if the behavior tree was stopped or paused.</returns>
bool StopBehavior(bool pause = false)

 /// <summary>
/// Restarts the behavior tree.
/// </summary>
/// <returns>True if the behavior tree was restarted.</returns>
bool RestartBehavior()

 /// <summary>
/// Returns the SharedVariable with the specified name and scope.
/// </summary>
/// <param name="name">The name of the SharedVariable that should be retrieved.</param>
/// <param name="scope">The scope of the SharedVariable that should be retrieved.</param>
/// <returns>The SharedVariable with the specified name (can be null).</returns>
SharedVariable GetVariable(string name, SharedVariable.SharingScope scope)

 /// <summary>
/// Saves the behavior tree at the specified file path.
/// </summary>
/// <param name="filePath">The file path to save the behavior tree at. The file will be replaced if it already exists.</param>
/// <param name="variableSaveScope">Specifies which variables should be saved. Graph variables will automatically be saved.</param>
/// <returns>True if the behavior tree was successfully saved.</returns>
bool Save(string filePath, SaveManager.VariableSaveScope variableSaveScope)

 /// <summary>
/// Loads the behavior tree from the specified file path.
/// </summary>
/// <param name="filePath">The file path to load the behavior tree at.</param>
/// <returns>True if the behavior tree was successfully loaded.</returns>
bool Load(string filePath)
```

If your behavior tree is set to a **Manual Update Mode** then you will need to tick the tree by calling `BehaviorTree.Tick`. This is useful for turn-based games.

<div class="woocommerce-message docs-info">See the TurnBased sample scene for an example of manually ticking the behavior tree.</div>

## Events

The following events are exposed:

```csharp
OnBehaviorTreeStarted
OnBehaviorTreeStopped
OnBehaviorTreeDestroyed

OnWillSave
OnDidSave
OnWillLoad
OnDidLoad
```

The execution status of the tree is available from the `BehaviorTree.Status` property.

---

<a id="page-behavior-designer-pro-networking"></a>

# Networking

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/networking/)

## Run decisions on the authority

The recommended approach for Behavior Designer and networking is to have Behavior Designer run on the server. This will ensure the server makes all of the decisions and then sends the clients the results. For example, if the **Seek** task is running the client should only receive the current position of the agent. With this setup the behavior tree isn't even aware of the network. This is also true for a client authoritative solution. Only the resulting transform/animation properties should be synced to all other clients. The actual behavior tree does not need to be synchronized across the network. For a practical example your script would look something like this:

```csharp
public class BehaviorTreeEnabler : MonoBehaviour
{
    [Tooltip("A reference to the behavior tree.")]
    public BehaviorTree m_BehaviorTree;

    private void Awake()
    {
        m_BehaviorTree.enabled = IsServer();
    }
}
```

## Start deferred Entity trees on the server

The `IsServer` method depends on your networking implementation, but it ensures the behavior tree is enabled only on the server or authoritative client in a peer-to-peer setup. With this approach, Behavior Designer can work with any networking implementation.

For Entity clients, leave **Start When Enabled** off and call `StartBakedBehaviorTree` only on the server. This prevents the client from starting its own decision-making tree. Based on the [Entity Baking](https://opsive.com/support/documentation/behavior-designer-pro/entity-baking/) example, the spawner system can use an authority check before starting each deferred tree:

```csharp
public partial struct EntitySpawnerSystem : ISystem
{
    /// <summary>
    /// Sets the system requirements.
    /// </summary>
    /// <param name="state">The current SystemState.</param>
    private void OnCreate(ref SystemState state)
    {
        state.RequireForUpdate<SpawnData>();
    }

    /// <summary>
    /// Spawns the entities.
    /// </summary>
    /// <param name="state">The current SystemState.</param>
    private void OnUpdate(ref SystemState state)
    {
        state.Enabled = false;

        var spawner = SystemAPI.ManagedAPI.GetSingleton<SpawnData>();
        var entities = state.EntityManager.Instantiate(spawner.Prefab, 100, Allocator.Temp);

        // Any custom setup for each entity. This can include adding new components, enabling components, setting entity data, etc.

        // The behavior trees have been baked.
        if (spawner.IsServer) { // Your networking implementation for determining if the agent is on the server.
            BehaviorTree.StartBakedBehaviorTree(world, entity);
        }
    }
}
```

---

<a id="page-behavior-designer-pro-repository"></a>

# Repository

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/repository/)

## Access the source repository

The separate Behavior Designer Pro repository license provides the full source code and regular commits between official releases. It is an annual, per-seat license. If you choose not to renew, you retain access to the compiled Behavior Designer package but no longer receive the latest repository source. Contact Opsive support for current repository licensing details.

---

<a id="page-behavior-designer-pro-resources"></a>

# Resources

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/resources/)

The following resources provide walkthroughs, examples, and broader introductions to behavior-tree design.

## Official Opsive resources

-   [Behavior Designer Pro videos](https://opsive.com/videos/?pid=28276)
-   [Behavior Tree Basics video series](https://www.youtube.com/watch?v=PuLuwzgYB4g&index=1&list=PLCPL5IYZm1NLVVxJx3-CFTLuHvLbCgmzk)
-   [Opsive Character Controller Integration Explanation](https://opsive.com/support/documentation/behavior-designer/integrations/opsive-character-controllers/)
-   [Deathmatch AI Kit Implementation Explanation](https://opsive.com/support/documentation/deathmatch-ai-kit/behavior-tree-overview/)

## Courses and project examples

-   [Awesome AI made Easy with Behavior Designer](https://thestrangeschool.vhx.tv/checkout/easy-awesome-ai-with-behavior-designer/purchase)
-   [Unity AI Guide: Create a Autonomous Game with Adaptive NPCs](https://www.udemy.com/course/unity-ai-guide-create-a-autonomous-game-with-adaptive-npcs/?referralCode=895A0356AC20743582B5)
-   [Recreating the FALSE KNIGHT Boss Fight](https://www.youtube.com/watch?v=X7VwAGvAOIw)
-   [Practical Guide to AI in Unity](https://www.udemy.com/course/ai-in-unity/)

---

<a id="page-behavior-designer-pro-integrations"></a>

# Integrations

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)

Integrations add Tasks that command or inspect another gameplay system while Behavior Designer Pro owns the decision flow.

## Install an integration

Download the matching bridge from [Opsive Downloads](https://opsive.com/downloads/), then import it after the third-party asset. Bridges are separate downloads and appear in the project only after import. Provider-maintained exceptions are identified on their integration pages.

Open **Tools > Opsive > Behavior Designer > Integrations** to review the installed entry, then search the Task List for a Task named on its page below.

## Available integrations

| Integration | What it adds |
| --- | --- |
| [A* Pathfinding Project](https://opsive.com/support/documentation/behavior-designer-pro/integrations/astar-pathfinding-project/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/behavior-ai/a-pathfinding-project-pro-87744?aid=1100lGdc) | An A* pathfinder adapter and examples for the Movement, Formations, and Tactical add-ons. |
| [Animal Controller](https://opsive.com/support/documentation/behavior-designer-pro/integrations/animal-controller/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/animation/animal-controller-malbers-character-controller-148877?aid=1100lGdc) | Malbers animal movement, targeting, stance, Mode, reaction, weapon, aim, and controller Conditions. |
| [Atlas](https://opsive.com/support/documentation/behavior-designer-pro/integrations/atlas/)<br>[Atlas page](https://opsive.com/atlas/) | Ask, plan, generate, modify, correct, review, and apply validated GameObject or ECS tasks in Unity. |
| [Curvy Splines](https://opsive.com/support/documentation/behavior-designer-pro/integrations/curvy-splines/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/utilities/curvy-splines-8-212532?aid=1100lGdc) | Create and query splines, control points, nearest positions, segment values, and spline alignment. |
| [Dialogue System](https://opsive.com/support/documentation/behavior-designer-pro/integrations/dialogue-system/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/behavior-ai/dialogue-system-for-unity-11672?aid=1100lGdc) | Conversations, barks, sequences, Lua, dialogue variables, and quest state tasks. |
| [DOTS Survivors](https://opsive.com/support/documentation/behavior-designer-pro/integrations/dots-survivors/)<br>[Provider documentation](https://survivors.tmg.dev/integrations/BehaviorDesignerPro.html) | A provider-maintained ECS-agent bridge whose package and support boundary live with DOTS Survivors. |
| [Easy Build System](https://opsive.com/support/documentation/behavior-designer-pro/integrations/easy-build-system/)<br>[Asset Store](https://assetstore.unity.com/packages/slug/45394?aid=1100lGdc) | Control building modes, previews, placement, adjustment, destruction, upgrades, and saves. |
| [Feel](https://opsive.com/support/documentation/behavior-designer-pro/integrations/feel/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/particles-effects/feel-183370?aid=1100lGdc) | Play a single feedback or an MMF Player feedback sequence. |
| [Juicy Actions](https://opsive.com/support/documentation/behavior-designer-pro/integrations/juicy-actions/)<br>[Asset Store](https://assetstore.unity.com/packages/slug/269711?aid=1100lGdc) | Coordinate Action Executors and behavior trees in either direction, including status and variable transfer. |
| [Love/Hate](https://opsive.com/support/documentation/behavior-designer-pro/integrations/love-hate/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/ai/love-hate-33063?aid=1100lGdc) | Faction, affinity, deed, rumor, emotion, personality, and relationship tasks. |
| [PlayMaker](https://opsive.com/support/documentation/behavior-designer-pro/integrations/playmaker/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/playmaker-368?aid=1100lGdc) | Start, stop, resume, signal, and synchronize PlayMaker 1 finite state machines and behavior trees. |
| [Quest Machine](https://opsive.com/support/documentation/behavior-designer-pro/integrations/quest-machine/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/quest-machine-39834?aid=1100lGdc) | Quest generation, state, counters, messages, spawners, dialogue, alerts, heads-up display, and Journal interface tasks. |
| [Sensor Toolkit 2](https://opsive.com/support/documentation/behavior-designer-pro/integrations/sensor-toolkit-2/)<br>[Asset Store](https://assetstore.unity.com/packages/slug/317234?aid=1100lGdc) | Pulse sensors, inspect detections and signals, test obstruction, and steer seek or strafe targets. |
| [Simple Waypoint System](https://opsive.com/support/documentation/behavior-designer-pro/integrations/simple-waypoint-system/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/animation/simple-waypoint-system-2506?aid=1100lGdc) | Select paths and waypoints and start, pause, resume, stop, or retime their movement. |
| [State Designer](https://opsive.com/support/documentation/behavior-designer-pro/integrations/state-designer/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/visual-scripting/state-designer-dots-powered-finite-state-machines-369152?aid=1100lGdc) | Start, stop, inspect, and synchronize a State Machine from a behavior tree, with reciprocal State Designer nodes. |
| [Ultimate Character Controller](https://opsive.com/support/documentation/behavior-designer-pro/integrations/ultimate-character-controller/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/ultimate-character-controller-233710?aid=1100lGdc) | Control abilities, effects, items, health, attributes, State System state, aim, and character events. |
| [Ultimate Inventory System](https://opsive.com/support/documentation/behavior-designer-pro/integrations/ultimate-inventory-system/)<br>[Asset Store](https://assetstore.unity.com/packages/tools/game-toolkits/ultimate-inventory-system-166053?aid=1100lGdc) | Inspect or change Items, Currency, Item Actions, interface panels, interactions, and Version 1 saves. |

## Runtime ownership

The behavior tree owns the decision and branch lifetime; the third-party system owns the operation requested or queried by the integration Task. Inspect both when their states disagree.

## Related pages

- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Events](https://opsive.com/support/documentation/behavior-designer-pro/events/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)
- [GameObject or Entity tasks](https://opsive.com/support/documentation/behavior-designer-pro/getting-started/gameobject-or-entity-tasks/)

---

<a id="page-behavior-designer-pro-integrations-astar-pathfinding-project"></a>

# A* Pathfinding Project

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/astar-pathfinding-project/)


Use the [A* Pathfinding Project](https://assetstore.unity.com/packages/tools/behavior-ai/a-pathfinding-project-pro-87744?aid=1100lGdc) integration when Behavior Designer movement, formations, or tactical add-ons should obtain paths from Aron Granberg's A* agents instead of Unity NavMesh.

## Install the integration

1. Download the current **A* Pathfinding Project** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerAstarPathfindingProject.unitypackage`.
3. Confirm **Astar AI Pathfinder** appears in the Task List.

## What the integration adds

- **Pathfinding adapter:** **Astar AIPathfinder**.
- **Included examples:** **Movement Pack Demo**, **Formations Pack Demo**, **Tactical Pack Demo**.

This package is an adapter for the Behavior Designer movement-family add-ons. It is not a replacement for those task packs and does not add a complete base-product movement catalog by itself.

## Build a first workflow

1. Build and scan an A* graph, then verify an AIPath-compatible agent can reach one destination.
2. Import the integration after A* Pathfinding Project and the relevant Behavior Designer add-on.
3. Select the A* pathfinder implementation expected by that add-on.
4. Run one Seek or formation example before adapting the production tree.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-animal-controller"></a>

# Animal Controller

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/animal-controller/)


Use the [Animal Controller](https://assetstore.unity.com/packages/tools/animation/animal-controller-malbers-character-controller-148877?aid=1100lGdc) integration when a behavior tree should drive a Malbers Animations animal, stance, mode, weapon, aim, target, or destination through the controller APIs.

## Install the integration

1. Download the current **Animal Controller** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerAnimalController.unitypackage`.
3. Confirm **Set Destination** appears in the Task List.

## What the integration adds

- **Movement and targeting:** **Set Destination**, **Set Speed**, **Set Strafe**, **Set Target**, **Stop Movement**.
- **Animation and reaction:** **Play Mode**, **Play Stance**, **Play State**, **React**, **Activate Zone**.
- **Weapons:** **Attack Weapon**, **Equip Weapon**, **Unequip Weapon**, **Reload Weapon**, **Set Aim**.
- **Conditions:** **Is Aiming**, **Is Attacking**, **Is Reloading**.

## Build a first workflow

1. Verify the Animal Controller can move and play one Mode without Behavior Designer.
2. Use **Set Target** and **Set Destination** in a Sequence.
3. Wait until the target is in range, then use **Set Aim** and **Attack Weapon**.
4. Use the matching Conditions to keep attack and reload branches observable.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-atlas"></a>

# Atlas

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/atlas/)

Atlas is the Opsive assistant for asking Behavior Designer Pro questions, planning a task, and generating validated GameObject or ECS task source inside Unity. Generated files remain previews until you explicitly apply them.

## Install and connect Atlas

Atlas requires **Behavior Designer Pro 3.3.0 or newer**.

1. Confirm the installed Behavior Designer Pro version is 3.3.0 or newer.
2. Download Atlas from the [Atlas page](https://opsive.com/atlas/) and import it into the Behavior Designer Pro project. Atlas is not available from the Opsive Downloads page.
3. Install the Codex desktop app or standalone Codex CLI on Windows or macOS and sign in with the subscription you want Atlas to use.
4. In Unity, open **Tools > Opsive > Behavior Designer > Atlas**. The Behavior Designer window can also open its docked Atlas panel.
5. Select **Sign in**. Atlas opens a one-time browser page and checks the signed-in Opsive account for the selected product. If no matching direct order or linked Unity invoice is found, enter the invoice number on that page.
6. Return to Unity. Confirm that **Behavior Designer** is selected as the active Opsive asset before asking product-specific questions.

No Atlas token or Codex credential is copied into the Unity Inspector. Codex authentication remains on the local machine.

![Atlas generating a Behavior Designer Pro task and presenting the validated source before it is applied.](https://opsive.com/wp-content/uploads/2026/08/bdp-atlas-task-generation-editor.webp?v=eb0985134a55)

## Choose how Atlas should help

- **Ask** explains a Behavior Designer concept or suggests an existing built-in task without creating a file.
- **Plan** produces an implementation plan that can be reviewed and saved before code generation.
- **Generate** creates one or more task files. Atlas can generate Action, Conditional, Decorator, and Composite tasks for GameObjects or Entities.
- **Modify** changes a user-authored task that you explicitly select while preserving unrelated code.
- **Correct** sends real compiler diagnostics from an earlier result back through validation.
- A request to build the saved plan can produce a dependency-ordered multi-file package. Atlas keeps incomplete batches staged and exposes **Apply all** only after the manifest is complete.

Atlas first checks whether a built-in task already performs the requested behavior. When it does, the useful result is guidance to use that task rather than a redundant subclass.

## Generate a first task

1. Create a source-control checkpoint and open a small test tree.
2. Ask a narrow request with a visible result, such as: `Generate a GameObject Action that rotates its target toward a Shared Transform and succeeds within two degrees.`
3. Review the response summary, generated filename, base class, fields, lifecycle methods, and success/failure behavior.
4. Expand **Show work** only when you need the progress detail. Expand the code card to inspect the complete source.
5. Select **Apply `FileName`.cs** to use the suggested path, **Save as...** to choose another project path, **Copy** to keep the source outside Atlas, or **Discard** to reject it.
6. Let Unity compile. If it reports an error, send the exact diagnostic back through the correction action instead of manually guessing at framework boilerplate.
7. Add the new task to the test tree and verify its Success, Failure, Running, interruption, and reset paths.

For a multi-file result, inspect every file before selecting **Apply all**. Atlas preserves planned subfolders beneath the destination you choose and rolls back the batch if a file write fails.

## Understand the visible controls

- **Active Opsive asset** changes the product context when more than one supported Opsive product is installed.
- **Model** and **Effort** select from the choices currently returned for the connected provider. An unavailable combination is not forced by the Unity client.
- **New chat**, chat tabs, and **All chats** separate unrelated requests. Keep one implementation in one chat so corrections retain the right context.
- The **settings** menu contains connection and provider controls. The **Atlas** menu under **Tools > Opsive > Behavior Designer** contains **Verbose Diagnostics**, which is intended for support investigation rather than normal authoring.
- **Helpful** and **Not helpful** report the result quality without applying a file.
- **Retry request** repeats a failed request; **Resume package build** continues a recoverable multi-file build.

Atlas collects a bounded relevant API summary and explicitly included project files. It does not send the entire Unity project. Review the current privacy and provider explanation on the [Atlas page](https://opsive.com/atlas/) before using it with sensitive project code.

## Verify the generated task

1. Confirm the generated class derives from the intended Behavior Designer Pro GameObject or ECS base.
2. Inspect the task in the normal Task Inspector. Its Shared Variables and attributes should render without a custom repair.
3. Run the tree and verify the node's visible status and player-facing result.
4. Abort or disable the branch while the task is Running and confirm its cleanup occurs.
5. Re-enter the tree and confirm fields and runtime state reset correctly.
6. Commit the reviewed source as normal project code. Atlas output is not a substitute for source control or a gameplay test.

## Troubleshooting

| Symptom | Check | Fix |
| --- | --- | --- |
| Behavior Designer is unavailable in the asset selector. | Confirm the Behavior Designer Pro package compiled and its task base types are loaded. | Resolve the first Console error, then reopen Atlas. |
| The browser says the product is not entitled. | Confirm the browser uses the Opsive account that owns the order or linked Unity invoice. | Sign in to the correct account or enter the matching invoice on the one-time connection page. |
| Atlas cannot find Codex. | Confirm the Codex app or CLI is installed and signed in on this machine. | Start Codex once, complete its sign-in, then retry the Atlas request. |
| A generated task duplicates a built-in task. | Check the guidance and the Task List before applying. | Prefer the built-in task unless the request genuinely requires different behavior. |
| Unity reports a compile error after Apply. | Preserve the exact compiler diagnostic and the generated file. | Use the Atlas correction action so the result is validated again, or discard/revert the file. |
| The task compiles but behaves incorrectly. | Check target ownership, lifecycle cleanup, Shared Variable assignments, and expected task status. | Reduce the request to one observable responsibility and test each status path before expanding it. |

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Creating a GameObject task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/gameobject-task/)
- [Creating an Entity task](https://opsive.com/support/documentation/behavior-designer-pro/new-tasks/entity-task/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-curvy-splines"></a>

# Curvy Splines

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/curvy-splines/)


Use the [Curvy Splines](https://assetstore.unity.com/packages/tools/utilities/curvy-splines-8-212532?aid=1100lGdc) integration when a behavior tree needs to create, query, align with, or update a Curvy spline and its control points.

## Install the integration

1. Download the current **Curvy Splines** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerCurvy.unitypackage`.
3. Confirm **Get Nearest Point** appears in the Task List.

## What the integration adds

- **Spline tasks:** **Create Spline**, **Set Control Points**, **Get Control Points**, **Delete Control Points**, **Get Nearest Point**, **Get Segment Value**, **Get Value**, **Align To Spline**, **Is Initialized**.

## Build a first workflow

1. Create and initialize a Curvy spline in a small scene.
2. Use **Is Initialized** before any query task.
3. Use **Get Nearest Point** to store the nearest spline position for the agent.
4. Use **Align To Spline** or a project movement task to produce the visible motion.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-dialogue-system"></a>

# Dialogue System

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/dialogue-system/)


Use the Pixel Crushers [Dialogue System](https://assetstore.unity.com/packages/tools/behavior-ai/dialogue-system-for-unity-11672?aid=1100lGdc) integration when a behavior tree should start or stop conversations and sequences, bark, run Lua, or read and write dialogue and quest values.

## Install the integration

1. Download the current **Dialogue System** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerDialogueSystem.unitypackage`.
3. Confirm **Start Conversation** appears in the Task List.

## What the integration adds

- **Conversation:** **Start Conversation**, **Stop Conversation**, **Is Conversation Active**, **Bark**, **Start Sequence**, **Stop Sequence**.
- **Lua and variables:** **Run Lua**, **Is Lua True**, **Get Dialogue Bool Variable**, **Set Dialogue Bool Variable**, **Get Dialogue Float Variable**, **Set Dialogue Float Variable**, **Get Dialogue Int Variable**, **Set Dialogue Int Variable**, **Get Dialogue String Variable**, **Set Dialogue String Variable**.
- **Quests:** **Get Quest State**, **Set Quest State**, **Get Quest Entry State**, **Set Quest Entry State**.

## Build a first workflow

1. Verify the Dialogue Manager can start one conversation without the tree.
2. Add **Start Conversation** with the actor, conversant, and conversation title expected by that scene.
3. Wait with **Is Conversation Active** or a callback-driven branch when gameplay should pause.
4. Read the resulting quest or dialogue variable before choosing the next behavior.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-dots-survivors"></a>

# DOTS Survivors

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/dots-survivors/)


Use the DOTS Survivors integration when that framework should run Behavior Designer Pro decisions for its ECS agents through the provider-maintained bridge.

## Install the integration

1. Open **Tools > Opsive > Behavior Designer > Integrations**, select **DOTS Survivors**, and follow its provider-owned documentation route. Opsive does not distribute this bridge.
2. Confirm that the provider's expected Tasks appear and its sample opens.

## What the integration adds

The provider supplies the tasks used to hand work between the two products. Inspect the installed selector and provider sample for the exact version-specific list.

## Build a first workflow

1. Install DOTS Survivors and open its verified standalone sample.
2. Follow the [provider guide](https://survivors.tmg.dev/integrations/BehaviorDesignerPro.html) from the Integrations window.
3. Add the provider integration to a copy of that sample before modifying a production agent.
4. Verify one agent changes behavior and its entity data remains valid after the transition.

## Package and support boundary

Because the provider controls this bridge, the package version, supported platforms, and exact node names can change independently of Behavior Designer Pro. Record the tested combination in the project before upgrading.

- The current catalog uses the provider's Behavior Designer Pro guide as the authority. Do not substitute an undocumented Opsive package.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-easy-build-system"></a>

# Easy Build System

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/easy-build-system/)


Use the [Easy Build System](https://assetstore.unity.com/packages/slug/45394?aid=1100lGdc) integration when a behavior tree should control build modes, preview rotation, placement, adjustment, destruction, upgrades, or building save data.

## Install the integration

1. Download the current **Easy Build System** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerEasyBuildSystem.unitypackage`.
3. Confirm **Place Building Part** appears in the Task List.

## What the integration adds

- **Controller:** **Set Building Mode**, **Is Placement Mode**, **Is Destruction Mode**, **Is Adjustment Mode**, **Rotate Preview**, **Validate Action**, **Cancel Action**.
- **Building manager:** **Place Building Part**, **Adjust Building Part**, **Destroy Building Part**, **Destroy Building Part By Unique Id**, **Destroy All Placed Parts**, **Select Building Part**, **Select Building Part By Index**, **Get Selected Part**, **Get Part By Prefab Id**, **Get Part By Unique Id**, **Get Part Count**, **Upgrade Building Part**.
- **Persistence:** **Save Buildings**, **Load Buildings**, **Delete Save**, **Has Save Data**.

The downloaded integration contains this complete task set even when an online catalog revision does not list it.

## Build a first workflow

1. Verify the Easy Build System controller can preview and place one part.
2. Use **Set Building Mode** and **Select Building Part**.
3. Run **Place Building Part** only after the placement condition is valid.
4. Read **Get Part Count** and test save/load before extending the production tree.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-feel"></a>

# Feel

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/feel/)


Use the [Feel](https://assetstore.unity.com/packages/tools/particles-effects/feel-183370?aid=1100lGdc) integration when a behavior-tree Action should play one MMFeedback or an MMF Player feedback sequence.

## Install the integration

1. Download the current **Feel** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerFeel.unitypackage`.
3. Confirm **Play Feedbacks** appears in the Task List.

## What the integration adds

- **Feedback tasks:** **Play Feedback**, **Play Feedbacks**.

## Build a first workflow

1. Create and test one Feel feedback or MMF Player directly.
2. Add **Play Feedback** for a single feedback or **Play Feedbacks** for the player sequence.
3. Assign the exact feedback owner and choose whether the graph waits for completion when that option is available.
4. Run the branch twice to confirm replay and reset behavior are intentional.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-juicy-actions"></a>

# Juicy Actions

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/juicy-actions/)


Use the [Juicy Actions](https://assetstore.unity.com/packages/slug/269711?aid=1100lGdc) integration when a behavior tree should run, stop, restart, or inspect an Action Executor, or when a Juicy Action asset should control a behavior tree.

## Install the integration

1. Download the current **Juicy Actions** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerJuicyActions.unitypackage`.
3. Confirm **Execute Action Executor** appears in the Task List.

## What the integration adds

- **Tree to action:** **Execute Action Executor**, **Wait For Action Executor**, **Stop Action Executor**, **Restart Action Executor**, **Compare Action Executor Status**, **Compare Action Runner Status**, **Is Action Executor Completed**.
- **Clock:** **Clock Get Time**, **Clock Get Time Scale**, **Clock Pause**, **Clock Resume**, **Clock Set Time Scale**, **Clock Wait**.
- **Action assets to tree:** **Start Behavior Tree Action**, **Start Behavior Tree Branch Action**, **Stop Behavior Tree Action**, **Pause Behavior Tree Action**, **Resume Behavior Tree Action**, **Restart Behavior Tree Action**, **Get Behavior Tree Status Action**, **Get Behavior Tree Variable Action**, **Set Behavior Tree Variable Action**, **Copy Behavior Tree Variables To Blackboard Action**, **Copy Blackboard To Behavior Tree Variables Action**.

The downloaded integration contains this complete task set even when an online catalog revision does not list it.

## Build a first workflow

1. Create an Action Executor and verify its Action list runs directly.
2. Use **Execute Action Executor** in the behavior tree.
3. Follow it with **Wait For Action Executor** when the branch must remain active until completion.
4. Use one variable-copy Action only when both systems need the same value.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-love-hate"></a>

# Love/Hate

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/love-hate/)


Use the Pixel Crushers [Love/Hate](https://assetstore.unity.com/packages/tools/ai/love-hate-33063?aid=1100lGdc) integration when behavior decisions depend on factions, affinities, deeds, rumors, emotional state, personality, or relationship traits.

## Install the integration

1. Download the current **Love/Hate** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerLoveHate.unitypackage`.
3. Confirm **Get Affinity** appears in the Task List.

## What the integration adds

- **Read:** **Get Affinity**, **Get Arousal**, **Get Dominance**, **Get Emotional State**, **Get Faction Name**, **Get Happiness**, **Get Personality Trait**, **Get Pleasure**, **Get Relationship Trait**, **Get Temperament**.
- **Check:** **Has Ancestor**, **Has Direct Parent**, **Knows Deed**.
- **Change:** **Add Direct Parent**, **Remove Direct Parent**, **Modify Affinity**, **Modify PAD**, **Modify Relationship Trait**, **Report Deed**, **Set Affinity**, **Set Personality Trait**, **Set Relationship Inheritability**, **Set Relationship Trait**, **Share Rumors**.

## Build a first workflow

1. Create two Love/Hate actors and verify their affinity without a tree.
2. Use **Get Affinity** or **Get Relationship Trait** and store the result.
3. Branch on the stored value to select a friendly, neutral, or hostile behavior.
4. Use **Report Deed** or a Modify task, then read the value again to verify the relationship changed.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-playmaker"></a>

# PlayMaker

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/playmaker/)


Use the [PlayMaker](https://assetstore.unity.com/packages/tools/visual-scripting/playmaker-368?aid=1100lGdc) integration when a behavior tree should start, stop, signal, or wait for a PlayMaker 1 FSM, or when an FSM should control a Behavior Designer Pro tree.

## Install the integration

1. Download the current **PlayMaker** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerPlaymaker.unitypackage`.
3. Confirm **Start FSM** appears in the Task List.

## What the integration adds

- **Behavior Designer Pro tasks:** **Start FSM**, **Stop FSM**, **Resume FSM**, **Run Conditional FSM**, **Send Event**, **Broadcast Event**, **Synchronize Variable**, **Synchronize Variables**.
- **PlayMaker actions:** **Start Behavior Tree**, **Stop Behavior Tree**, **Resume Behavior Tree**, **Send Event**, **Syncronize Variable**, **Syncronize Variables**.

## Build a first workflow

1. Build a PlayMaker FSM that waits for a named event, performs one visible action, then executes **Resume Behavior Tree**.
2. Add **Start FSM** to the tree, select that event, and enable its completion wait.

![A Start FSM task starts the selected PlayMaker finite state machine from a behavior tree.](https://opsive.com/wp-content/uploads/2026/08/bdp-playmaker-start-fsm-task.webp?v=47c0e79077eb)

3. Use variable synchronization only for the values needed by both graphs.
4. Test cancellation so neither graph remains waiting after its owner is disabled.

![A Resume Behavior Tree PlayMaker action resumes the waiting behavior tree.](https://opsive.com/wp-content/uploads/2026/08/bdp-playmaker-resume-behavior-tree-action.webp?v=25bfceba9cd7)

For the reverse direction, start the Behavior Tree from the FSM and use **Resume FSM** when the tree reaches the handoff point.

![A Resume FSM task resumes the waiting PlayMaker finite state machine.](https://opsive.com/wp-content/uploads/2026/08/bdp-playmaker-resume-fsm-task.webp?v=50a4609959a7)

## Compatibility

The released bridge targets PlayMaker 1. PlayMaker 2 uses a different action API and is not a drop-in replacement.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-quest-machine"></a>

# Quest Machine

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/quest-machine/)


Use the Pixel Crushers [Quest Machine](https://assetstore.unity.com/packages/tools/game-toolkits/quest-machine-39834?aid=1100lGdc) integration when a behavior tree should create or give quests, inspect and change quest state, update quest UI, or send Quest Machine messages.

## Install the integration

1. Download the current **Quest Machine** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerQuestMachine.unitypackage`.
3. Confirm **Give Quest** appears in the Task List.

## What the integration adds

- **Quest generation and state:** **Generate Quest**, **Give Quest**, **Get Quest Count**, **Get Quest State**, **Set Quest State**, **Get Quest Node State**, **Set Quest Node State**, **Get Quest Counter Value**, **Set Quest Counter Value**.
- **World and UI:** **Control Spawner**, **Send To Message System**, **Set HUD**, **Set Journal UI**, **Show Quest Alert**, **Start Quest Dialogue**.

## Build a first workflow

1. Verify Quest Machine can give and display one quest without the tree.
2. Use **Give Quest** from an interaction or planner branch.
3. Read **Get Quest State** or a counter before choosing the next behavior.
4. Change one node or counter and confirm the Quest Journal displays the same result.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-sensor-toolkit-2"></a>

# Sensor Toolkit 2

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/sensor-toolkit-2/)


Use the [Sensor Toolkit 2](https://assetstore.unity.com/packages/slug/317234?aid=1100lGdc) integration when a behavior tree should pulse a sensor, inspect detections or signals, test obstruction, or steer a seeking sensor.

## Install the integration

1. Download the current **Sensor Toolkit 2** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerSensorToolkit2.unitypackage`.
3. Confirm **Has Any Detection** appears in the Task List.

## What the integration adds

- **Sensor control:** **Pulse**, **Clear**, **Set Seek Target**, **Set Seek Stop**, **Set Strafe Target**.
- **Detection and navigation checks:** **Has Any Detection**, **Is Detected**, **Is Obstructed**, **Get Detections**, **Get Signal**, **Get Detection Ray Hit**, **Is Seeking**, **Is Destination Reached**.

## Build a first workflow

1. Configure a Sensor Toolkit sensor and verify it detects one target without a tree.
2. Use **Pulse** when the sensor is not continuous, then **Has Any Detection**.
3. Store a detection with **Get Detections** or **Get Signal**.
4. Pass the selected target to a seek or attack branch and handle the no-detection failure.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-simple-waypoint-system"></a>

# Simple Waypoint System

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/simple-waypoint-system/)


Use the [Simple Waypoint System](https://assetstore.unity.com/packages/tools/animation/simple-waypoint-system-2506?aid=1100lGdc) integration when a behavior tree should select a path, choose a waypoint, and start, pause, resume, stop, or retime movement.

## Install the integration

1. Download the current **Simple Waypoint System** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerSimpleWaypointSystem.unitypackage`.
3. Confirm **Set Path** appears in the Task List.

## What the integration adds

- **Waypoint tasks:** **Set Path**, **Get Waypoint Of Path**, **Set Waypoint Of Path**, **Start Movement**, **Pause Movement**, **Resume Movement**, **Stop Movement**, **Change Speed**, **Update Bezier Path**.

## Build a first workflow

1. Create a Simple Waypoint System path and verify its mover follows the route.
2. Use **Set Path** and optionally **Set Waypoint Of Path**.
3. Run **Start Movement**, then pause and resume it from separate branches.
4. Use the movement owner's completion state before choosing the next behavior.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-state-designer"></a>

# State Designer

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/state-designer/)


Use the [State Designer](https://assetstore.unity.com/packages/tools/visual-scripting/state-designer-dots-powered-finite-state-machines-369152?aid=1100lGdc) integration when a behavior tree should start, stop, inspect, or exchange variables with a finite state machine without duplicating that state logic as tree branches.

## Install the integration

1. Download the current **State Designer** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerStateDesigner.unitypackage`.
3. Confirm **Start State Machine** appears in the Task List.

## What the integration adds

- **Behavior Designer Pro tasks:** **Start State Machine**, **Stop State Machine**, **Is State Machine Active**, **Compare State Machine Status**, **Synchronize State Machine Variables**.
- **State Designer nodes:** **Start Behavior Tree**, **Stop Behavior Tree**, **Is Behavior Tree Active**, **Compare Behavior Tree Status**, **Synchronize Behavior Tree Variables**.

## Build a first workflow

1. Put a State Machine component on the object that owns a short interaction or animation flow.
2. Add **Start State Machine** to the behavior tree and assign that State Machine.
3. Use **Compare State Machine Status** or **Is State Machine Active** before the next decision branch.
4. Add **Synchronize State Machine Variables** only for values that genuinely cross the graph boundary.
5. Stop or resume the state machine deliberately when the behavior branch is aborted.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-ultimate-character-controller"></a>

# Ultimate Character Controller

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/ultimate-character-controller/)


Use this integration when a behavior tree should make AI decisions while [Ultimate Character Controller](https://assetstore.unity.com/packages/tools/game-toolkits/ultimate-character-controller-233710?aid=1100lGdc) owns locomotion, abilities, items, health, effects, and animation.

## Install the integration

1. Download the current **Ultimate Character Controller** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerUltimateCharacterController.unitypackage`.
3. Confirm **Start Stop Ability** appears in the Task List.

## What the integration adds

- **Abilities and effects:** **Start Stop Ability**, **Is Ability Active**, **Start Stop Effect**, **Is Effect Active**, **Start Stop Interact**.
- **Items and aim:** **Set Aim Target**, **Start Stop Use**, **Reload**, **Start Equip Unequip**, **Start Item Set Ability**, **Get Item Identifier Amount**.
- **Health and state:** **Damage**, **Heal**, **Is Alive**, **Has Taken Damage**, **Get Attribute Value**, **Set State**, **Execute Event**.

The bridge supplies Ultimate Character Controller commands and checks, not sensing or pathfinding decisions. Use a movement task or sensing package for those decisions, then let Ultimate Character Controller apply the final character motion.

## Build a first workflow

1. Build the character as an Ultimate Character Controller AI Agent and verify its navigation and item without a tree.
2. Run the integration **Agent Setup** so the character receives Behavior Tree and Behavior Tree Agent components.
3. Use a decision branch to select a target, then set its aim target.
4. Start the required Ultimate Character Controller Aim, Use, Reload, or movement ability through the integration task.
5. On abort, stop any ability that should not remain active and clear the aim target.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)

---

<a id="page-behavior-designer-pro-integrations-ultimate-inventory-system"></a>

# Ultimate Inventory System

[View this page online](https://opsive.com/support/documentation/behavior-designer-pro/integrations/ultimate-inventory-system/)


Use this integration when an agent must inspect or change a released [Ultimate Inventory System](https://assetstore.unity.com/packages/tools/game-toolkits/ultimate-inventory-system-166053?aid=1100lGdc) Version 1 Inventory, Currency amount, panel, interaction, or save from a behavior tree.

## Install the integration

1. Download the current **Ultimate Inventory System** integration from [Opsive Downloads](https://opsive.com/downloads/).
2. Import `BehaviorDesignerUltimateInventorySystem.unitypackage`.
3. Confirm **Has Item With Definition** appears in the Task List.

## What the integration adds

- **Items:** **Add Item**, **Remove Item**, **Has Item With Definition**, **Has Item With Category**, **Compare Item Amount**, **Drop Item From Inventory**, **Exchange Item Between Inventories**.
- **Currency:** **Add Currency**, **Remove Currency**, **Has Currency**, **Compare Currency**.
- **Actions and UI:** **Use Item From Inventory**, **Use Item Object**, **Interact**, **Open Close Panel**.
- **Persistence:** **Save**, **Load**, **Delete Save**.

## Build a first workflow

1. Put the behavior tree on the Inventory GameObject for the first test.
2. Create a Selector whose first Sequence checks **Has Item With Definition** for one Health Potion.
3. Add **Use Item From Inventory** with the potion Item Action Set and action index.
4. Use the Selector fallback when the item is absent or the action fails.
5. Inspect the Inventory after the task so the real amount change, not only node success, is verified.

## Related pages

- [Integrations](https://opsive.com/support/documentation/behavior-designer-pro/integrations/)
- [Tasks](https://opsive.com/support/documentation/behavior-designer-pro/concepts/tasks/)
- [Variables](https://opsive.com/support/documentation/behavior-designer-pro/variables/)
- [Debugging](https://opsive.com/support/documentation/behavior-designer-pro/debugging/)
