Home Game Development Enemy AI With Conduct Timber In Unreal Engine

Enemy AI With Conduct Timber In Unreal Engine

0
Enemy AI With Conduct Timber In Unreal Engine

[ad_1]

In my earlier publish about enemy AI we created enemy patrol, chase and assault conduct utilizing Blueprints and C++.

On this publish we’re going to do the identical however we’re going to use conduct timber and sensing.

Obtain Belongings And Full Undertaking For This Tutorial

To comply with together with this tutorial, please obtain the began mission by clicking on the inexperienced Obtain belongings button above.

Within the downloaded folder you will discover the completed mission, and the began mission which I ready so that you can comply with this tutorial.

Necessary Data Earlier than We Begin

This tutorial is supposed for intermediate and superior Unreal Engine builders. If you’re an entire newbie then I like to recommend that you simply first undergo my C++ tutorial collection, then undergo my introduction to Unreal Engine tutorial collection and after that undergo this tutorial.
 

Blackboards And Conduct Tress

Blackboards and Conduct Timber are two important AI frameworks constructions in Unreal Engine. Blackboards are used to retailer information for the Conduct Tree and the Conduct Tree acts like a mind of the AI.
 
Mixed collectively, these two elements enable us to create superior AI conduct in Unreal Engine sooner and extra environment friendly than in another approach.
 
Let’s begin by creating the elements that we’d like. Open the began mission that’s offered on this tutorial after which contained in the Content material -> Blueprints folder, Proper Click on -> New Folder and identify it AI.
 
Contained in the AI folder Proper Click on -> Synthetic Intelligence -> Blackboard:
 

Img-1-3.jpg

Identify the Blackboard BB_EnemyAIData after which Proper Click on -> Synthetic Intelligence -> Conduct Tree:

Img-2-3.jpg

Double click on BB_EnemyAIData to open the Blackboard within the editor. You will notice two tabs in aspect the Blackboard editor, one named Blackboard and the opposite Blackboard Particulars:

Img-3-3.jpg

Within the Blackboard tab we’ll see all of the keys that we outlined which represents the info of the Blackboard, and within the Blackboard Particulars tab we’ll see particulars about particular key we choose.

Within the Blackboard tab you will note a New Key blackboard icon, that is the place we create new keys for the Blackboard.

Click on on the New Key icon and create two new keys, one will likely be a bool named Can See Participant, and the opposite will likely be a Vector named Random Patrol Location:

Img-4-3.jpg

Now choose the SelfActor variable and identify it Participant Goal. Ensure that the Key Kind is about to Object within the Blackboard Particulars tab and that the Base Class is about to Actor:

Img-5-3.jpg

These are the variables that we’ll use to form the enemy AI conduct which can occur within the BT_EnemyAI Conduct Tree.

Creating Enemy AI In The Conduct Tree

The very first thing we have to do is open the BT_EnemyAI, click on on the Root node, and within the Particulars tab for the Blackboard Asset choose the BB_EnemyAIData:

Img-6-3.jpg

It will enable the Conduct Tree to make use of the info we outlined within the BB_EnemyAIData Blackboard.

Now Left Click on and drag from the Root node, whenever you launch a pop up window will seem and you’re going to click on on Selector:

Img-7-3.jpg

You too can Proper Click on wherever within the editor for the Conduct Tree and click on on the Selector:

Img-8-3.jpg

The Selector node executes its youngsters from left to proper, and it’ll cease executing its youngsters when certainly one of their youngsters succeeds. This mainly implies that the Selector will execute the duty nodes we offer, and when that job finishes its execution, the Selector node will begin executing once more from begin.

Let’s create a Sequence node and make the Selector node level to it:

Img-9-3.jpg

The Sequence node additionally executes its youngsters from left to proper and stops when certainly one of their youngsters succeeds. From this Sequence node, we’re going to calculate a random place in area, after which make the AI transfer in the direction of that place.
 
To do that, first we have to create a Process which might be completed in certainly one of two methods. The primary approach is to click on on the New Process button within the BT_EnemyAI:
 

Img-10-3.jpg

One other approach is to Proper Click on -> Blueprint Class, and within the search bar for All Courses inherit BTTask_BlueprintBase:

Img-11-3.jpg

Earlier than we create a brand new Process, within the AI folder, Proper Click on -> New Folder and identify it Duties. Now create a brand new Process and identify it Task_GetRandomLocationPoint then open it within the editor.

Contained in the My Blueprint tab underneath Variables, create a brand new variable of kind Blackboard Key Selector Construction, identify it Random Location Key and in addition make it a public variable:

Img-12-3.jpg

