Creating Gameplay Balance System – Part 3 – Supporting all enemies


I have created Pattern Manager  and now I need to support all enemies to be able to reset properly. Remember – the goal was to not spawn / destroy enemies – instead just resetting the values. I will go through all enemies and make sure that:

  • Mesh ragdoll is getting back to animation,
  • Mesh is attached to capsule component with the same translation as it was on Begin Play,
  • All necessary timers will be disabled as well,
  • Tick will be disabled when enemy isn’t active,
  • Refactor the enemies as it was long time ago I had created them,

So let’s go!

This Tutorial has been created using Unreal Engine 4.10
Make sure you are working on the same version of the engine.

Updating BP_BaseEnemy

First I will update BP_BaseEnemy and add some functions to help me with ragdoll and capsule components.

Basically pattern manager is moving the actors when disabling / enabling pattern. There will be two problems: moving ragdoll and capsule with movement.

Open BP_BaseEnemy and add one Translation variable named TranslationBeforeActive. This will be mesh default translation when attached to CapsuleComponent.  Just set it to Mesh relative transform at Begin Play:


And make sure on Begin Play Character Movement Mode is set to None. Spawned characters shouldn’t move, we will activate movement when character will be enabled:


Now create new function named EnableCapsule:


This will reset our CapsuleComponent.

Create another function named EnableRagdoll which will just enable Ragdoll on Mesh:


Now create another function named ResetRagdoll:


This will basically get back mesh to it’s default position and make sure character is ready for next pattern.

The last thing here is to update interface events:


I’m hiding the enemy and disabling skeleton updates. Thanks to this I won’t get draw calls on disabled enemies in patterns.

And that’s all here. We are ready to roll.

Updating BP_Enemy_Trooper

Open BP_Enemy_Trooper  and add IEnemies interface events:


Remember that things connected to gameplay that are in Begin Play should be called again in Activate Enemy like RandomDistanceFromPlayer.

Updating Movement

Trooper have AIController and Behavior tree. Shooter Tutorial movement is simple – enemy should walk forward and that’s all. Behavior Tree isn’t needed and AIController isn’t needed as well.

Add Tick event and make sure it’s walking forward when not reloading (as in Behavior Tree)


Why I’m using Tick instead of Behavior Tree? There will be lot of instances of this enemy on level which won’t be active for pattern manager. If I will have custom AIController with Behavior Tree – they will be active all the time. Trooper have really simple AI and movement and it don’t need Behavior Tree. Another thing is that I’m disabling Tick when Enemy is disabled.

Updating Die event

Just make sure that EnableRagdoll function is called in Die:


And that’s all. You can delete all Set Blackboard Key functions as we don’t use Behavior Tree. You can now add Trooper to Patterns and check if everything is working properly. It should go back from ragdoll to it’s default position.

Updating BP_Enemy_Marine

Marine is more complicated as it uses custom events to Fire and Reload – and Fire is calling again from Fire after a delay.

Open BP_Enemy_Marine and add one bool variable named CanExecuteFireAgain.

Updating BeginPlay

Create new custom event named ResetData:


It will be called each time Marine will be activated.

Updating Tick

In Tick Marine is triggering OnNearPlayer function only one time. We need to reset DoOnce node. Create new custom event named ResetOnNearPlayer:


I will call ResetOnNearPlayer when this enemy will be activated again.

Updating Fire

This is simple just check if CanExecuteFireAgain is True in the beginning:


This will prevent from shooting after killing him while reloading or shooting.

Updating Die

In Die we want to be sure that CanExecuteFireAgain is False. Instead of destroying MuzzleFlash I’m deactivating it:


Updating TakeDamage

Just one thing – make sure that TakeDamage won’t be called if Marine is Dead:


Adding IEnemies Interface events

Now add IEnemies interface events:


It’s much more harder to work with activate / deactivate enemy but trust me we will gain a lot of performance and less glitches.

Marine comes with two movement type: Standing and Crouching (isCrouching bool) just create new blueprint named BP_Enemy_Marine_Crouching extending from BP_Enemy_Marine and set isCrouching in defaults to True. Thanks to this you will be able to place crouching and standing Marines in your pattern. You will get more control and less random.

Updating BP_Enemy_Ninja

Here we have the same situation as in Marine. Open BP_Enemy_Ninja and add one bool variable named CanAttackAgain.

Updating Tick

Create new Custom Event named ResetJump and connect it to DoOnce function in Tick:


Set CanAttackAgain as well. Now before calling MeleeAttack check if Ninja isn’t dead or CanAttackAgain is false:


Why this is needed?

Because after Delay – character could be dead or it has been reset – this will prevent triggering melee animations when activating Ninja.

Updating Take Damage

We can just call Die here instead of old nodes:


So it will be more constant.

Updating Die

Here’s when we will set CanAttackAgain to false. Rest of old nodes aren’t needed as physics has been updated and bones are still hidden after enabling physics.


Updating Melee Attack

