Multiple AI Bots shares the same behavior tree?

Hi guys,

All was fine for one AI,but after I’ve added more I was surprised to see that all shared the same behavior tree,this is actually kind of funny to watch :smiley: but its not what i’m looking for.
so I have in AIController the possess function and the constructor that sets the blackboard and behavior tree.



AEnemyAIController::AEnemyAIController()
{
	BlackboardComp = CreateDefaultSubobject<UBlackboardComponent>(TEXT("BlackboardComp"));
	BehaviorComp = CreateDefaultSubobject<UBehaviorTreeComponent>(TEXT("BehaviorComp"));
}
void AEnemyAIController::Possess(APawn *InPawn)
{
	Super::Possess(InPawn);

	ACharacter*Char = Cast<ACharacter>(InPawn);

	if (Char && Char->BotBehavior)
	{
		BlackboardComp->InitializeBlackboard(*Char->BotBehavior->BlackboardAsset);

		TargetKeyID = BlackboardComp->GetKeyID("Target");
                ...
		BehaviorComp->StartTree(*Char->BotBehavior);
	}
}

And in the main behavior tree Selector class I have functions that set different objects like find the closest weapon/ medical kit etc.The problem is that the selector finds the closest weapon but only for the first AI and all others AI goes for it.The same goes if I hit a Bot all others bots go for the closest medical hit,even if they are not hit,so this makes me thing that they share the same instance of behavior tree.Shouldn’t editor suppose to create a new instance of the behavior tree for each AI like it is with the controller and other classes or did I not set something right ?
Ive set the AIController in BP of the class Player on Pawn ->AI Controller Class

When debugging and watching the tree execute, you can select which AIController you are debugging from the drop-down - they have different state.

Yep they have the same targets.Controller_0 sets correctly the closest weapon and the Controller_1 sets the same weapon even if it is another closest weapon to him,same think with medical kit.
Is maybe because I didn’t set a clone vision for each? instead I’m using a for loop for each actor and pick the closest one?


void UBTService_CheckPlayerCondition::CheckForWeapon()
{
	FVector CharacterLocation = CharPC->GetCharacter()->GetActorLocation();
	AWeaponBase* WeaponFound = nullptr;
	float ClosestDistance = -1;
	float Distance;

	//iterate for all weapons actors in the world
	for (TActorIterator<AWeaponBase> ActorItr(GetWorld()); ActorItr; ++ActorItr)
	{
		//find the closest one
		if (!ActorItr->IsAttachedToCharacter())
		{
			Distance = (CharacterLocation - ActorItr->GetActorLocation()).Size();
			if (ClosestDistance == -1 || ClosestDistance > Distance) {
				WeaponFound = *ActorItr;
				ClosestDistance = Distance;
			}
		}
	}

	if (WeaponFound)
		BlackboardComp->SetValue<UBlackboardKeyType_Object>(CharPC->WeaponKeyID, WeaponFound);
	else
		BlackboardComp->ClearValue(CharPC->WeaponKeyID);
}

CharPC and BlackBoardComp is instantiated in TickNode


CharPC = Cast<AEnemyAIController>(OwnerComp.GetAIOwner());
	BlackboardComp = OwnerComp.GetBlackboardComponent();

But shouldn’t that work because CharPC and BlackboardComp are different objects for each AI?I’m confused.

Oke I found the problem and now i feel dumb because I wasted good hours on this, in blackboard the keys have an option called “Instance Synced” if that is checked it will sync with all the instance of the blackboard.Why in the world would you put that checked on default ? :))

1 Like

Oke I found the problem and now i feel dumb because I wasted good hours on this, in blackboard the keys have an option called “Instance Synced” if that is checked it will sync with all the instance of the blackboard.Why in the world would you put that checked on default ? :))
[/QUOTE]

OMG Thank you! I’ve spent hours trying to work out why this wasn’t working for me. My google-fu finally brought me here and this solved all my problems.

Oke I found the problem and now i feel dumb because I wasted good hours on this, in blackboard the keys have an option called “Instance Synced” if that is checked it will sync with all the instance of the blackboard.Why in the world would you put that checked on default ? :))
[/QUOTE]

As far as i understand it the blackboard variables with “Instance synced” on can essentially be interpreted as static variables in C++, which means all actors that use instances of that blackboard share that variable and its value.