With a purpose to entry the Keys we outlined in BB_EnemyAIData Blackboard we have to present the Blackboard Key Selector Construction because the parameter.

Subsequent, we’re going to override a operate referred to as Obtain Execute AI:

Img-13-3.jpg

This operate will present us entry to the managed pawn e.g. the pawn that will likely be managed by the AI, in order that we will entry its place and from it generate a random level:
 

Img-14-3.jpg

You may copy the nodes from right here:
 

We have to name Set Blackboard Worth as Vector as a result of the Random Patrol Location is a Vector kind variable. We additionally must name the End Execute node to point that the Process has completed executing, in any other case the Process will solely execute as soon as.

Compile and save the adjustments we made to Task_GetRandomLocationPoint and open BT_EnemyAI editor. We are able to both Proper Click on and underneath Duties seek for the Task_GetRandomLocationPoint or drag a node from the Sequence node and choose the Task_GetRandomLocationPoint:

Img-15-3.jpg

Now choose the brand new job node, and within the Particulars tab for the Random Location Key, click on on the drop down record and choose Random Patrol Location variable:

Img-16-Fixed.jpg

That is how we’re going to point out that the Random Location Key variable we outlined within the Task_GetRandomLocationPoint is pointing to the Random Patrol Location variable we outlined in BB_EnemyAIData Blackboard.

The final step is to name the Transfer To Process by Proper Click on -> Duties -> Transfer To:

Img-17-3.jpg

You too can drag a node from the Sequence, however make it possible for the Transfer To job is positioned after the Task_GetRandomLocationPoint as a result of for those who keep in mind, the Sequence node will execute its youngsters e.g. duties, from left to proper, so we first must generate a random location level, after which make the AI transfer to that location.

The order of execution can be denoted with numbers on every node, the decrease the quantity means the node will likely be executed first:

Img-18-3.jpg

The final step is to pick the Transfer To node, and within the Particulars tab for the Blackboard Key choose the Random Patrol Location:

Img-19-3.jpg

Working Conduct Tree From AI Controller

To make the Conduct Tree management our enemy character, we have to create an AI Controller Blueprint. Contained in the Content material -> Blueprint -> AI, Proper Click on -> New Blueprint Class and inherit from AIController and identify the brand new Blueprint BP_BB_EnemyAIController:

Img-20-3.jpg

Earlier than we run the Conduct Tree from the AIController Blueprint, open the BP_Enemy_BT situated in Content material -> Blueprints.

Within the Parts tab Choose the highest mother or father BP_Enemy_BT(self), and within the Particulars tab underneath Pawn for the AI Controller Class choose BP_BB_EnemyAIController:

Img-21-3.jpg

Now open the BP_BB_EnemyAIController Blueprint within the editor. Create a brand new variable of kind Conduct Tree and identify it AI Conduct Tree:

Img-22-3.jpg

Subsequent, choose the AI Conduct Tree variable, and within the Particulars tab underneath Default Worth choose the BT_EnemyAI:

Img-23-3.jpg

To make the Conduct Tree run, we have to add the next nodes:

Img-24-3.jpg

You may copy the nodes from right here:

Now let’s run the sport and try it out:

As a result of the BP_BB_EnemyAIController is now controlling the enemy, as quickly as the sport began and the BeginPlay inside BP_BB_EnemyAIController was executed which has the code to run the Conduct Tree we noticed that the enemy began patrolling the extent.

We additionally noticed within the BT_EnemyAI the execution circulate of the nodes. You may all the time open the Conduct Tree Blueprint and watch the execution circulate for debugging functions to see if every part works.

Pawn Sensing Part

Within the earlier publish about enemy AI we used collision elements to detect the presence of the participant, on this publish we’re going to use PawnSensing part which permits our AI to have human senses like listening to and seeing.

One tip in terms of establishing the AI system, if in case you have an AIController like we do on this instance, you possibly can connect the PawnSensing part on the AIController.

That approach, each enemy in your sport that makes use of that AI controller may have the sensing capacity, which is a lot better than to go in each enemy blueprint and fix a PawnSensing part.

So let’s open BP_BB_EnemyAIController and within the Parts tab click on on Add Part button and fix the PawnSensing part:

Img-25-3.jpg

Open the Viewport tab and choose the PawnSensing part within the Parts tab, this what you will note:

Img-26-3.jpg

Within the Particulars tab we’ve the settings for the PawnSensing part, particularly the AI settings which is what we’re focused on:

Img-27-3.jpg

We’re going to use sight sensing to make the enemy see the participant within the sport. For that we’ve the Sight Radius settings, which is the radius of the enemy’s sight. We even have the Peripheral Imaginative and prescient Angle which is the view angle of the enemy.

