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.
A new action ships with an empty Scorers list, so it scores the same at every distance and angle until you add scorers to it. This is the flow for adding one:
Content Browser
Content>Plugins>SoulslikeEnemyCombat>ActionSets
Scoring list
Action Scorers
SelectionWeight
Always present · × base
No scorers or gates, so the action scores on weight alone.
score = Weight × Distance · (Stamina pass) × Yours
Add from library
Distance ScorerData Asset (Scorer)
Stamina GateData Asset (Gate)
Create customBlueprint (USECScorer)
Each scorer multiplies in; each gate can veto. Mix built-ins with custom subclasses.

Light attack, close range

Identity
Action Id
LightAttack
Enabled
Execution
Execution Method
Gameplay Ability
Ability Class
GA_LightAttack
Scoring
Selection Weight
1
Scorers
2 Array elements
Distance Scorer
Range 0 / 100 / 250 / 400
Angle Scorer
Range 0 / 0 / 30 / 90
Gates
0 Array elements
Chaining
Preferred Follow-Up Action
HeavyAttack
Chain Bonus Multiplier
1.5
Cooldown
Cooldown Duration
2
Initial Cooldown
1
Distance ranges are centimetres and angle ranges degrees. Initial Cooldown keeps the enemy from opening the fight with this attack. The chaining rows are what feed the heavy attack below.

Heavy attack, the combo finisher

Identity
Action Id
HeavyAttack
Enabled
Execution
Execution Method
Gameplay Ability
Ability Class
GA_HeavyAttack
Scoring
Selection Weight
0.8
Risk Penalty
1.5
Scorers
1 Array element
Distance Scorer
Range 0 / 150 / 300 / 450
Cooldown
Cooldown Duration
4
A lower Selection Weight and a Risk Penalty above one both bias against picking this on its own, which is what leaves room for the chain: the light attack's Preferred Follow-Up Action and Chain Bonus Multiplier score the heavy 50% higher for one pick after a light lands.

Retreat, when crowded

Identity
Action Id
QuickRetreat
Enabled
Execution
Execution Method
Behavior Tree Sequence
Behavior Tree Sequence
1 Array element
[0]
BT_QuickBackstep
Scoring
Selection Weight
1.5
Scorers
1 Array element
Distance Scorer
Range 0 / 0 / 100 / 200
Tag Score Multipliers
State.PlayerAttacking = 2.0
Cooldown
Cooldown Duration
3
This one runs a Behavior Tree rather than an ability, and its distance range peaks close in, so it scores highest exactly when the player has crowded the enemy.
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 Weapons page: inherit ASECWeaponBase, define the trace sockets, and add the weapon to the enemy's Starting Loadout so it arrives in hand on spawn. Melee Trace covers the SEC Melee Trace Window notify state and the damage config. Set that up, then come back to test.

5. StateTree, if you want authored structure

Leave the config's Default State Tree empty and the native loop runs the combat you 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: [EvalComp] LightAttack: Ctx=0.95 Nov=1.00 Chain=1.00 Risk=1.00 Runtime=1.00 Custom=0.95 -> 0.90
LogEvaluation: [EvalComp] HeavyAttack: Ctx=0.40 Nov=1.00 Chain=1.00 Risk=0.67 Runtime=1.00 Custom=0.40 -> 0.11
LogEvaluation: [EvalComp] Committed to: LightAttack (score 0.90)
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 well, or the others have no scorersAdd a Distance Scorer and an Angle Scorer per action, with different 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 attackThe ability never endsConfirm it reaches End Ability on every exit path. The Execution Method's Ability Timeout catches one that does not, and logs the action that hung.