I’ve been looking all over the google machine and the wiki the best help I can find to get my AI working through C++ is Unreal Engine 4 C++ Tutorial Version 4.0.2: Basic Artificial Intelligence - YouTube, yet because of the amount of errors I am having to squash and the fact that a lot of things have been depreciated and changed since that video was published, I am going to reach out to the AnswerHub for a pointer to a start up guide to getting the behavior tree running and attached properly in C++.
Hello, PalverZ
There are other tutorials available, but they also use the old version of the Engine.
However, you can use this tutorial with UE 4.7. For this, please apply these small changes to the tutorial:
-
Since TSubobjectPtr is deprecated, use the usual C++ pointer syntax:
UPROPERTY(Transient)
UBlackboardComponent* BlackboardComp; -
In the constructor use GENERATED_BODY() macro instead of GENERATED_UCLASS_BODY(). Please also note, that members of the class are now private by default, so you need to explicitly declare them as such with public keyword. FObjectInitializer is a parameter that should be used in constructor instead of FPostConstructInitializeProperties:
ATutorial_Controller::ATutorial_Controller(const class FObjectInitializer& ObjectInitiaizer)
: Super(ObjectInitiaizer) { …} -
In the Editor, please make sure Environment Querying System Flag is checked (go to Edit-Editor Preferences-General-Experimental). In the tutorial the parameter has a different name (Behavior Tree).
-
Use lowercase override keyword instead of an old OVERRIDE macro.
-
Change the implementation of Possess method of AITutorial_Controller class to:
void ATutorial_Controller::Possess(class APawn* InPawn)
{
Super::Possess(InPawn);
ATutorial_Bot* Bot = Cast<ATutorial_Bot>(InPawn);
if (Bot && Bot->BotBehavior)
{
UBlackboardData* BlackboardData = Bot->BotBehavior->BlackboardAsset;
BlackboardComp->InitializeBlackboard(*BlackboardData);
EnemyKeyID = BlackboardComp->GetKeyID(“Enemy”);
EnemyLocationID = BlackboardComp->GetKeyID(“Destination”);BehaviorComp->StartTree(*Bot->BotBehavior); }
}
-
In this file (Tutorial_Controller.cpp, as named in tutorial) add the include for Blackboard Key Types header file:
#include “BehaviorTree/Blackboard/BlackboardKeyAllTypes.h”
Change the implementation of SetEnemy method of AITutorial_Controller class to:void ATutorial_Controller::SetEnemy(class APawn* InPawn)
{
BlackboardComp->SetValue<UBlackboardKeyType_Object>(EnemyKeyID, InPawn);
BlackboardComp->SetValue<UBlackboardKeyType_Vector>(EnemyLocationID, InPawn->GetActorLocation());
}
Also please check if appropriate header files are included.
Hope this helped!
Have a great day!
I thank you kindly for the response. I actually figured most of that out from my “squashing errors” I mentioned before, I guess what I was hoping for was information on ways to use the
AIController::RunBehaviorTree(UBehaviorTree * BTAsset);
I didn’t even know what namespace or object that method was hiding in before but someone had mentioned it on the forums as opposed to this method, I have since found it, and I am sure I can get it to work .
Is there a more preferred method of implementing an AI and executing behavior trees from C++, as far as best practices?
But all in all you did answer my question, there are no up to date tutorials.
Please note, that StartTree() method, which is presented in the tutorial, actually has two parameters – one for behavior tree asset and one for execution mode. By default the second one is set to Looped mode, so we get the behavior, provided in the tutorial – the bot keeps following the player all the time (as long as the player remains in NavMeshBoundsVolume):
/** starts execution from root */
bool StartTree(UBehaviorTree& Asset, EBTExecutionMode::Type ExecuteMode = EBTExecutionMode::Looped);
You can, however, set the mode to SingleRun:
BehaviorComp->StartTree(*Bot->BotBehavior,EBTExecutionMode::SingleRun);
In this situation, the bot will only make a “step” towards the player and stop chasing, since the tree has only ran once.
This is pretty much what we get with RunBehaviorTree() method – it executes the Tree just once and there is no second parameter. So, if you replace the previous line with
RunBehaviorTree(Bot->BotBehavior);
, the behavior of the bot won’t change.
I didn’t even catch that thank you. I am only very loosely following the video and haven’t even gotten to the end truthfully, but it is good to know that the RunBehaviorTree() has no additional modes, Now I need to ask if by “Step” you mean like a Debugger steps in code or will it actually execute the behavior tree all the way through but only once?