Refactoring
Refactor custom tasks and variables without accidentally replacing the values saved in your behavior trees. The original Behavior Designer stores task and SharedVariable type names in its own serialized data, so renaming a C# type is different from renaming a node in the editor.
Before changing a serialized type
- Save a version-control checkpoint containing the scripts, scenes, prefabs, external behavior trees, and global variables that use the type.
- Keep the old type available while you identify every tree and variable that uses it. Include trees that are loaded through Behavior Tree Reference.
- Change one kind of identity at a time: the C# type, a serialized field, or a variable’s Name.
- Reopen representative trees and inspect their field values, shared-variable assignments, task references, and child connections before saving the migration across the project.
Moving a script between folders does not change the serialized task type if its namespace and class name stay the same. Moving it across an assembly-definition boundary also requires the destination assembly and its dependencies to be available to the player. The classic loader searches loaded assemblies for the stored full type name.
Rename a class or namespace
The classic loader does not use Unity’s MovedFrom attribute to resolve task or SharedVariable type names. Adding that attribute alone will not repair a renamed classic task or custom SharedVariable class.
If you only want a different name in the task list, use TaskName instead of renaming the C# class. TaskCategory changes where a task appears in the task list. Neither operation needs to change the serialized type identity. See Task Attributes.
For an actual type rename, keep a compatible type under the old namespace and class name until you have migrated all affected data. If a rename has already produced unknown tasks or missing variables, first restore the old type and reopen the original saved tree. Replacing individual tasks is an alternative when you are prepared to reconfigure and verify them; it is not a project-wide type-rename command.
Changing a custom SharedVariable class name also changes the type part of fields declared with that class. Renaming the field and adding a field-name attribute does not compensate for that type change. Keep the old variable wrapper available until you have explicitly migrated its definitions and task assignments.
Rename a serialized field
Keep the field’s type and serialized value shape unchanged, and put Unity’s FormerlySerializedAs attribute on the renamed field. Both the classic JSON and binary loaders check its previous field name.
For example, this task’s field was previously named speed and had the same SharedFloat type:
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using UnityEngine.Serialization;
public class ReadMovementSpeed : Action
{
[FormerlySerializedAs("speed")]
public SharedFloat movementSpeed;
public override TaskStatus OnUpdate()
{
return movementSpeed.Value >= 0f
? TaskStatus.Success
: TaskStatus.Failure;
}
}
The attribute preserves a field name, not an arbitrary conversion between types. Check a saved nondefault value and a shared-variable assignment after reloading. Keep the compatibility attribute while older trees may still be loaded.
Replace a task in the graph
Outside Play Mode, right-click a task and choose Replace, then choose the replacement task from the category menu. Replace one task at a time so you can inspect the result.

For an ordinary task, replacement creates a new instance. The editor remembers its position and reconnects its parent; children can reconnect only when the replacement accepts children. Re-enter the replacement’s settings and recheck any other tasks that referenced the old task. References to the removed instance can be cleared.
An Unknown Task leaf can retain a copy of its original serialized fields, and Replace attempts to deserialize those fields as the chosen type. This is limited recovery, not a guarantee: field names and types must match. The JSON replacement path does not supply the original Unity-object reference list, so replacement can fail when a saved field references a GameObject, Transform, asset, or other Unity object. Restore the missing type and original saved tree to recover those references. Unknown Parent Task does not have the same saved-field recovery payload.
Recover unknown tasks or variables
If a task becomes unknown after a script change, check compilation, its full namespace and class name, and whether its assembly is available. Restore the missing type before making unrelated graph edits. The editor saves graph changes as you work; saving an unknown parent can discard its original custom fields and type identity.
A missing custom SharedVariable type is more serious than a renamed variable label: the classic loader returns no variable instance for an unresolved type, and serialization omits null variables. Restore the wrapper type and reload the last good tree or global-variable asset before saving. Replace applies to graph tasks, not missing variable definitions.
If the affected data has already been saved, restore both the scripts and the serialized tree, scene, prefab, or global-variable asset from the checkpoint, then perform the migration again.
Rename a variable’s Name
Use the Name field in the Variables tab for an existing variable. This changes the variable name and its lookup, not its C# type. Check code that calls GetVariable or SetVariable, property mappings, global-variable consumers, and external-tree bindings that use the old string. A C# symbol rename cannot update those string-based contracts automatically.
See Variables, External Behavior Trees, and Task Attributes.