We’re going to change the Peripheral Imaginative and prescient Angle to 60:

Img-28-3.jpg

You’ll discover that this has additionally change the form of the PawnSinsing part within the Viewport tab:

Img-29-3.jpg

I’m additionally going to vary the Sensing Interval to 0.2:
 

Img-30-3.jpg

The Sensing Interval implies how usually the system will replace the senses, setting the worth at 0.2 means each 0.2 seconds the system will replace the senses and make the AI “see” within the sport.

These are the settings that I’m going to make use of for our instance, you might be, in fact, free to experiment with all of the values and see the result of the adjustments you made.

You can also make the enemy detect the participant on massive distances or you can also make the enemy detect the participant solely when he’s shut sufficient to the enemy, so be my visitor and experiment with totally different choices which is the easiest way to be taught.

Subsequent, I’m going to pick the PawnSensing part and within the Particulars tab scroll all the way in which down till you see the Occasions settings. Click on on the + button for the On See Pawn:

Img-31-3.jpg

It will create the On See Pawn node within the Occasion Graph which is known as each time the PawnSensing part sees an Actor within the sport, and we will use this node to check if the Actor that the PawnSensing part sees is the participant character, then we will make the enemy chase the participant.

Sensing The Presence Of The Participant

Earlier than we add the code that can sense the participant’s presence, we’re going to create a operate that’s going to set the values within the Blackboard Blueprint when the participant is seen or not.
 
Contained in the BP_BB_EnemyAIController create a brand new operate and identify it SetCanSeePlayer:
 

Img-32-3.jpg

This operate goes to have two parameters, a bool parameter referred to as Can See Participant, and an object parameter referred to as Participant Object. We’ll use these two parameters to indicate if we see the participant, and if we do, we can even move a reference to the participant actor:

Img-33-3.jpg

You may copy the nodes from right here:

Now that we’ve the CanSeePlayer operate, we will return within the Occasion Graph tab and contained in the On See Pawn occasion, the very first thing we’ll do is check if the Pawn the enemy sees, is the participant:

Img-34-3.jpg

For the reason that mission I’m utilizing is the Third Individual template mission, the participant character makes use of the ThirdPersonCharacter Blueprint, that’s the reason we’re casting the Pawn parameter from the On See Pawn occasion to the ThirdPersonCharacter.

If the solid succeeds, meaning the enemy can see participant, so we name the SetCanSeePlayer operate passing true for the Can See Participant parameter and passing ThirdPersonCharacter because the Participant Object parameter.

When you keep in mind, we set the Sensing Interval for the PawnSensing part to 0.2, which means each 0.2 seconds the PawnSensing part will likely be up to date.

That is necessary as a result of at present we solely have the logic to make the enemy see the participant, however what if the participant escapes the enemy’s sight? In that case we’d like a logic that can inform us that now the enemy doesn’t see the participant anymore.

For that I’m going to make use of a operate referred to as Retriggerable Delay:

Img-35-3.jpg

You may copy the nodes from right here:

The Retriggerable Delay operate has the identical performance because the Delay operate, it is going to anticipate the desired period and after that it’ll proceed executing.

However the distinction is, whenever you name the Retriggerable Delay operate whereas it’s counting down, it is going to reset the countdown and begin from scratch.

For that purpose, for the Period parameter I used the Sensing Interval worth of the PawnSensing part, and I’ve multiplied it by 2, which implies when the PawnSensing part sees the participant, it is going to name the Retriggerable Delay operate which can begin its countdown.

Within the meantime, the PawnSensing part will proceed to run, and if it sees the participant once more, it is going to name the Retriggerable Delay operate which can reset its countdown, and since we set the Period of the delay to be 2 occasions the Sensing Interval, meaning if the PawnSensing part doesn’t see the participant for 0.4 seconds, then the Retriggerable Delay operate will undergo and it’ll name the SetCanSeePlayer to tell us that the enemy doesn’t see the participant anymore.

So now that the enemy can see the participant, we have to go within the BT_EnemyAI and add one other sequence that can name the Transfer To Process and make the AI transfer to the Participant Goal:

Img-36-3.jpg

As you possibly can see I’ve set the Sequence that can make the AI chase the participant on the left aspect, as a result of I need that job to be executed first. When that job is completed then the tree will transfer to the second Sequence.

Don’t overlook to pick the Transfer To node and for the Blackboard Key set the Participant Goal:

Img-37-3.jpg

We’re nonetheless not completed as a result of the present arrange of the tree doesn’t have any circumstances that have to be checked earlier than we carry out every job. For instance, if we don’t have a reference to the participant, we will’t make the AI transfer to the participant. For that we’re going to add a decorator to the Sequence.