Just make sure that CanAttackAgain is true:


Adding IEnemies Interface events

Last thing is to add IEnemies interface events:


They should be straightforward.

Updating BP_Enemy_FutureSoldier

This one is using more complicated Behavior Tree so I will leave it as it is, but make sure he will work with patterns.

Open BP_FutureSoldierController and add new custom event named EnableAI:


You don’t need to call this on Posses – delete this old node.

Now open the Blackboard named SoldierBlackboard and add one new bool variable named isActive. Open all Soldier Behavior Trees and make sure you have added Blackboard Decorator in top of your tree:


Make sure it aborts both. So basically if isActive will be false rest of the tree won’t be called.

Updating Anim Blueprint

Open FutureSoldier_AnimBP and add new slot named Dying.  You can find more information how to create new slots here.


So basically when I call Dying slot anim soldier_anims_separated will run as well. I want to be sure that it will be at the end of the animation (when soldier is lying on ground) before slot animation ends. That’s why it have 100 rate.

Now open BP_Enemy_FutureSoldier and make sure CharacterMovement’s Orient Rotation To Movement is set to True.

Adding IEnemies Interface events

This time it will be different as it uses Behavior Tree. You need to make sure blackboards is aware of isActive variable as well.


Updating Die

Soldier isn’t using ragdoll as UE4 Physics cant import skel meshes with different scale option. Instead I’m playing dying animation on Dying slot.


Standing / Crouching

Soldier can crouch and stand as well as Marine. Just create child blueprint and set SoldierType to Crouching / Melee / Standing so you can place it in your patterns.

That’s all for Soldier!

Updating BP_Enemy_RobotWarrior

This one will be simple. Open BP_Enemy_RobotWarrior.

Updating AttackPlayerMelee

Just make sure before you run AttackPlayerMelee again that isAttackingPlayer bool is True:


This way even after delay we will check if we can attack again.

Updating Die


This will make sure all animations will stop and IsAttackingPlayer will be set to false. Thanks to this MeleeAttacks won’t be triggered again after delay.

Adding IEnemies Interface events


It should be straightforward.

Updating BP_Enemy_SmallSpider

This will be more difficult as it isn’t extending BP_BaseEnemy. Open BP_Enemy_SmallSpider and add one new Dispatcher named OnEnemyDead.

Then add these variables:

  • isActive (bool),
  • TransformBeforeActive (Transform)

Make sure you have implemented IEnemies interface on this actor!

Now select SpringArm component and disable Camera Lag and Camera Rotation Lag. When moving spider we don’t want to have any interpolation 🙂

Updating Begin Play

Here we just need to store TransformBeforeActive variable:


Updating Tick

Make sure you won’t run Tick if isActive is false:


Whole movement is done in Tick so spider shouldn’t move when isn’t active.

Another thing is attacking player – it’s done using Do Once which need to be reset.

Create new custom event named ResetAttack and connect it to DoOnce node:


Updating Take Damage

Delete Set Life Span node because we don’t want to destroy the Spider on death. Another thing is to call OnEnemyDead dispatcher:


Adding IEnemies Interface events

Make sure IEnemies is implemented to this actor. Spider isn’t extending from BP_BaseEnemy so we can’t use its functions.


And Reset:


I have added comments so it should be straightforward.

That’s all here but Pattern doesn’t know about BP_Enemy_SmallSpider. Open Pattern blueprint and in GetEnemiesInPattern add another Cast to bind OnEnemyDead:


Thanks to this Pattern will know when Spider will be dead!

Final Words

Now each enemy is supported by Patterns and can be activated / deactivated. Thanks to that I can finally move to balancing and creating first patterns!

Again: spawning / destroying actors are costly and can make glitches on dynamic games. Doing activate / reset was hard and log way but I’m sure I won’t have problems with performance now.

Creating ShooterTutorial takes a lot of my free time.
donateIf you want you can help me out! I will use your donation to buy better assets packs and you will be added to Credits /Backers page as well. Implementing game is taking time but writing about it is taking much more effort!


4 Replies to “Creating Gameplay Balance System – Part 3 – Supporting all enemies”

  1. Really great tutorial! I am really glad that you help to learn UE4!
    the only issue that stood in front of me is that EnableAI that runs behavior tree is only works with the first Pattern_soldier and the other ones are stading and not running the behavior. I am implementing the locig for the trooper because this character is not moving just forward but moveTo player location. could you help me if i end you my project?

  2. Outstanding tutorials, thanks again for taking the time to do these. Side note – For anyone struggling with guys not moving while working on this one – I encountered an issue in my project where I needed to extend the tunnel geo and add a navmesh to the area beyond the end of the tunnel, where the patterns get placed and activated. I’m not using any of the tutorial assets, so if you’re also using your own stuff this might crop up.

    1. To clarify – basically my patterns were getting activated in mid-air, about 100 yards in front of the player, outside the map. Fine for the flying drones but broke everyone else.

Leave a Reply