skip to Main Content

Implementing AI Hearing using C++

In this post we’re going to create an AI Character that hears our player footsteps and follows him. If you are interested in creating a “Seeing” sense for your AI, check out this post. Before we start, here is the end result:

To achieve the above functionality, we’re going to need a couple of things:

  1. A playable character with a PawnNoiseEmitter component, which will be used to “report” into the game that a sound has been played.
  2. A Controller for our AI character
  3. A custom AI Character which will contain a reference for our Behavior Tree and a PawnSensing component
  4. A Behavior Tree for our AI Logic
  5. A Blackboard to store values for our Behavior Tree
  6. A footstep sound (Optional)

While reading this list you will notice that the footsteps sound is optional, this is because in UE4 we explicitly tell the game that we’ve played a sound somewhere with a certain volume. The engine itself doesn’t care if we have actually played a sound or not. In case you want to include the same footstep sound I’ve used in the video above, here is the download link. In order to get started, create a Third Person C++ Template project.

Before we even begin to write any code, right when your template project loads up, add a nav mesh bounds volume to cover your whole level!

navmesh
Click on the image to enlarge in a new tab

Setting up our playable Character

To set up our character, open up it’s header file, and include the following library right before the .generated.h file:

#include "Perception/PawnSensingComponent.h"

Then, add the following declarations:

Then, switch to your character’s source file and inside your constructor, type in the following initialization:

Moreover, type in the following implementation of the ReportNoise function:

Note here we’re doing two things. We first play the given sound and then we’re using the built-in function MakeNoise to inform our game that we have played a sound.

In case you copy and pasted the code above don’t forget to edit my Character’s class name to match yours.

Now that we’re done with our character’s C++ logic and what we need to tell our character to play a sound when he touches the floor. To do that we’re going to use Animation Notifies. Think of Animation Notifies like functions, which get called in a specific frame of an animation that we decide. For more information about them, check out the official UE4 documentation.

Locate your character’s run animation and add a new Notify (I named my notify GenerateFootstepSound) when your character’s feet touch the ground. I’ve placed my notifies in frames 8 and 18 like the following image suggests:

anim_notify
Click on the image to enlarge in a new tab

Then, go to the Event Graph of your animation blueprint and add in the following logic for the Notifies we’ve created above:

footstep_generation
Click on the image to enlarge in a new tab

Notice that I imported the sound I’ve mentioned above and I have hardcoded its reference for the given function. It would be more flexible to create a separate USoundBase* property inside the Character’s header file and assign values through its Blueprint. However, in this case, this is adequate.

Compile and save your Blueprint. If you play with your Character right now, you will hear the generated sounds for each footstep! Let’s move on!

Creating our AI Character

Add a new C++ class which is based on the Character class and name it MyAICharacter. Inside it’s header file, right before the .generated.h add the following includes:

Then, type in the following declarations:

Then, switch to your source file, and type in the following code:

You will notice that inside the OnHearNoise function I’ve commented out the lines 28 and 34. This is because we have yet to add our AI Controller class. When we’re done with our Controller, we’ll get back and uncomment that code. For now, just compile and save your code.

Creating our AI Controller

Add a new C++ class which is based on the AI Controller class and name it MyAIController. Inside the header file, before the .generated.h header file, type in the following includes:

Then, type in the following declarations:

Switch to your source file and type in the following code:

Moreover,  inside your controller’s source file, don’t forget to add the following include:

#include “MyAICharacter.h”

When you’re done with all that, switch to your AI Character’s source file, uncomment lines 28 and 34 and add the following include:

#include “MyAIController.h”

Compile and save your code.

Setting up our Blueprints

Once you have completed all the steps above, create the following Blueprints:

  1. A Blueprint which inherits our AICharacter class
  2. A Blueprint which inherits our AIController class, and name it BP_MyAICon
  3. A Behavior Tree, named MyBehaviorTree
  4. A Blackboard named MyBlackboard

Once you’ve completed all that, go to our AI Character’s Blueprint and:

  1. Assign the default mannequin skeletal mesh and make sure to rotate the mesh to face the blue arrow inside the capsule collider
  2. Inside the Anim Blueprint Generated Class select the same Anim Blueprint as your main Character
  3. Select the BP_MyAICon as the AI Controller Class
  4. Select the MyBehaviorTree for the Behavior Tree

The above steps are summarised in the following image:

ai_character_bp
Click on the image to enlarge in a new tab

Since we don’t want a “Seeing” sense for our AI, locate it’s PawnSensingComponent and disable the See Pawns option. This is crucial.

ai_character_bp2
Click on the image to enlarge in a new tab

Setting up our Blackboard

Our blackboard setup is simple, add a new Object key named SensedPawn.

Settin up our Behavior Tree

The logic for our AI will be the following: Once we have heard a pawn, we move to its location. When we’ve reached our target we wait. And so on… It’s not the smartest AI in the world obviously, but it will do for this tutorial. The above logic is described in the following Behavior Tree:

