{"id":3160,"date":"2021-01-02T19:14:33","date_gmt":"2021-01-02T11:14:33","guid":{"rendered":"http:\/\/blog.coolcoding.cn\/?p=3160"},"modified":"2021-01-02T19:40:34","modified_gmt":"2021-01-02T11:40:34","slug":"ai-for-controlling-npcs","status":"publish","type":"post","link":"https:\/\/blog.coolcoding.cn\/?p=3160","title":{"rendered":"AI for Controlling NPCs"},"content":{"rendered":"\n<p>In this chapter, we will cover the following recipes:<\/p>\n\n\n\n<ul><li>Implementing a simple\u00a0following behavior<\/li><li>Laying down a Navigation Mesh<\/li><li>Creating a Blackboard<\/li><li>Creating a Behavior Tree<\/li><li>Connecting a Behavior Tree to a Character<\/li><li>Creating a BTService<\/li><li>Creating a BTTask<\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Introduction<\/h1>\n\n\n\n<p>AI includes many aspects of a game&#8217;s NPC, as well as player behavior. The general topic of AI includes pathfinding and NPC behavior. Generally, we term the selection of what the NPC does for a period of time within the game as behavior.<\/p>\n\n\n\n<p>AI in UE4 is well supported. A number of constructs exist to allow basic AI programming from within the editor, but we will be focusing on using C++ to program elements while touching on engine aspects when needed.<\/p>\n\n\n\n<p>To make it easier to visualize our AI character and the interactions with the player, in this chapter, I will be using the&nbsp;C++ Third Person&nbsp;template:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/0293a11c-8c73-4598-b464-097efdc453a5.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>While I would love to cover all aspects of working with AI in Unreal Engine 4, that could take a whole book of its own. If you are interested in exploring AI even more after reading this chapter, I suggest that you check out\u00a0<em>Unreal Engine 4 AI Programming Essentials<\/em>, also available from Packt Publishing.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Technical requirements<\/h1>\n\n\n\n<p>This chapter requires the use of Unreal Engine 4 and uses Visual Studio 2017 as the IDE. Instructions on how to install both pieces of software and the requirements for them can be found in&nbsp;<a href=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/4adb307e-d86f-4d70-b6de-a0893102d1cf.xhtml\">Chapter 1<\/a>,&nbsp;<em>UE4 Development Tools<\/em>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Implementing a simple following behavior<\/h1>\n\n\n\n<p>The most simple way to implement any kind of AI is to just write it out by hand. This allows you to get something up-and-running&nbsp;quickly, but lacks the elegance and finesse that using Unreal&#8217;s built-in systems gives us. This recipe gives us a super-simple implementation of making an object follow another one.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Have a UE4 project ready with a simple landscape or set of geometry on the ground,&nbsp;ideally with a&nbsp;<em>cul-de-sac<\/em>&nbsp;somewhere in the geometry to test AI movement functions. The&nbsp;ThirdPersonExampleMap&nbsp;that comes with the&nbsp;C++ Third Person&nbsp;template should work just fine.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>Create a new C++ class that derives from&nbsp;Character&nbsp;by going to&nbsp;Add New | New C++ Class. Under the&nbsp;Add C++ Class&nbsp;menu, select&nbsp;Character&nbsp;and hit the&nbsp;Next&nbsp;button:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/39d55e09-2d74-4208-a316-e58723a542d9.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>From the next screen,&nbsp;Name&nbsp;the class&nbsp;FollowingCharacter&nbsp;and click on the&nbsp;Create Class&nbsp;button:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/597248e0-ee12-459f-9588-84457a32324a.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>From the&nbsp;FollowingCharacter.cpp&nbsp;file, update the&nbsp;Tick&nbsp;function to the following:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">void AFollowingCharacter::Tick(float DeltaTime)<br>{<br>    Super::Tick(DeltaTime);<br><br><strong>    \/\/ Get current location<\/strong><br><strong>    auto startPos = GetActorLocation();<\/strong><br><br><strong>    \/\/ Get player's location<\/strong><br><strong>    FVector playerPos = GetWorld()-&gt;GetFirstPlayerController()-&gt;GetPawn()-&gt;GetActorLocation();<\/strong><br><br><strong>    \/\/ Get the direction to move in<\/strong><br><strong>    FVector direction = playerPos - startPos;<\/strong><br><strong>    direction.Normalize();<\/strong><br><br><strong>    \/\/ Move the player in that direction<\/strong><br><strong>    SetActorLocation(startPos + direction);<\/strong><br>}<\/pre>\n\n\n\n<p>The&nbsp;auto&nbsp;keyword can be used for variable declarations if the compiler can deduce what the type of an object is from the assignment given to it.<\/p>\n\n\n\n<ol><li>Save your script and compile your code.<\/li><li>Drag and drop the&nbsp;Following Character&nbsp;into your scene. There is currently no visualization of the character, so go ahead and select the object. Then, from the&nbsp;Details&nbsp;tab, click the&nbsp;Add Component&nbsp;button. From there, select the&nbsp;Cylinder&nbsp;shape:&nbsp;<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/c8d54ec0-bd6d-4269-8951-2fcc86cf0489.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>If all goes well, you should see the object on the screen.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/eaec7727-a31c-429c-a0c9-d53b6b24b012.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The Following Character with a Cylinder shape added<\/p>\n\n\n\n<ol><li>Run the game and move around. You should notice that the cylinder will follow the player, no matter where they go!<\/li><\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>In this example, we are effectively&nbsp;<em>hard-coding<\/em>&nbsp;this enemy to follow the player character by doing simple vector math ourselves. While this technically works, it doesn&#8217;t make use of Unreal&#8217;s built-in AI functionality. It will also stop the AI at walls since there is no actual path-finding going on, and it will break the player character if you let the AI catch up. The player won&#8217;t be able to move anymore due to collisions.<\/p>\n\n\n\n<p>The rest of this chapter will be working with Unreal&#8217;s actual built-in systems, which create a much more robust implementation.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Laying down a Navigation Mesh<\/h1>\n\n\n\n<p>A Navigation Mesh (also known as a&nbsp;<strong>Nav Mesh<\/strong>) is basically a definition of areas that an AI-controlled unit considers passable (that is, areas that the &#8220;AI-controlled&#8221; unit is allowed to move into or across). A Nav Mesh does not include geometry that would block the player if the player tried to move through it.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Constructing a Nav Mesh based on your scene&#8217;s geometry is fairly easy in UE4. Start with a project that has some obstacles around it, or one that uses terrain. The&nbsp;ThirdPersonExampleMap&nbsp;included with&nbsp;the&nbsp;C++ Third Person&nbsp;template works well for this purpose.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<p>To construct your Nav Mesh, simply perform the following steps:<\/p>\n\n\n\n<ol><li>Go to&nbsp;Modes&nbsp;|&nbsp;Volumes.<\/li><li>Drag the&nbsp;Nav Mesh Bounds Volume&nbsp;option&nbsp;onto your viewport.<\/li><li>Use the&nbsp;Scale&nbsp;tool to increase the size of the Nav Mesh so that it covers the area the actors that use the Nav Mesh should be allowed to navigate and pathfind in.&nbsp;To toggle the visibility of the completed Nav Mesh, press the&nbsp;<em>P<\/em>&nbsp;key:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/9b025c53-495a-412d-91e5-ae9c9e6b5b92.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>A Nav Mesh drawn within the bounds of the Nav Mesh Bounds Volume\n\n<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>A Nav Mesh doesn&#8217;t block the player pawn (or other entities) from stepping on a certain geometry, but it serves to guide AI-controlled entities as to where they can and cannot go.<\/p>\n\n\n\n<p>For more information on scaling objects in UE4, check out the following link:&nbsp;<a href=\"https:\/\/docs.unrealengine.com\/en-us\/Engine\/Actors\/Transform\">https:\/\/docs.unrealengine.com\/en-us\/Engine\/Actors\/Transform<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Creating a Blackboard<\/h1>\n\n\n\n<p>A&nbsp;<strong>Blackboard<\/strong>&nbsp;is a container for variables that are often used with Behavior Trees. This data is used for decision-making purposes, either by a single AI or a whole group of others. We will be creating a Blackboard here that we will then use in future recipes.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>From the&nbsp;Content Browser&nbsp;under the&nbsp;Content&nbsp;folder, select&nbsp;Add New | Artificial Intelligence | Blackboard:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/ab959cad-1fb0-4c9f-9d53-5425a5ed955c.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>When asked for a name, provide&nbsp;EnemyBlackboard. Double-click on the file to open the Blackboard Editor.<\/li><li>From the Blackboard tab, click&nbsp;New Key | Object:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/bf12d03b-7d23-4239-bdb8-8f1bdc718b8a.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>When asked for the name of the object, insert&nbsp;Target. Then, open the&nbsp;Key Type&nbsp;property by clicking the arrow to the left of the name and set the&nbsp;Base Class&nbsp;property to&nbsp;Actor:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/bf4829a3-3d30-4687-a757-43229a9bed7c.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Add any other properties you wish to have access to and then click on the&nbsp;Save&nbsp;button.<\/li><\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>In this recipe, we created a blackboard that we will later use in code to set and get the value of the player that we will use in our behavior tree.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Creating a Behavior Tree<\/h1>\n\n\n\n<p>If a Blackboard is the shared memory of an AI, the Behavior Tree is the AI&#8217;s processor, which will contain the logic of the AI. It makes decisions, and then acts on those decisions to enable an AI to actually do something when the game is running. In this recipe, we will create a Behavior Tree and then assign its Blackboard.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>From the&nbsp;Content Browser&nbsp;under the&nbsp;Content&nbsp;folder, select&nbsp;Add New | Artificial Intelligence | Behavior Tree:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/144f462c-a25f-4e5f-9243-507ee517881a.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>When asked for a name, provide&nbsp;EnemyBehaviorTree. Double-click on the file to open the Behavior Tree Editor.<\/li><li>Once opened, under the&nbsp;Details&nbsp;tab, open the&nbsp;AI | Behavior Tree&nbsp;section and verify that the&nbsp;Blackboard Asset&nbsp;property is set to&nbsp;EnemyBlackboard. You should notice the&nbsp;Target&nbsp;property we created listed under&nbsp;Keys. If not, close the editor and open it again:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/40020a2c-e30b-4f4b-b880-8c227ee889d0.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>A view of the Behavior Tree Editor<\/p>\n\n\n\n<ol><li>Once finished, click on the&nbsp;Save&nbsp;button.<\/li><\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>In this recipe, we created a Behavior Tree, which is required by the AI system so that it can fulfill tasks and other assorted features. In future recipes, we will use this to create our own custom Character classes.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Connecting a Behavior Tree to a Character<\/h1>\n\n\n\n<p>A&nbsp;BehaviorTree&nbsp;chooses a behavior to be exhibited by an AI-controlled unit at any given moment. Behavior Trees are relatively simple to construct, but there is a lot of setting up to do to get one running. You also have to be familiar with the components that are available for constructing your&nbsp;<strong>Behavior Tree<\/strong>&nbsp;to do so effectively.<\/p>\n\n\n\n<p>A Behavior Tree is extremely useful for defining NPC behavior that is more varied than simply moving toward an opponent (as shown in the previous recipe with&nbsp;AIMoveTo).<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready<\/h1>\n\n\n\n<p>Before starting this recipe, verify that you have completed the following recipes:<\/p>\n\n\n\n<ul><li><em>Laying down a Navigation Mesh<\/em><\/li><li><em>Creating a Blackboard<\/em><\/li><li><em>Creating a Behavior Tree<\/em><\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>Open up your&nbsp;.Build.cs&nbsp;file (in our case,&nbsp;Chapter_13.Build.cs) and add the following dependencies:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">using UnrealBuildTool;<br><br>public class Chapter_13 : ModuleRules<br>{<br>  public Chapter_13(ReadOnlyTargetRules Target) : base(Target)<br>  {<br>    PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;<br><br>    PublicDependencyModuleNames.AddRange(new string[] { \"Core\", \"CoreUObject\", \"Engine\", \"InputCore\", \"HeadMountedDisplay\" });<br>        <strong>PublicDependencyModuleNames.AddRange(new string[] { \"AIModule\", \"GameplayTasks\" });<\/strong><br><br>    }<br>}<\/pre>\n\n\n\n<ol><li>Compile your code.&nbsp;<\/li><li>From the&nbsp;Content Browser, select&nbsp;Add New | New C++ Class. At the&nbsp;Add C++ Class&nbsp;menu, check the&nbsp;Show All Classes&nbsp;option type in&nbsp;AIController, and then select the&nbsp;AIController&nbsp;class. Then, click on&nbsp;Next:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/4db220e7-1fa7-48a1-9f27-d230b88354d4.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>When asked for a name for the class, name it&nbsp;EnemyAIController&nbsp;and click on the&nbsp;Create Class&nbsp;button.<\/li><li>Open up Visual Studio and update the&nbsp;EnemyAIController.h&nbsp;file to the following:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"AIController.h\"<br><strong>#include \"BehaviorTree\/BehaviorTreeComponent.h\"<br>#include \"BehaviorTree\/BlackboardComponent.h\"<\/strong><br>#include \"EnemyAIController.generated.h\"<br><br>\/**<br> * <br> *\/<br>UCLASS()<br>class CHAPTER_13_API AEnemyAIController : public AAIController<br>{<br>    GENERATED_BODY()<br>    <br><strong>private:<\/strong><br><strong>    \/\/ AI Component references<\/strong><br><strong>    UBehaviorTreeComponent* BehaviorComp;<\/strong><br><strong>    UBlackboardComponent* BlackboardComp;<\/strong><br><br><strong>public:<\/strong><br><strong>    AEnemyAIController();<\/strong><br><br><strong>    \/\/ Called when the controller possesses a Pawn\/Character<\/strong><br><strong>    virtual void Possess(APawn* InPawn) override;<br><br>    FBlackboard::FKey TargetKeyID;<\/strong><br><br>};<br><br><\/pre>\n\n\n\n<ol><li>After creating the function declarations, we need to define them in the&nbsp;EnemyAIController.cpp&nbsp;file:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"EnemyAIController.h\"<br><br>AEnemyAIController::AEnemyAIController()<br>{<br>    \/\/Initialize components<br>    BehaviorComp = CreateDefaultSubobject&lt;UBehaviorTreeComponent&gt;(TEXT(\"BehaviorComp\"));<br>    BlackboardComp = CreateDefaultSubobject&lt;UBlackboardComponent&gt;(TEXT(\"BlackboardComp\"));<br>}<br><br>\/\/ Called when the controller possesses a Pawn\/Character<br>void AEnemyAIController::Possess(APawn* InPawn)<br>{<br>    Super::Possess(InPawn);<br>}<\/pre>\n\n\n\n<p>In addition to an AI Controller, we also need to have a Character.&nbsp;<\/p>\n\n\n\n<ol><li>Create a new C++ class that derives from&nbsp;Character&nbsp;by going to&nbsp;Add New | New C++ Class. Under the&nbsp;Add C++ Class&nbsp;menu, select&nbsp;Character&nbsp;and hit the&nbsp;Next&nbsp;button:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/9f10b90b-8e30-4d27-9752-a97c1c011ad5.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>From the next screen,&nbsp;Name&nbsp;the class&nbsp;EnemyCharacter&nbsp;and click on the&nbsp;Create Class&nbsp;button.<\/li><li>Open Visual Studio. Under the&nbsp;EnemyCharacter.h&nbsp;file, add the following property:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"GameFramework\/Character.h\"<br>#include \"EnemyCharacter.generated.h\"<br><br>UCLASS()<br>class CHAPTER_13_API AEnemyCharacter : public ACharacter<br>{<br>    GENERATED_BODY()<br><br>public:<br>    \/\/ Sets default values for this character's properties<br>    AEnemyCharacter();<br><br><strong>    UPROPERTY(EditAnywhere, Category = Behavior)<\/strong><br><strong>    class UBehaviorTree *EnemyBehaviorTree;<\/strong><br><br>protected:<br>    \/\/ Called when the game starts or when spawned<br>    virtual void BeginPlay() override;<br><br>public: <br>    \/\/ Called every frame<br>    virtual void Tick(float DeltaTime) override;<br><br>    \/\/ Called to bind functionality to input<br>    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;<br><br>};<\/pre>\n\n\n\n<ol><li>Then, we can go back into the&nbsp;EnemyAIController.cpp&nbsp;file and update the&nbsp;Possess&nbsp;function since our Character class exists:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"EnemyAIController.h\"<br><strong>#include \"EnemyCharacter.h\"<\/strong><br><strong>#include \"BehaviorTree\/BehaviorTree.h\"<\/strong><br><br><br>AEnemyAIController::AEnemyAIController()<br>{<br>    \/\/ Initialize components<br>    BehaviorComp = CreateDefaultSubobject&lt;UBehaviorTreeComponent&gt;(TEXT(\"BehaviorComp\"));<br>    BlackboardComp = CreateDefaultSubobject&lt;UBlackboardComponent&gt;(TEXT(\"BlackboardComp\"));<br>}<br><br>\/\/ Called when the controller possesses a Pawn\/Character<br>void AEnemyAIController::Possess(APawn* InPawn)<br>{<br>    Super::Possess(InPawn);<br><br><strong>    \/\/ Convert InPawn to EnemyCharacter<\/strong><br><strong>    auto Character = Cast&lt;AEnemyCharacter&gt;(InPawn);<\/strong><br><br><strong>    \/\/ Check if pointers are valid<\/strong><br><strong>    if(Character &amp;&amp; Character-&gt;EnemyBehaviorTree)<\/strong><br><strong>    {<\/strong><br><strong>        BlackboardComp-&gt;InitializeBlackboard(*Character-&gt;EnemyBehaviorTree-&gt;BlackboardAsset);<\/strong><br><br><strong>        TargetKeyID = BlackboardComp-&gt;GetKeyID(\"Target\");<\/strong><br><br><strong>        BehaviorComp-&gt;StartTree(*Character-&gt;EnemyBehaviorTree);<\/strong><br><strong>    }<\/strong><br>}<\/pre>\n\n\n\n<ol><li>Save your scripts and compile your code.<\/li><\/ol>\n\n\n\n<p>Now, we will create a Blueprint version of the two classes we just created and assign our variables.<\/p>\n\n\n\n<ol><li>From the&nbsp;Content Browser&nbsp;under the&nbsp;C++ Classes\/Chapter_13&nbsp;folder, right-click on the&nbsp;EnemyAIController&nbsp;object and select the&nbsp;Create Blueprint class based on EnemyAIController&nbsp;option. Give it a name and click on the&nbsp;Create Blueprint Class&nbsp;button.<\/li><li>Likewise, do the same thing for the&nbsp;EnemyCharacter&nbsp;object.<\/li><li>Double-click on your&nbsp;MyEnemyCharacter&nbsp;Blueprint and, under the&nbsp;Details&nbsp;tab, set the&nbsp;Enemy Behavior Tree&nbsp;property to&nbsp;EnemyBehaviorTree. Then, set the&nbsp;AI Controller&nbsp;Class&nbsp;property to&nbsp;MyEnemyAIController:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/553deaf5-094e-49be-850d-047a325d2958.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Assigning the Enemy Behavior Tree and AI Controller Class properties<\/p>\n\n\n\n<ol><li>You&#8217;ll likely want a visual component for the character as well, so from the&nbsp;Components&nbsp;tab, click on the&nbsp;Add Component&nbsp;button and select&nbsp;Cube. Afterward, modify the&nbsp;Scale&nbsp;to (0.5, 0.5, 1.5).&nbsp;<\/li><\/ol>\n\n\n\n<p>As we discussed previously, you may need to click on the&nbsp;Open Full Blueprint Editor&nbsp;text to see all of the available options.<\/p>\n\n\n\n<p>16. Then, hit&nbsp;Compile&nbsp;and save all of your assets:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/ea359363-aa31-4d0b-b7d0-c8d67aab84e7.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>The completed enemy character<\/p>\n\n\n\n<p>And with that, we&#8217;ve set up a connection between an AI Character, an AI Controller, and a Behavior Tree!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>The AI Controller class we created will add both the Behavior Tree and the Blackboard that we created in the previous two recipes.&nbsp;<\/p>\n\n\n\n<p>A Behavior Tree is connected to an AI Controller, which in turn is connected to a Character. We will control the behavior of&nbsp;Character&nbsp;through the Behavior Tree by entering Task and Service nodes in the diagram.<\/p>\n\n\n\n<p>A Behavior Tree hosts six different types of node, as follows:<\/p>\n\n\n\n<ol><li><strong>Task<\/strong>: Task nodes are the purple nodes in the Behavior Tree that contain Blueprint code to run. It&#8217;s something that the AI-controlled unit has to do (code-wise). Tasks must return either&nbsp;true&nbsp;or&nbsp;false, depending on whether the task succeeded or not (by providing a&nbsp;FinishExecution()&nbsp;node at the end).<\/li><li><strong>Decorator<\/strong>: A decorator is just a Boolean condition for the execution of a node.&nbsp;It checks a condition, and is typically used within a Selector or Sequence block.<\/li><li><strong>Service<\/strong>: This runs some Blueprint code when it ticks. The tick interval for these nodes is adjustable (it can run slower than a per-frame tick, for example, every 10 seconds). You can use these to query the scene for updates, a new opponent to chase, and so on. The Blackboard can be used to store queried information. Service nodes do not have a&nbsp;FinishExecute()&nbsp;call at the end of them.<\/li><li><strong>Selector<\/strong>: This runs all subtrees from left to right until it encounters a success. When it encounters a success, the execution goes back up the tree.<\/li><li><strong>Sequence<\/strong>: This runs all subtrees from left to right until it encounters a failure. When a failure is encountered, the execution goes back up the tree.<\/li><li><strong>Simple Parallel<\/strong>: This runs a single task (purple) in parallel with a subtree (gray).<\/li><\/ol>\n\n\n\n<h1 class=\"wp-block-heading\">Creating a BTService<\/h1>\n\n\n\n<p>Services attach to nodes in Behavior Trees and will execute at their defined frequency; that is, as long as their branch is being executed. Similar to&nbsp;Parallel nodes in other Behavior Tree systems, these are often used to make checks and to update the Blackboard, which we will use in this recipe to find our player object and assign it to our Blackboard.&nbsp;<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready&#8230;<\/h1>\n\n\n\n<p>Finish the previous recipe,&nbsp;<em>Connecting a Behavior Tree to a Character<\/em>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>From the Content Browser, select&nbsp;Add New | New C++ Class. From the&nbsp;Choose Parent Class&nbsp;menu, check the&nbsp;Show All Classes&nbsp;option and look for the&nbsp;BTService&nbsp;class. Select it and then hit the&nbsp;Next&nbsp;button:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/0a41289d-bab4-4f68-a540-4f354a5e08a8.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>At the next menu, set its name to&nbsp;BTService_FindPlayer&nbsp;and then click on the&nbsp;Create Class&nbsp;option.<\/li><li>From the&nbsp;BTService_FindPlayer.h&nbsp;file, use the following code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"BehaviorTree\/BTService.h\"<br><strong>#include \"BehaviorTree\/BehaviorTreeComponent.h\"<\/strong><br>#include \"BTService_FindPlayer.generated.h\"<br><br>\/**<br> * <br> *\/<br>UCLASS()<br>class CHAPTER_13_API UBTService_FindPlayer : public UBTService<br>{<br>    GENERATED_BODY()<br><br><strong>public:<\/strong><br><strong>    UBTService_FindPlayer();<\/strong><br><br><strong>    \/** update next tick interval<\/strong><br><strong>    * this function should be considered as const (don't modify state of object) if node is not instanced! *\/<\/strong><br><strong>    virtual void TickNode(UBehaviorTreeComponent&amp; OwnerComp, uint8* NodeMemory, float DeltaSeconds) override;<\/strong><br><br>};<\/pre>\n\n\n\n<ol><li>From the&nbsp;BTService_FindPlayer.cpp&nbsp;file, use the following code:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"BTService_FindPlayer.h\"<br>#include \"EnemyAIController.h\"<br>#include \"BehaviorTree\/Blackboard\/BlackboardKeyType_Object.h\"<br><br>UBTService_FindPlayer::UBTService_FindPlayer()<br>{<br>    bCreateNodeInstance = true;<br>}<br><br>void UBTService_FindPlayer::TickNode(UBehaviorTreeComponent&amp; OwnerComp, uint8* NodeMemory, float DeltaSeconds)<br>{<br>    Super::TickNode(OwnerComp, NodeMemory, DeltaSeconds);<br><br>    auto EnemyAIController = Cast&lt;AEnemyAIController&gt;(OwnerComp.GetAIOwner());<br><br>    if(EnemyAIController)<br>    {<br>        auto PlayerPawn = GetWorld()-&gt;GetFirstPlayerController()-&gt;GetPawn();<br>        OwnerComp.GetBlackboardComponent()-&gt;SetValue&lt;UBlackboardKeyType_Object&gt;(EnemyAIController-&gt;TargetKeyID, PlayerPawn);<br>        UE_LOG(LogTemp, Warning, TEXT(\"Target has been set!\"));<br><br>    }<br><br>}<\/pre>\n\n\n\n<ol><li>Save your scripts and compile them.<\/li><\/ol>\n\n\n\n<ol><li>In the&nbsp;Content Browser, go to the&nbsp;Content&nbsp;folder where the&nbsp;EnemyBehaviorTree&nbsp;we created previously is located and double-click on it to open the Behavior Tree editor.<\/li><li>From there, drag a line from&nbsp;ROOT&nbsp;down and select&nbsp;Selector:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/02b17ca7-1f63-459e-812c-f631ef24d0e5.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>It&#8217;s important to note that you need to drag from the darker gray rectangle on the bottom. If you try to drag from the middle of&nbsp;ROOT, you&#8217;ll just move the node.<\/p>\n\n\n\n<ol><li>Right-click on the Selector node and select&nbsp;Add Service | FindPlayer:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/36058d95-940d-494f-bcd3-9f1d70ff5617.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Now, drag and drop an instance of your&nbsp;MyEnemyCharacter&nbsp;object into your scene and run the game:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/learning.oreilly.com\/library\/view\/unreal-engine-4x\/9781789809503\/assets\/538167bc-799d-4532-a475-eaa0eee25c53.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>As you can see, the value has been set!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>Our Behavior Tree will continue to call the Selector as there are no other nodes for it to transition to.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Creating a BTTask<\/h1>\n\n\n\n<p>In addition to Services, we also have Tasks, which are&nbsp;leaf nodes of Behavior Trees. These are the things that actually perform actions. In our example, we are going to have our AI follow our target, the player.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Getting ready&#8230;<\/h1>\n\n\n\n<p>Finish the previous recipe,&nbsp;<em>Creating a BTService<\/em>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How to do it&#8230;<\/h1>\n\n\n\n<ol><li>From the Content Browser, select&nbsp;Add New | New C++ Class. From the&nbsp;Choose Parent Class&nbsp;menu, check the&nbsp;Show All Classes&nbsp;option and look for the&nbsp;BTTask_BlackboardBase&nbsp;class. Select it and then hit the&nbsp;Next&nbsp;button:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/91d4a05e-cee6-4e79-bdc9-18e76094d6d9.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>At the next menu, set its name to&nbsp;BTTask_MoveToPlayer&nbsp;and then click on the&nbsp;Create Class&nbsp;option:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/00eb28d3-9f0c-4946-89f3-a726f8b2f435.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Open Visual Studio and add the following function to&nbsp;BTTask_MoveToPlayer.h:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#pragma once<br><br>#include \"CoreMinimal.h\"<br>#include \"BehaviorTree\/Tasks\/BTTask_BlackboardBase.h\"<br>#include \"BTTask_MoveToPlayer.generated.h\"<br><br>\/**<br> * <br> *\/<br>UCLASS()<br>class CHAPTER_13_API UBTTask_MoveToPlayer : public UBTTask_BlackboardBase<br>{<br>    GENERATED_BODY()<br><br>public:<br><strong>    \/** starts this task, should return Succeeded, Failed or InProgress<\/strong><br><strong>     * (use FinishLatentTask() when returning InProgress)<\/strong><br><strong>     * this function should be considered as const (don't modify state of object) if node is not instanced! *\/<\/strong><br><strong>    virtual EBTNodeResult::Type ExecuteTask(UBehaviorTreeComponent&amp; OwnerComp, uint8* NodeMemory) override;<\/strong><br>    <br>};<\/pre>\n\n\n\n<ol><li>Then, open the&nbsp;BTTask_MoveToPlayer.cpp&nbsp;file and update it to the following:<\/li><\/ol>\n\n\n\n<pre class=\"wp-block-preformatted\">#include \"BTTask_MoveToPlayer.h\"<br><strong>#include \"EnemyAIController.h\"<\/strong><br><strong>#include \"GameFramework\/Character.h\"<\/strong><br><strong>#include \"BehaviorTree\/Blackboard\/BlackboardKeyType_Object.h\"<\/strong><br><br><strong>EBTNodeResult::Type UBTTask_MoveToPlayer::ExecuteTask(UBehaviorTreeComponent&amp; OwnerComp, uint8* NodeMemory)<\/strong><br><strong>{<\/strong><br><strong>    auto EnemyController = Cast&lt;AEnemyAIController&gt;(OwnerComp.GetAIOwner());<\/strong><br><strong>    auto Blackboard = OwnerComp.GetBlackboardComponent();<\/strong><br><br><strong>    ACharacter * Target = Cast&lt;ACharacter&gt;(Blackboard-&gt;GetValue&lt;UBlackboardKeyType_Object&gt;(EnemyController-&gt;TargetKeyID));<\/strong><br><br><strong>    if(Target)<\/strong><br><strong>    {<\/strong><br><strong>        EnemyController-&gt;MoveToActor(Target, 50.0f);<\/strong><br><strong>        return EBTNodeResult::Succeeded;<\/strong><br><strong>    }<\/strong><br><br><strong>    return EBTNodeResult::Failed;<\/strong><br><strong>}<\/strong><\/pre>\n\n\n\n<ol><li>Save your files and return to the Unreal Editor. Compile your code.<\/li><li>In the&nbsp;Content Browser,&nbsp;go to the&nbsp;Content&nbsp;folder where the&nbsp;EnemyBehaviorTree&nbsp;we created previously is located and double-click on it to open the Behavior Tree editor.<\/li><li>Drag this below the Selector node and select&nbsp;Tasks | Move to Player:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/571d92a5-1006-40e6-b2a4-64a3d13b72fc.png\" alt=\"\"\/><\/figure>\n\n\n\n<ol><li>Save the Behavior Tree and return to the Unreal Editor. Drag and drop a&nbsp;MyEnemyCharacter&nbsp;object into the scene if you haven&#8217;t done so already and play the game:<\/li><\/ol>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"http:\/\/blog.coolcoding.cn\/wp-content\/uploads\/2021\/01\/dcddb9f0-f8a7-4b70-b9c9-2088fd700a86.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>As you can see, our enemy is now following our player, which will happen for as long as the NavMesh covers the area!<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">How it works&#8230;<\/h1>\n\n\n\n<p>This recipe takes all of the materials we&#8217;ve covered so far and compiles them all together. The&nbsp;ExecuteTask&nbsp;method will be called as long as the BehaviorTree is inside this state. This function requires us to return an&nbsp;EBTNodeResult, which&nbsp;should return&nbsp;Succeeded,&nbsp;Failed, or&nbsp;InProgress&nbsp;to let the BehaviorTree know whether we can change states or not.<\/p>\n\n\n\n<p>In our case, we first obtain the&nbsp;EnemyController&nbsp;and the&nbsp;Target&nbsp;objects so that we can figure out who we want to move and where we want to move to. As long as those properties are valid, we can call the&nbsp;MoveToActor&nbsp;function.There are a lot of other properties that the&nbsp;MoveToActor&nbsp;function offers that may be useful so that you can customize your movement. For more information, check out the following link:&nbsp;<a href=\"https:\/\/api.unrealengine.com\/INT\/API\/Runtime\/AIModule\/AAIController\/MoveToActor\/index.html\">https:\/\/api.unrealengine.com\/INT\/API\/Runtime\/AIModule\/AAIController\/MoveToActor\/index.html<\/a>.<br>For those of you who are interested in exploring additional AI concepts with UE4, I highly suggest checking out Orfeas Eleftheriou&#8217;s UE4 AI Tutorials:&nbsp;<a href=\"https:\/\/orfeasel.com\/category\/ue_tuts\/ai-programming\/\">https:\/\/orfeasel.com\/category\/ue_tuts\/ai-programming\/<\/a>.\n\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this chapter, we will cover the following recipes: I [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,1],"tags":[],"_links":{"self":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3160"}],"collection":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3160"}],"version-history":[{"count":5,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3160\/revisions"}],"predecessor-version":[{"id":3312,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=\/wp\/v2\/posts\/3160\/revisions\/3312"}],"wp:attachment":[{"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3160"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3160"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.coolcoding.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3160"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}