Behavior Tree Tutorial

Hi :

Thank you for your interest, please like our facebook page, , you can follow updates to the project there.

I keep changing things with the Cat behavior and have tons of nodes I experiment with. I think it’s most import to keep it simple at first and get the timings of the animations working right with the Tree. I think the setup is going to be different for each game on what constitutes right. There’s a lot of communication with the Artist and experimenting. I have tons of animation clips of the cat to play with because of him. Having those assets available enables my being creative with the AI.

Basically, the cat was interested in the Laser but not ready to pounce on it yet, so it stared at it. It was in a branch on the Behavior Tree. It played the animation that made it look like that.

More specifically, I’m trying desperately to get the animGraphs to understand the Blackboard keys. No clue how to pass those values over.

Can anybody explain to me how the MoveTo BTTask works (or post source) and also how the BTDecorator MoveTo Goal Complete (cant remember exact name) determines when MoveTo is complete (or post source)?
I am currently doing a Behavior Tree without a Blackboard so I will need to rewrite these two classes to use a value from my AIEnemy instead of a Blackboard.

Much thanks.

details: Basically I have a group of AIEnemies. Each enemy has a TargetPosition FVector variable. When ANY AI in that group hits the Node to GroupPath, the Task sets all TargetPositions for the members of the group. All AI Enemies should now MoveTo the new TargetPosition instead of wherever they were moving to originally (sort of like moving the target).
The first group member that reaches the TargetPosition (moveto complete triggers) will again hit BTTask GroupRepath setting all group members MoveTo position to a new TargetPosition.

Nevermind I found it…I just need to understand how MoveTo goes from InProgress to Succeeded to allow the Decorator to trigger.



		if (RequestResult == EPathFollowingRequestResult::RequestSuccessful)
		{
			const uint32 RequestID = MyController->GetCurrentMoveRequestID();

			MyMemory->MoveRequestID = RequestID;
			WaitForMessage(OwnerComp, UBrainComponent::AIMessage_MoveFinished, RequestID);
			WaitForMessage(OwnerComp, UBrainComponent::AIMessage_RepathFailed);

			NodeResult = EBTNodeResult::InProgress;
		}
		else if (RequestResult == EPathFollowingRequestResult::AlreadyAtGoal)
		{
			NodeResult = EBTNodeResult::Succeeded;
		}


The Blackboard is part of the BehaviorTree system. I don’t use it outside of it. I use a Blueprint Interface function to call onto the Anim Blueprint from a BT Task and pass new variables to it.

Trying to do that too! How though?

There are other threads and documentation on Blueprint Interfaces.

Here is a good place to start:
https://answers.unrealengine.com/questions/4964/how-to-have-blueprints-pass-variables-to-each-othe.html

[TABLE]

http://upload.wikimedia.org/wikipedia/commons/9/97/NetworkTopologies.svg

Just want to say a Special Thanks to for the UDK BTKIT. Its been a big help in the R & D of BRAINS. I’m tracking your progress I CAN HAS LAZER.

I’m starting to see other Behavior Topologies form working with BRAINS in Kismet. I’m doing my best to stick to the Tree Topology, but, I have strong urges to connect nodes in alternative ways to form other types of Behavior Networks. I’m curious if others are experiencing this?

Great Tutorial and introduction into BehaviorTrees. I’m trying to get the code running but i got some compile Errors :


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

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

At this place it says : “no instance of overloaded function “Cast” matches the Argument list APawn*”
and “Identifier ABot is undefined”.
Maybe someone got an idea.

This usually means you’re missing a header include somewhere. There’s not enough information here to help you. Maybe you could supply us with a stripped down yet still not compiling version of your cpp and h files?

Hi,
this is my BotController.h


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/AIController.h"
#include "BotController.generated.h"

/**
 * 
 */
UCLASS()
class ABotController :  AAIController
{
	GENERATED_UCLASS_BODY()

	UPROPERTY(transient)
	TSubobjectPtr<class UBlackboardComponent> BlackboardComp;

	UPROPERTY(transient)
	TSubobjectPtr<class UBehaviorTreeComponent> BehaviorComp;

	virtual void Possess(class APawn* InPawn) OVERRIDE;

	virtual void BeginInactiveState() OVERRIDE;

	
};

and this is the BotController.cpp


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "MyProject2.h"
#include "BotController.h"


ABotController::ABotController(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
	BlackboardComp = PCIP.CreateDefaultSubobject<UBlackboardComponent>(this, TEXT("BlackBoardComp"));
	BehaviorComp = PCIP.CreateDefaultSubobject<UBehaviorTreeComponent>(this, TEXT("BehaviorComp"));
	bWantsPlayerState = true;

}


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

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

	// start behavior
	if (Bot && Bot->BotBehavior)
	{
		BlackboardComp->InitializeBlackboard(Bot->BotBehavior->BlackboardAsset);

		BehaviorComp->StartTree(Bot->BotBehavior);
	}
}

void ABotController::BeginInactiveState()
{
	Super::BeginInactiveState();
}

It is working when i include the Bot.h file to the BotController.cpp like this :


#include "MyProject2.h"
#include "BotController.h"
#include "Bot.h"

My question is then, why do i have do include the Bot.h file so that the Compiler recognizes the ABot class ?
The ShooterGame example from Epic doesn’t include the ShooterBot.h either and still the cast in ShooterAIController.cpp does work (AShooterBot* Bot = Cast(InPawn); )