ai_hearing_bt2
Click on the image to enlarge in a new tab

Moreover, click on the MoveActor node and set the acceptable radius to 100 and the Blackboard Key to SensedPawn.

Save your project and place an AI Character inside your map. The AI should now follow you like the video I’ve uploaded above.

This Post Has 20 Comments

  1. I don’t know if this is a stupid question or not, but I am going to ask it anyway:
    I have an AI setup going already, it has sight patrol points, deal damge etc. but it is in blueprints only, can I add this C++ to it without breaking my current system?

    Thanks.

    1. Depending on your actual setup you may need to do some tweaking.

      Since your entire AI is based on Blueprints you have already a Blueprint Controller and a Blueprint Character. In case you wish to follow my tutorial you need to create a c++ class for both the controller and the character and then reparent your Blueprints (in order to derive from the c++ classes). By doing so, you might encounter strange problems (again, depending on your Blueprint code so far) so things might go sideways.

      If you’re not feeling safe using C++ I think it would be a better option to implement the whole hearing system using Blueprints (it is do-able and it’s covered in an official UE4 Livestream in their youtube channel somewhere).

      However, you can always create a backup and revert your project if things go sideways!
      -Orfeas

      1. Thanks for your reply, I think this is a really strong tutorial, so I will go on and make a backup and try it 😀

      2. And I already ran into a problemm, I have I characterBase blueprint that manages damage and managers, but I can’t find a way to let my Enemycharacter have a C++ parent, and let that C++ parent have a characterBase parent, this characterBase is also the parent of my FPSCharacter, so I cant just give that a new parent.

        1. I’m a bit confused, do you mean that you have the same parent class for both your playable character and your AI character?
          -Orfeas

  2. Hey,
    Thanks for the tutorial!
    Why are you creating a BehaviourTree Component both in the AICharacter and the AIController? Seems like you’re only using it in the AIController (and the way I’ve understood the functionality, you only need it in the Controller).

    1. Hello, in the AICharacter I’ve added a Behavior Tree and in the AIController I’ve added a Behavior Tree Component. The Behavior Tree located in the AICharacter contains the actual logic of the AI (notice that we assigned a Behavior Tree in the Blueprint of our character), however the Behavior Tree Component is used in order to kickstart that logic when our controller possesses a pawn.

      -Orfeas

  3. I’m having an issue with the UPawnNoiseEmitterComponent… apparently it’s not being properly initialized in the constructor:

    d:\programas (x86)\epic games\4.11\engine\source\runtime\coreuobject\public\uobject\UObject.h(87): error C2027: use of undefined type ‘UPawnNoiseEmitterComponent’

    D:\Programas (x86)\Epic Games\4.11\Engine\Source\Runtime\Engine\Classes\GameFramework/Pawn.h(19): note: see declaration of ‘UPawnNoiseEmitterComponent’

    C:\Users\Goncalo\Documents\Unreal Projects\CodeAI\Source\CodeAI\CodeAICharacter.cpp(43): note: see reference to function template instantiation ‘TReturnType *UObject::CreateDefaultSubobject(FName,bool)’ being compiled
    2> with
    2> [
    2> TReturnType=UPawnNoiseEmitterComponent
    2> ]

    1. Hello Alex, after re-reading my published code in this tutorial, I forgot to mention that you need to add the following header file right before the .generated.h file in your character’s header file:
      #include “Perception/PawnSensingComponent.h”

      I think this will fix your issue, if not, please attach your code in a pastebin link

      -Orfeas

        1. Thank you for your kind words and your suggestion!

          I’ve got an EQS tutorial on my backlog for some time now, so I think that I will take a look into that in the future.

          -Orfeas

          1. Hey i’m having another issue :p

            I’m trying to build up on your tutorials with more AI logic in which two AI characters make noises and receive each other’s noises, other than the ones that come from the player… but for some reason, they can’t hear each other’s noises!

            I did everything just like you did but i changed some stuff (instead of calling the ReportNoise function from the AnimBP, i call it from within the AICharacter class, and on the OnHearNoise function of the AICharacter, it also checks to see whether the same class made that noise).

            Any help would be greatly appreciated 😀

            1. Have you checked their Blackboard values in order to make sure that you have the right referenced values?

              Moreover, make sure that your OnHearNoise and ReportNoise function fire when they supposed to.

              -Orfeas

              1. The problem is that one of the AICharacters is reporting the noise with the MakeNoise() function, but the other AICharacter isn’t calling the OnHearNoise() function when the noise is triggered…

      1. In 4.15.1 alone did not fix my problem (I had the same problem Alex had). But once I added

        #include “Runtime/Engine/Classes/Components/PawnNoiseEmitterComponent.h”

        it worked for me then. I don’t know if Epic Games has changed the API since then but I thought I’d let you know.

        Awesome tutorial once again, Thank you so much for doing this! You are my favorite Unreal tutorial-maker!

        1. That worked for me as well. I checked tom Looman’s tutorial he does the same as Orfeas. What did they do that we didn’t ? =/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Back To Top