To do this, merely Proper Click on on the Sequence and scroll down the place it says Decorator:

Img-38-3.jpg

The Decorator will act like a situation that must be met earlier than the Sequence can run, and as you possibly can see we’ve loads of choices to selected for the situation. We’re going to choose Blackboard situation:
 

Img-39-3.jpg

If you do this, you will note a blue Blackboard Based mostly Situation icon on the Sequence node:
 

Img-40-3.jpg

If you click on on the Blackboard Based mostly Situation within the Particulars tab you will note the Movement Management and Blackboard settings which is the place you set the circumstances for this Blackboard.

To make the AI transfer to the participant, we have to make it possible for the enemy can see the participant, which implies the Can See Participant worth must be set:

Img-41-3.jpg

For the Key Question within the Blackboard setting choose the Is Set, and for the Blackboard Key choose Can See Participant, which implies Can See Participant worth must be set to true for this situation to judge.

I’ve additionally set the Observer aborts to Each within the Movement Management setting, which implies that when the end result adjustments, which is about within the Notify Observer setting for the Movement Management, then the tree will abort this Sequence(node), all of its youngsters and any nodes to the suitable of this node(Sequence).

For the Sequence that makes the enemy patrol, we’re additionally going so as to add a Blackboard Decorator situation, and we’re going to set the next settings for it:

Img-42-3.jpg

The situation for this Decorator is when the Can See Participant worth isn’t set, which you’ll be able to see within the Blackboard setting. And within the Movement Management we set the Observer aborts to Self, which implies when the worth of Can See Participant adjustments, the tree will abort this Sequence(node) and all of its youngsters.
 
Let’s run the sport and try it out:
 

As quickly because the enemy sees the participant it begins shifting in the direction of him, and when it will get near the participant it stops shifting. You may choose the Transfer To node and within the Particulars tab change the Acceptable Radius to the next worth, this may make the enemy cease when the space to participant is the same as the worth that you simply set:

Img-43-3.jpg

We additionally noticed the execution circulate of the Conduct Tree when the enemy was chasing the participant and when the enemy was patrolling the extent.

You may all the time play with the AI settings for the PawnSensing part to make the enemy detect the participant when he’s far-off or when he’s shut and so forth.

Attacking The Participant

The final step is to make the enemy assault the participant. To make this work we have to create a brand new Process, identify it Task_Attack and open it within the editor.

Within the Task_Attack we’re going to override the Obtain Execute AI occasion:

Img-44-3.jpg

From the Obtain Execute AI occasion we’re going to get a reference to BP_Enemy_BT and play the assault montage animation:

Img-45-3.jpg

You may copy the nodes from right here:
 

The assault animation is already ready simply choose it from the drop down record for the Play Montage node:
 

Img-46-3.jpg

Identical as for the Task_GetRandomPointLocation, for the assault job we additionally must name End Execute operate to tell the tree that the duty has completed executing.

One factor that you’ll discover is that we’re calling the End Execute operate from the On Full and On Interrupted occasions for the Play Montage operate:

Img-47-2.jpg

The On Accomplished half is obvious, when the animation finishes enjoying, then we’ll name End Execute. As for the On Interrupted, it will likely be referred to as when the animation is interrupted in any approach and didn’t end enjoying.

The explanation why I’m utilizing it is because when the enemy tries to assault the participant, the participant can run away from the enemy, if that occurs I need the enemy to abort the assault and proceed chasing the participant.

Earlier than we will see that in motion, we have to name the Task_Attack within the Conduct Tree:

Img-48-2.jpg

With that node, that is the ultimate model of our Conduct Tree:

Img-49-2.jpg

Earlier than we will check this out, we have to do another factor. Open the BP_BB_EnemyAIController, and within the My Blueprint tab create a brand new variable and make it kind of BP_Enemy_BT:

Img-50-2.jpg

Within the BeginPlay after we begin the Conduct Tree, we’re going to get a reference to the BP_Enemy_BT:
 

Img-51-2.jpg

You may copy the nodes from right here:

Subsequent, within the On See Pawn occasion, after we name the Retriggerable Delay and the Set Can See Participant operate, we’re going to use the Enemy BT REF to cease the assault animation:
 

Img-52-2.jpg

You may copy the nodes from right here:

We already know when the Retriggerable Delay operate is known as meaning the enemy doesn’t see the participant, and when that occurs we’re additionally going to abort the assault animation as a result of the participant has escaped the enemy and we have to chase him once more.

After we abort the animation, this can even cease the Task_Attack as a result of we’re calling End Execute when the animation is interrupted in any approach:

Img-53-2.jpg

Let’s check the sport out and see the ultimate consequence:

Now when the enemy reaches the participant it assaults him, and when the participant escapes the enemy in the midst of the assault the enemy stops the assault and begins patrolling.

In fact, you possibly can add further logic to check if the participant is in a sure distance away from the enemy in order that the enemy will begin chasing him as an alternative of patrolling straight away when the participant isn’t within the enemy’s sight anymore which can make a extra real looking enemy AI.

C++ Enemy AI Controller

Allow us to now create the C++ model of our Conduct Tree which begins with creating AI controller class. Contained in the C++ Courses -> Enemy_AI folder, Proper Click on -> New C++ Class and make it possible for it inherits from AIController:

Img-53-2.jpg

Identify the category BTAIController and click on Create Class button. Earlier than we proceed to code the AI conduct, we have to add public dependency module names in order that we will use issues like duties, AI and navigation system in our code.

Open the Enemy_AI.Construct.cs file:

Img-54.jpg

Contained in the file, that is how your PublicDependencyModuleNames ought to appear to be:

				
					PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", 
			"Engine", "InputCore", "HeadMountedDisplay", 
			"GameplayTasks", "AIModule", "NavigationSystem" });
				
			

You may merely copy and paste this line of code as an alternative of the identical line you’ve gotten in your mission.

Now that we’ve that out of the way in which, contained in the BTAIController.h file, add the next traces of code:

				
					public:
	void BeginPlay() override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		class UBehaviorTree* BehaviorTree;
				
			

When you keep in mind, contained in the BP_BB_EnemyAIController we bought a reference to the Conduct Tree after which we run the Conduct Tree when the sport begins, we’re going to do the identical factor besides with C++.

That’s the reason we’ve the UBehaviorTree variable on line 5 within the code above. Now open BTAIController.cpp file and first we’re going to add consists of we’d like on the high of the file:

				
					#embody "BehaviorTree/BehaviorTree.h"
#embody "Notion/PawnSensingComponent.h"
#embody "BehaviorTree/BlackboardComponent.h"
#embody "Kismet/KismetSystemLibrary.h"
#embody "Parts/SkeletalMeshComponent.h"
#embody "GameFramework/Character.h"
#embody "Enemy_AICharacter.h"
				
			

As an alternative of going again and fort including new consists of at any time when we’d like them, I’m going so as to add all of the consists of we’ll want for our logic now.

Run the Conduct Tree, we solely must name one line of code which we’ll do within the BeginPlay operate:

				
					void ABTAIController::BeginPlay()
{
    Tremendous::BeginPlay();

    RunBehaviorTree(BehaviorTree);
}
				
			

Just be sure you compile the code by going underneath Construct -> Construct answer or urgent CTRL + SHIFT + B in Visible Studio, or urgent the Compile button in Unreal Engine editor.

C++ Conduct Tree

To run the Conduct Tree we have to create a Blueprint out of our BTAIController. Contained in the Content material -> Blueprints -> AI, Proper Click on -> Blueprint Class, make sure that it inherits from BTAIController and identify it BP_BB_EnemyAIController_CPP:

Img-55.jpg

Now open BP_Enemy_BT Blueprint situated in Content material -> Blueprints folder and within the Parts tab, choose the BP_Enemy_BT(self), then within the Particulars tab underneath Pawn settings set the AI Controller Class to the brand new BP_BB_EnemyAIController_CPP Blueprint that we simply created:

Img-56.jpg

Subsequent, we’re going to create a brand new Conduct Tree that we’re going to use with the C++ model of this tutorial. We aren’t going to create a C++ class for the Conduct Tree as a result of there isn’t any want to do this, as an alternative we’re going to create a brand new Conduct Tree by Proper Click on -> Synthetic Intelligence -> Conduct Tree:

Img-57.jpg

Identify the brand new Conduct Tree BT_EnemyAI_CPP after which open it within the editor. For the Blackboard we’re going to reuse the identical Blackboard we used within the first a part of this tutorial:

Img-58.jpg

I’m additionally going to reuse the random patrol logic that we created within the first instance:
 

Img-59.jpg

That is solely to check if our code for working the Conduct Tree works, after that we’ll create our personal random patrol logic utilizing C++.

Simply just be sure you choose the right Blackboard key for each GetRandomLocationPoint and Transfer To job which is Random Patrol Location.

Open BP_BB_EnemyAIController_CPP within the editor and within the Parts tab choose BP_BB_EnemyAIController_CPP(self), then within the Particulars tab for the Conduct Tree choose BT_EnemyAI_CPP:

Img-60.jpg

Compile and save the adjustments to the BP_BB_EnemyAIController_CPP Blueprint and now let’s run the sport to try it out:

Creating Conduct Duties With C++

Now that we see that our preliminary arrange is working, allow us to create our personal job utilizing C++ which goes to generate a random location level.

Contained in the C++ Courses -> Enemy_AI folder, Proper Click on -> New C++ Class. Within the pop up window seek for the BTTaskNode and inherit from it. Identify the brand new class Task_GetRandomLocation_CPP and create the category:

Img-61.jpg

Open the Task_GetRandomLocation_CPP.h file and add the next traces of code:

				
					non-public:

	class UNavigationSystemV1* NavArea;

	FVector RandomLocation;

	digital EBTNodeResult::Kind ExecuteTask(UBehaviorTreeComponent& OwnerComp,
		uint8* NodeMemory) override;
				
			

To generate a random location, we have to have a reference to the navigation system, that’s the reason we’d like the variable on line 3. The operate on line 7, is the override operate which can inform the duty that it must execute and it will likely be referred to as routinely by the Conduct Tree.

Now open the Task_GetRandomLocation_CPP.cpp file, and first we’re going to add all consists of we’d like:

				
					#embody "Kismet/GameplayStatics.h"
#embody "NavigationSystem.h"
#embody "BehaviorTree/BlackboardComponent.h"
				
			

And within the ExecuteTask operate we’re going to get a random location and inform the Blackboard part in regards to the random location we generated:
 

				
					EBTNodeResult::Kind UTask_GetRandomLocation_CPP::
	ExecuteTask(UBehaviorTreeComponent& OwnerComp, uint8* NodeMemory)
{
	NavArea = FNavigationSystem::
		GetCurrent(UGameplayStatics::GetPlayerPawn(GetWorld(), 0));

	if (NavArea)
	{
		NavArea->K2_GetRandomReachablePointInRadius(GetWorld(),
			GetWorld()->GetFirstPlayerController()->GetPawn()->GetActorLocation(),
			RandomLocation, 15000.0f);
	}
	else
	{
		return EBTNodeResult::Failed;
	}

	// inform blackboard about random location end result
	OwnerComp.GetBlackboardComponent()
		->SetValueAsVector(FName("Random Patrol Location"), RandomLocation);

	return EBTNodeResult::Succeeded;
}
				
			

First we get a reference to the navigation system on line 4. Then we use the navigation system to generate a random location within the radius of 15000 items from the participant pawn on line 9.
 
What’s necessary to notice is that we have to return the end result consequence for the ExecuteTask operate. That’s the reason we’re testing if we’ve a reference to the navigation system on line 7, and if we don’t have a reference to it we’ll return Failed as the duty consequence on line 15.
 
But when we’ve a reference then we’ll generate a random location, then we’ll inform the Blackboard part in regards to the random location we generated on line 19, and lastly we’ll return Succeeded as the duty consequence on line 22.
 
Not that we’re calling SetValueAsVector and we move the identify of the Blackboard Key parameter utilizing FName. That is one thing that we have to specify in order that the Blackboard part will know which worth to set.
 
Now we will open BT_EnemyAI_CPP within the editor, and use our customized job:
 

Img-62.jpg

It will change the duty node we created utilizing Blueprints and it’ll use the C++ job node we simply created.

Let’s run the sport and try it out:

We is not going to discover any distinction within the conduct of the enemy compared to the earlier instance, however now we see that the Conduct Tree is utilizing the duty node we created through C++ as an alternative of the Blueprint one.
 

Creating PawnSensing Part With C++

The subsequent step is to sense or detect the participant actor within the sport and we’re going to do this with the assistance of PawnSensing part.
 
Open BTAIController.h file and add the next traces under the UBehaviorTree variable declaration:
 

				
					ABTAIController();

	UPROPERTY(EditAnywhere)
	class UPawnSensingComponent* PawnSensing;

	UFUNCTION()
		void OnSeePawn(APawn* PlayerPawn);

	UFUNCTION()
	void SetCanSeePlayer(bool SeePlayer, class UObject* Participant);

	FTimerHandle RetriggerableTimerHandle;
	FTimerDelegate FunctionDelegate;
	void RunRetriggerableTimer();
				
			

Now open BTAIController.cpp file and contained in the constructor we’re going to create the PawnSensing part:

				
					ABTAIController::ABTAIController()
{
    PawnSensing = CreateDefaultSubobject(TEXT("PawnSensing"));   
}
				
			

Contained in the BeginPlay we’re going to bind the OnSeePawn operate to the OnSeePawn occasion of the PawnSensing part:
 

				
					void ABTAIController::BeginPlay()
{
    Tremendous::BeginPlay();

    PawnSensing->OnSeePawn.AddDynamic(this, &ABTAIController::OnSeePawn);

    RunBehaviorTree(BehaviorTree);
}
				
			

