Target system similar to “Dark Souls” | Blueprint Part 2


In this post you we will learn how to implement targeting enemy system similar to the one used in “Dark Souls” games.
Part 2 will build up on a project that we have done before. Part 1 of this tutorial can be found here : CLICK ME

This tutorial will use Blueprints only and it will contain:

  • Multiple enemies that follow player.
  • Finding and targeting closest enemy to the player.
  • Disable rotation of the camera around the Z axis (Yaw) when enemy is targeted.

Note: This tutorial is made in Unreal Engine 4.10.4 and it uses Third Person new Blueprint project.

Preview:


Function DistanceFromPlayerCheck

In Eneamy_BP add a new function called DistanceFromPlayerCheck. It will be used to return a distance from our player. You can do that by clicking “+” button on the right-hand side of the Functions menu.

1 enamy distacefrom player check function

 

 

 

[1] New function inside the blueprint

Double click on the function then on the right side of the blueprint In Details select “New” in Outputs and add a new float variable called DistanceFromPlayer.

Next, make sure that Access Specifier is select to Public.

2 call it distance from player

 

 

 

 

 

 

 

 

[2] Access Specifier. Click on the drop down menu and select “Public”

Function Get Distance To allows us to get a distance from one actor to the other,

To do that we need to get the player character using Get Player Character. Since we have only one player character on the scene, as the Player index we put 0. If there would be more players it would return the first one in the list. When you have your getter put a new Get Distance To. Plug a Return Value of the Get Player Character to the “Other Actor” input of Get Distance To.  Put a Return Node in your blueprint if don’t have it yet and connect return value  to Distance From Player. After you’ve finished, your function should look like the one on a picture below [3].

When ever this function will be call it will return distance between this enemy and player.

3 check distance function

[3] Get Distance from Player Check


 

Add Alive Check to Enemy_BP

Add a new Boolean variable called Alive and set it to True.

4 add alive varibles

 

 

 

[4] New Boolean variable

 

In Enemy blueprint on Event BeginPlay add a new  Branch node with condition Alive  and connect the node from True to DoOnce.

This check will stop the enemy from ruining any logic if variable Alive is set to false.

5 add alive

 

 

 

 

 

[5] Event BeginPlay of the Enemy_BP

 


 

Custom Event SeekPlayer

Now let’s create a custom event called SeekPlayer then connect it to the AI MoveTo.

This event will move the enemy to a player’s location.

AI Move To is a function responsible for moving a specific actor towards the other actor or a vector. More informations about this can be found here :  CLICK ME

Now, connect all the other nodes as shown in the picture [6]:

6 SeekPlayer

 

 

 

 

[6] Seek player section

 


 

Add Variables to ThirdPersonCharacter(BP_Player)

Open the ThirdPersonCharacter blueprint and add the following variables:

  • Boolean TargetLocked – it will be used to tell whether enemy is targeted or not.
  • Enemy_BP NearestTarget – it will hold instance of the nearest target to the player.
  • Float ClosestTargetDistance – it will be used for keeping the distance to the closest target
  • Float MinimumDistanceToEnable – this will be a minimum distance required to enable targeting (by default I set it to 600)

 

 

 

 

 

[7] New variables at BP_Player

 


 

Update custom Event Target logic

In the ThirdPersonCharacter blueprint we will modify a  Event Target logic that was created in part one. From now on, when the target is set, it will allow our player to find the closest enemy in a range to be targeted. What we have to do is simply set the Closest Target Distance to a Minimum Distance To Enable, that will allow player to reset closest target distance to correct minimum distance in order to allow player to target enemy.

Create a new branch that will check our Target Locked condition.

9 input fire

 

 

 

 

[8] Setting closest target

Now, when the Target Locked is set to true it we have to find the closest enemy.  To do so, first we need to get a list containing all the enemies available in the scene. Put a new node Get All Actors Of Class, set the Actor Class to Enemy_BP.  Create a ForEachLoop which will take as an input a list of all the enemies. In the LoopBody check a distance from Player using our newly created Distance from Player Check, then compare the distance to the Closest Target Distance using CompareFloat done and if it’s smaller simply set the current Array Element as the Nearest Target. Later on, when the loop is completed, use Branch node to check if the Closest Target Distance is smaller than a our MinimumDistance. If yes, then set TargetLocked to true. After all of this you should get something similar to the blueprint on picture [9].
13 get closest in ragenge

