Step-by-Step Enemy Creation

Documentation Unreal Engine AI Tutorial

Build a complete, armed enemy: a multi-action moveset with combos, a weapon, and testing. Builds on Getting Started.


Getting Started built a one-attack enemy. This guide arms it into a real fight: a moveset that scores different ranges, a light-into-heavy combo, a retreat, a weapon that lands hits, and a way to watch the AI decide. Each part links to the system page behind it.

Before you start

  • Finish Getting Started. You reuse that pawn, controller, and config here.
  • Have two or three attack montages ready, and know which frames carry the hit.

1. Reuse the pawn, controller, and config

You already made these in Getting Started: a Blueprint from EnemyCharacterBase, a controller from EnemyControllerBase, and an EnemyAIConfig. Keep them. To swap in your own classes, use the reparent steps in Getting Started. The rest of this guide extends the ActionSet those pieces already point to.

2. Build a moveset

One action is enough to see the AI attack; a fight needs several that win at different ranges and moments. Open your ActionSet and add these to the Actions array. For the full field reference, see the Action System.

Light attack, close range

PropertyValueNotes
Action IDLightAttackUsed for chaining and cooldowns
Execution MethodGameplay AbilitySet its Ability Class to GA_LightAttack
Scoring → Distance Scorer0 / 100 / 250 / 400Min / OptimalMin / OptimalMax / Max, in cm
Scoring → Angle Scorer0 / 0 / 30 / 90Ideal within 30 degrees of facing
Cooldown → Duration2.0Two seconds between uses
Cooldown → Initial Cooldown1.0Cannot open with it in the first second
Selection Weight1.0Base weight

Heavy attack, the combo finisher

PropertyValueNotes
Action IDHeavyAttack
Execution MethodGameplay AbilityAbility Class GA_HeavyAttack
Scoring → Distance Scorer0 / 150 / 300 / 450Slightly farther than the light
Cooldown → Duration4.0Longer than the light
Selection Weight0.8Comes up less often on its own
Risk Penalty1.5Divides the score, biasing against it
To chain light into heavy, set Preferred Follow-Up Action to HeavyAttack on the light attack, and Chain Bonus Multiplier to 1.5. The heavy scores 50% higher for one pick after a light lands.

Retreat, when crowded

PropertyValueNotes
Action IDQuickRetreat
Execution MethodBehavior Tree SequenceSet Behavior Tree Sequence to [BT_QuickBackstep]
Scoring → Distance Scorer0 / 0 / 100 / 200Best when very close
Cooldown → Duration3.0
Selection Weight1.5Higher priority in range
Tag Score MultipliersState.PlayerAttacking → 2.0Doubles the score while the player attacks
Tag Score Multipliers map a FGameplayTag to a multiplier. When the tag is on the AI, the target, or the world, it scales the score. Use State.Stunned → 2.0 on the target for a punish, or World.Phase.BossPhase2 → 1.3 for late-fight aggression. The Action System covers the full scoring model.

3. One ability per Gameplay Ability action

Each action using the Gameplay Ability method needs an ability Blueprint. Inherit from GA_SEC_Attack, assign the montage, and you are done: it plays the montage, forwards the notify events, and sends the end tag the action system waits on. Getting Started, Step 3 covers this and the from-scratch route.

4. Arm the enemy

The attacks play, but nothing lands until the weapon runs melee traces. The full weapon build lives on the Melee Trace page: inherit ASECWeaponBase, define the trace sockets, add the SECMeleeTraceWindow notify to each montage, and assign a damage config. Set that up, then come back to test.

5. StateTree, if you want authored structure

Leave the config's DefaultStateTree empty and the native loop runs the combat you just built. Set it to StateTree_SEC_Core, or author your own, when you need patrol, investigation, or boss phases on top. The StateTree Tasks page covers the graph nodes.

6. Test and debug

Drop BP_MyEnemy into a level with a built NavMesh, and confirm its AI Controller Class points to your controller.
Turn on the decision logs while tuning:
  • ActionEvaluationComponent → bDebugLogDecisions: logs each action's score and why it won or lost.
  • MovementEvaluatorComponent → bDebugDrawScoring: draws the scored movement directions in the world.
The decision log reads something like:
LogEvaluation: Evaluating 3 actions for BP_MyEnemy...
LogEvaluation: LightAttack  -> 0.95
LogEvaluation: HeavyAttack  -> 0.60
LogEvaluation: QuickRetreat -> 0.10
Expect the enemy to close to its scored range, strafe, open with a light attack, sometimes chain into the heavy, and retreat when you crowd it or press an attack.
Per-scorer values live in FScoreBreakdown.CustomScores, keyed by each scorer's GetDisplayName(), and fold into the Custom factor. There is no separate Dist or Angle line in the log anymore.

Common issues

ProblemCauseFix
AI does not attackNo ability on the actionSet the Execution Method's Ability Class, and confirm the ability activates
AI repeats one actionOnly one scores wellAdd actions with different distance and angle ranges
AI does not moveNo NavMeshAdd a NavMeshBoundsVolume and build navigation
Weapon does not hitSocket ID mismatchMatch the notify's Socket IDs to the weapon's TraceSockets ID (see Melee Trace)
AI stuck after an attackEnd tag never sentInherit the ability from GA_SEC_Attack or GameplayAbilityBase