Contained in the OnSeePawn operate we’re going to check if the pawn that the PawnSensing part sees is the participant, if that’s the case we’ll inform the Conduct Tree that we see the participant and we’ll move the participant’s reference to the Conduct Tree:

				
					void ABTAIController::OnSeePawn(APawn* PlayerPawn)
{
    AEnemy_AICharacter* Participant = Solid(PlayerPawn);

    if (Participant)
    {
        SetCanSeePlayer(true, Participant);
        RunRetriggerableTimer();
    }
}
				
			

The SetCanSeePlayer operate accommodates the code that can inform the Conduct Tree, or higher but, the Blackboard part, that the enemy sees the participant:
 

				
					void ABTAIController::SetCanSeePlayer(bool SeePlayer, UObject* Participant)
{
    if (SeePlayer)
    {
        GetBlackboardComponent()
            ->SetValueAsBool(FName("Can See Participant"), SeePlayer);

        GetBlackboardComponent()
            ->SetValueAsObject(FName("Participant Goal"), Participant);
    }
    else
    {
        GetBlackboardComponent()
            ->SetValueAsBool(FName("Can See Participant"), SeePlayer);

        ACharacter* EnemyChar = Solid(GetPawn());
        EnemyChar->GetMesh()->GetAnimInstance()->StopAllMontages(0);
    }
}
				
			

When the SeePlayer parameter is true, we’ll move that parameter, or the worth of that parameter to the Blackboard part utilizing FName(“Can See Participant”) which refers back to the similar Blackboard key contained in the Blackboard part.
 
We do the identical factor with FName(“Participant Goal”) once we move a reference to the participant pawn.
 
When you keep in mind within the Conduct Tree Blueprint model, we’re utilizing Can See Participant because the parameter for the Blackboard decorator, which servers because the situation for the Sequence, and we use the Participant Goal because the parameter for the Transfer To node which can make the enemy transfer in the direction of the participant pawn:
 

Img-63.jpg

Within the code instance above, we’re doing the identical factor, besides utilizing C++.

And when the SeePlayer parameter is fake, then we solely move that worth to the Blackboard part with out the participant pawn, as a result of if the enemy can’t see the participant, it is not going to run in the direction of him and it’ll not assault him, thus, we don’t must move participant pawn to the Blackboard part.

We additionally must cease the enemy from attacking the participant if the assault is at present underneath approach, and we do this on traces 16 and 17 within the code instance above.

First we get a reference to the enemy actor, then we cease his montage animations which are at present enjoying by calling StopAllMontages(0) similar as what we did with the Blueprint model of the Conduct Tree.

The 0 parameter within the StopAllMontages capabilities will make the enemy animation Blueprint cease the assault animation and it’ll play one other animation based mostly on the situation we set for the animations.

The explanation why I’m mentioning that is for those who set 1 because the parameter, then the enemy will end the assault animation after which play different animations which isn’t the conduct we wish.

Lastly, we have to code the RunRetriggeranbleTimer operate, so add the next traces of code:

				
					void ABTAIController::RunRetriggerableTimer()
{
    GetWorld()->GetTimerManager().ClearTimer(RetriggerableTimerHandle);

    FunctionDelegate.BindUFunction(this, FName("SetCanSeePlayer"),
        false, GetPawn());

    GetWorld()->GetTimerManager().SetTimer(RetriggerableTimerHandle,
        FunctionDelegate, PawnSensing->SensingInterval * 2.0f, false);
}
				
			

Contained in the OnSeePawn operate we’re calling the RunRetriggerableTimer operate. With this operate we’re constructing the identical arrange we created in BP_BB_EnemyAIController Blueprint model:
 

Img-64.jpg

Basically, each time we name the RunRetriggeranbleTimer is known as, it is going to reset its countdown which we’re doing on line 3 within the code above. Then it is going to use the FunctionDelegate variable and its BindUFunction to move the SetCanSeePlayer operate and the 2 parameters.
 
Since we’re passing false because the parameter which means the enemy can’t see the participant, I’m utilizing GetPawn operate because the second parameter.
 
Then we name the timer supervisor to set the timer. We’re utilizing SensingInterval * 2 because the parameter for the wait time, as a result of we’re wait twice as lengthy it takes the PawnSensing part to refresh itself, which implies if the PawnSensing part doesn’t see the participant after SensingInterval / 2 seconds, then the timer will execute.
 
Earlier than we proceed, I’m going to go away the BTAIController.h and .cpp file under as a reference, in case you need to copy paste the code or examine it to your individual.
 