[9] Setting closest target continued

When the target is locked on we want to update camera’s rotation. The output of the TargetLock ON will serve as a toggle of a Gate. Take a Timeline_0 and plug Update to a Enter of a Gate [10].

 

tt

 

 

 

 

 

 

 

 

 

 

[10] Gate

Camera rotation part was pretty big and it’s a little bit hard to read. Let’s make our lives easier and replace all of these nodes with one function node. Select all of them like show in the picture [11]

 

15 camera update

[11] Select all these nodes

then right click and select Colapse To Function [12].

12 colap to function

 

 

 

 

 

 

 

 

[12] Collapse to function

Let’s name it Change Camera and Player Rotation when Target. This looks much better! All these nodes are now inside one function [13].

16 marg function

 

 

 

 

 

 

[13] Change Camera and Player Rotation when Target

 


 

Follow enemy test action

Let’s add one more functionality to the enemies. Right click and add a new Custom Event which will be fired when the “F” key. was pressed. Then, get all  actors of a class Enemy BP and call a Seek Player [14]

at f find all the players

 

 

 

 

[14] Seek Player when a “F” button was pressed

 


Nav Mesh Bounds Volume

Our system is useless if enemies cannot move. The missing part we need to add is a Nav Mesh Bounds Volume. Simply type a “nav mesh” in the window on your left-hand side and drag it into our scene [15].

nav find

 

 

 

 

 

[15] Nav Mesh Bounds Volume

When the Nav Mesh volume is placed in the scene you can scale it up to cover the area in which enemies will be able to move. If the point that enemy is looking for is outside of this volume, it will not be able to find a way to follow a player [16].

nav in scene

[16] Nav Mesh Bounds Volume in the scene

We’re almost done! Now when are inside the Nav Mesh volume and press “F”, enemies will start to follow you.

 


Fix mouse input

As your target is locked you might want to limit the movement of the Player’s camera. This system is now the precise copy of the one we can find in Dark Souls but it’s good enough for this moment. Our goal is to do the following:

  1. When the target is locked, disable rotation around Z axis (Yaw)
  2. When the target is locked, limit the rotation of the camera around X axis (Pitch)

Now all we need to do is to go ahead and modify the ThirdPersonCharacter blueprint. To do this go to the content browser and find the ThirdPersonCharacter blueprint and go to the Mouse input section.

Let’s start with the point 1. As you probably noticed, InputAxis Turn is responsible for changing the rotation around the Z axis (Yaw). To disable this, you will have to create a Branch node. Drag the TargetLocked bool to the canvas and wire it up to the the Condition of the Branch. If this is false (our target is currently not being locked) then simply do normal rotation. If this is true – nothing will happen. Now, wire up the Axis Value of the InputAxis Turn to the Val of the Add Controller Yaw Input.
Axis Value is a float number that represents the difference in the axis between the frames. If we multiply its value by a number from range 0-1, we can make the mouse input less sensitive. Let’s use this knowledge in implementation of point 2. All you need to do is to put a Multiply Node (right-click and type “*”) feed it with two inputs – Axis value and our multiplier and connect the output to the Value of the Add Controller Pitch Input. We want to have different mouse sensitive when the target is locked, so the last thing is we are going to do is dragging a Select Float and connect the TargetLocked to it’s condition.  In the A input you can put your own value. I feel that a 0.2 value (20%) is just right for this purpose. As you can imagine if you will give it a value higher than 1, then our mouse input will be more sensitive and will result in faster rotation. After all these steps you should end up with something similar to the blueprint from the picture [17].

8 mouse input

 

 

 

 

 

 

 

 

 

 

[17] Modified mouse input


Congratulations! You’ve made it to the end of part 2

You probably want to shout now: “But this is different than controls in Dark Souls!!!!”.
Calm down! 🙂 This is just a temporary.

In next and last part of this tutorial we will improve our controls that they will look exactly the same as in Dark Souls.

If you have any questions please leave a comment below or write to us directly.

Making tutorials takes a lot of our time. If you want us to make tutorials more often and with better quality please donate us!

Share: