How to set Behavior Tree in C++

How to set Behavior Tree in C++?

It seem that this code does not work.

static ConstructorHelpers::FObjectFinder<UBehaviorTree> BTOb(TEXT("BlackboardData'/Game/AIBattle/AI/Buildings/BB_test.BB_test"));
	BotBehavior = BTOb.Object;

Thank you in advance.

Having the same problem; did you manage to solve it?

AAIController::RunBehaviorTree(UBehaviorTree* BTAsset)

You just need to do two things. First, in the construction function of your character, the BehaviorTree should be loaded and the AIControllerClass should be set. Second, in your AIController class, you should start your tree in the function AIController::Possess(). Here is my code.
ASoldierTeam::ASoldierTeam()
{
FName BTPath = TEXT(“BehaviorTree’/Game/AI/BT_SoldierTeam.BT_SoldierTeam’”);
TeamBehavior = Cast(StaticLoadObject(UBehaviorTree::StaticClass(), NULL, *BTPath.ToString()));

	AIControllerClass = ASoldierTeam_AIController::StaticClass();
}

ASoldierTeam_AIController::ASoldierTeam_AIController(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
	BlackboardComp = ObjectInitializer.CreateDefaultSubobject<UBlackboardComponent>(this, TEXT("BlackBoardComp"));

	BrainComponent = BehaviorComp = ObjectInitializer.CreateDefaultSubobject<UBehaviorTreeComponent>(this, TEXT("BehaviorComp"));

}

void ASoldierTeam_AIController::Possess(APawn* InPawn)
{
	Super::Possess(InPawn);

	ASoldierTeam* Bot = Cast<ASoldierTeam>(InPawn);

	// start behavior
	if (Bot && Bot->TeamBehavior)
	{
		if (Bot->TeamBehavior->BlackboardAsset)
		{
			BlackboardComp->InitializeBlackboard(*Bot->TeamBehavior->BlackboardAsset);
		}
		BehaviorComp->StartTree(*(Bot->TeamBehavior));
	}
}
1 Like

Yeah, this is how I implemented it (inspired by Survival tutorial by Tom Looman), but the initial question was: is there any particular reason why it doesn’t work with FConstructorHelpers::FindObject() while (as per your example) it does with StaticLoadObject?

It seem the path of the behavior tree was wrong in my initial question…I made a mistake, the original path pointed to Blackboard not to BehaviorTree. I modify the code, and it still works. So if your path is correct and problem still exists, it might be other reason. Or you can set the break point to check if the BehaviorTree has been successfully loaded. Here is my new code.
static ConstructorHelpers::FObjectFinder BTob(TEXT(“BehaviorTree’/Game/AI/BT_SoldierTeam.BT_SoldierTeam’”));
TeamBehavior = BTob.Object;

That’s the same code I’m using (of course with my own path), I also tried with a breakpoint, but when I start the editor in Debug mode it just hangs to 72% loading (on that line), and never goes further. Looks like it can’t find/load the asset, though it’s there.

It never go further because you set the break point and you can press F10 to step over. And you can check if your variable has been set correctly. Normally, if the path is correct and the variable type is correct, it will work. You can also check if the AIController run the correct behavior tree. But it still quite hard to analyze because lack the information. You can contact me or send me the code at ethancs1993@gmail.com

I know how a breakpoint works :smiley: I mean that, even without breakpoint, that line of code will make the editor loading hang at 72%, no matter what. Also, the object appears null. I checked the code again, and the only difference with yours is that I use ConstructorHelpers::FObjectFinder bla bla, as explained in the docs (Referencing Assets in Unreal Engine | Unreal Engine 5.1 Documentation).

Is there any error message? Like ‘Error: CDO Constructor : failed to find …’ ?

Hmm I ran into same problem and here are 2 solutions, first you must do:

AIControllerClass = AMyAI_Controller::StaticClass();

then you can do it with constructor:

struct FConstructorStatics
	{
		ConstructorHelpers::FObjectFinderOptional<UBehaviorTree> Beh_Tree;
		FConstructorStatics()
			: Beh_Tree(TEXT("/Game/Blueprints/MyAI_Beh_Tree"))
		{
		}
	};
	static FConstructorStatics ConstructorStatics;
	MyAIBehavior = ConstructorStatics.Beh_Tree.Get();

or this way without constructor:

FString Path = "/Game/Blueprints/MyAI_Beh_Tree";
MyAIBehavior = Cast<UBehaviorTree>(StaticLoadObject(UBehaviorTree::StaticClass(), nullptr, *Path));

Don’t forget to include:

#include "BehaviorTree/BehaviorTree.h"

and if you do it using constructor of course also:

#include "UObject/ConstructorHelpers.h"

RunBehaviourTree(Bot->TeamBehavior);
Use this instead of “BehaviorComp->StartTree(*(Bot->TeamBehavior));” when initialising