PS.
This is My Bot.h and Bot.cpp


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "GameFramework/Character.h"
#include "Bot.generated.h"

/**
 * 
 */
UCLASS()
class ABot :  ACharacter
{
	GENERATED_UCLASS_BODY()

	UPROPERTY(EditAnywhere, Category = Behavior)
	class UBehaviorTree* BotBehavior;
};


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "MyProject2.h"
#include "Bot.h"


ABot::ABot(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{
}

As a rule of thumb you’re better off manually including files you need, especially that at some point we might drop precompiled headers if this proves to be beneficial for compilation times.

ShooterBot.cpp does not include ShooterBot.h directly since it’s already included in the PCH as part of ShooterGameClasses.h. Similarly, your Bot.h file should be included in MyProject2Classes.h. If it’s not then there’s a bug. In such cases we usually rebuild whole project, sometimes even manually deleting intermediate files. If it doesn’t help, please report a bug (or just stick to manually including required headers :smiley: )

Thats interesting, thx. I found an empty MyProject2Classes.h


// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
/*===========================================================================
	C++ class boilerplate exported from UnrealHeaderTool.
	This is automatically generated by the tools.
	DO NOT modify this manually! Edit the corresponding .h files instead!
===========================================================================*/
#pragma once





Only 4 whitespaces in it and thats it. So i cleaned the solution and rebuild it, but that didn’t help. Then i deleted the Intermediate files and generated new Visual Studio Files (rightclick on the uproject file) but still an empty MyProject2Classes.h

While I haven’t thought about trying other Topologies, I have played around a bit with using the Behavior Tree system for other things than A.I. For example, I added a behaviorTree component to a Hud class, and used the behavior tree to “draw” the HUD/UI. At the moment it is just a test of concept, but it does seem like it could be useful, as to myself anyway it is easier to see what elements will be draw in any given situation, than having a bunch of if tests in a blueprint. However the behaviorTree component would need a few changes for this to really be useful, as at the moment only one task is executed per tick. So a large HUD/UI system using this, could be slow to respond (depending on how many tasks it used).


I’ve also looked a bit into adapting the behaviorTree system, so that it can be used as a HTN (Hiearichal Task Network), or at least some kind of hybrid system.

Awesome! No one ever said BTs are to be used only to drive AI. It’s a decision making architecture, so should be applicable whenever there’s a need to make a decision. Great idea! :smiley:

Behavior Tree system had been implemented to be controlled via a component to empower just that - adding it to anything that might need it. There may be some AI dependencies, but should not be hard to remove once we have a use case :slight_smile:

Thanks . I’m just glad somebody got some use from the UDK Behavior Tree kit. I mostly just heard crickets on the forums regarding it. Bt’s were maybe too far a departure from the State system that the community was familiar with at that time. I thought about making a Kismet Editor, but just kept it at xml which was a step up from the original macro only system for defining trees.

I agree whole heartedly, I’m using them to manage complex weapon behaviors,etc. They are very scalable. I intend to use Behavior Trees/Behavior Networks to manage Dynamic Quest Behavior aka Quest Branching. At a high-level: Quest Objectives are Task Leaf Nodes arrange in a Behavior Tree. Objectives are Condition Nodes, and the acceptable Actions a Player can take are Action Nodes.

Hey and ,

Thanks for the tutorial and all of your documentation. It really helped me a lot. I ended up making a tutorial for people who like to follow along.

AI Behavior Tree & NavMesh

Hey alg0801 did you ever find out how to fire off the change from InProgress to Succeeded? I’m currently on a similiar task.

Really good thread on behavior tree, but I still don’t understand some concepts.
Like what is the intended way to set blackboard values when an event fires? What I mean is that for example I have an RTS in which I can control Characters to move to a desired destination. So when the Character is selected and then I click somewhere, I want a little more complex behavior than SimpleMoveTo, so I create my own AiController, and a BTree for it with a Blackboard.
So the click command can get through to the aicontroller, and the BTree knows how to move to the destination. But where should I set the blackboard value for the target location? Are services meant for that? Some ticking service that checks if command was given by getting values from the aicontroller every X seconds? First I made this happen with a BehaviorTask that does nothing else, just sets all the blackboard values by asking the AIController everything, and the finishes with success, then I put a cooldown decorator on top of it with 0.5 second duration, and put it as the first element in a sequence below root.
A service I think would be pretty much the same thing.
But both ways, I need to store some data about whether or not a command was given and where, and it just seems a little ugly.

Currently I set the blackboard data in the aicontroller when the click happens, which seems good.
Here’s a picture of how I set blackboard values from the aicontroller:


Is this the way to go?

My second question is an easier one, but I couldn’t find it anywhere:
There is a decorator that can check if a vector blackboard value is set. But if I want to unset it I would neet to set it to the FVector(floatmax, floatmax, floatmax), but I didnt find such a thing in blueprint. Can that be done only in code? (If i dont connect it with anything, it just sets it to zero)
Of course it can be done with a workaround by creating a bool variable storing if the value is set. But then the value is set decorator for type vector kind of loses its purpose.

This is a fantastic tutorial! Thanks so much.

One question about making new blueprints for tasks, services, etc.: What is the OwnerActor pin that comes out of EventReceiveTick in the blueprint used for? I end up having to cast it to AIController, then doing Get ControlledPawn so I can do things like GetActorLocation. Is there a more direct way? What would I do with the OwnerActor directly?

Thanks again.