BTAIController.h:
 

				
					#embody "CoreMinimal.h"
#embody "AIController.h"
#embody "BTAIController.generated.h"

/**
 * 
 */
UCLASS()
class ENEMY_AI_API ABTAIController : public AAIController
{
	GENERATED_BODY()

public:
	void BeginPlay() override;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		class UBehaviorTree* BehaviorTree;
	
	ABTAIController();

	UPROPERTY(EditAnywhere)
		class UPawnSensingComponent* PawnSensing;

	UFUNCTION()
		void OnSeePawn(APawn* PlayerPawn);

	UFUNCTION()
		void SetCanSeePlayer(bool SeePlayer, class UObject* Participant);

	FTimerHandle RetriggerableTimerHandle;
	FTimerDelegate FunctionDelegate;
	void RunRetriggerableTimer();

};
				
			

BTAIController.cpp:

				
					#embody "BTAIController.h"

#embody "BehaviorTree/BehaviorTree.h"
#embody "Notion/PawnSensingComponent.h"
#embody "BehaviorTree/BlackboardComponent.h"
#embody "Kismet/KismetSystemLibrary.h"
#embody "Parts/SkeletalMeshComponent.h"
#embody "GameFramework/Character.h"
#embody "Enemy_AICharacter.h"

ABTAIController::ABTAIController()
{
    PawnSensing = CreateDefaultSubobject(TEXT("PawnSensing"));
}


void ABTAIController::BeginPlay()
{
    Tremendous::BeginPlay();

    PawnSensing->OnSeePawn.AddDynamic(this, &ABTAIController::OnSeePawn);

    RunBehaviorTree(BehaviorTree);
}

void ABTAIController::OnSeePawn(APawn* PlayerPawn)
{
    AEnemy_AICharacter* Participant = Solid(PlayerPawn);

    if (Participant)
    {
        SetCanSeePlayer(true, Participant);
        RunRetriggerableTimer();
    }
}

void ABTAIController::SetCanSeePlayer(bool SeePlayer, UObject* Participant)
{
    if (SeePlayer)
    {
        GetBlackboardComponent()
            ->SetValueAsBool(FName("Can See Participant"), SeePlayer);

        GetBlackboardComponent()
            ->SetValueAsObject(FName("Participant Goal"), Participant);
    }
    else
    {
        GetBlackboardComponent()
            ->SetValueAsBool(FName("Can See Participant"), SeePlayer);

        ACharacter* EnemyChar = Solid(GetPawn());
        EnemyChar->GetMesh()->GetAnimInstance()->StopAllMontages(0);
    }
}

void ABTAIController::RunRetriggerableTimer()
{
    GetWorld()->GetTimerManager().ClearTimer(RetriggerableTimerHandle);

    FunctionDelegate.BindUFunction(this, FName("SetCanSeePlayer"),
        false, GetPawn());

    GetWorld()->GetTimerManager().SetTimer(RetriggerableTimerHandle,
        FunctionDelegate, PawnSensing->SensingInterval * 2.0f, false);
}
				
			

Just be sure you compile the code after which open BP_BB_EnemyAIController_CPP within the editor. You will notice the Pawn Sensing part underneath the Parts tab, choose it and within the Particulars tab change the Sensing Inverval worth to 0.2 and for the Peripheral Imaginative and prescient Angle set the worth 60:

Img-65.jpg

We already defined what these choices imply once we edited the Pawn Sensing part within the Blueprint instance.

Now open the BT_EnemyAI_CPP within the editor, and the final setup is just about the identical because the one we had within the Blueprint model:

Img-66.jpg

On the left aspect we’ve a Sequence node that can make the enemy transfer in the direction of the participant and assault him. The sequence has a Decorator which has the Can See Participant because the situation with the Key Question Is Set, and it aborts each nodes when the end result adjustments:

Img-67.jpg

We already examined the Sequence node on the suitable which makes the enemy patrol, the one factor that modified is that we added a Decorator which additionally has the Can See Participant because the situation with Key Question Is Not Set:

Img-68.jpg

One factor that you’ll discover is that I’ve reused the Task_Attack node we created through Blueprints. The explanation why I didn’t create an assault job with C++ is, it’s sophisticated to get all of the references we’d like such because the enemy and make him assault and so forth, it’s a lot simpler to do that with Blueprints that’s the reason I reused that node.

And apart from, Unreal Engine is all about combining Blueprints and C++, and a variety of video games are created purely in Blueprints so throw that Blueprints usually are not optimized mentality out of the window.

The very last thing that’s left for us to do is to check the sport and see the result:

[ad_2]

LEAVE A REPLY

Please enter your comment!
Please enter your name here