Step-by-Step Enemy Creation

Documentation Unreal Engine AI Tutorial

Comprehensive guide to creating a complete enemy from scratch with weapons, animations, and advanced features.


This section provides comprehensive instructions for creating a complete enemy from scratch, including weapons, animations, and advanced features.

Prerequisites

Before starting, ensure you have:

  • Character skeletal mesh with animations
  • Attack animation montages with hit frames identified
  • Basic understanding of Gameplay Ability System
  • Unreal Engine 5.7 installed

Step 1: Character Setup

Create Blueprint: BP_DetailedEnemy (inherits AEnemyCharacterBase)

In Components Panel:

  1. Select SkeletalMesh component

    • Set your character mesh
    • Configure materials
  2. Select CapsuleComponent

    • Adjust radius to fit mesh
    • Set height appropriately
  3. Select CharacterMovement component

Adjust movement component settings if you want.

What You Get Automatically:

  • USECMeleeTraceComponent - Already added by base class

  • UAbilitySystemComponent - Already configured

  • IAbilitySystemInterface - Already implemented

  • AIConfig -> Set it to your AI Config or the DA_SEC_Enemy_AIConfig_Default

AIConfig will be acquired from the pawn by the controller if it's set here. If it is not set in the pawn, AIController will try to use it's own. If that is also not set, there will be no AI behavior.


Step 2: AI Controller Setup

Create Blueprint: BP_DetailedEnemyController (inherits AEnemyControllerBase)

What the base class provides:

// These components are automatically added:
UMovementEvaluatorComponent*    // Tactical movement
UThreatDetectionComponent*      // Player attention tracking
UActionEvaluationComponent*     // Action scoring & execution
UBehaviorTreeComponent*         // For BT sequence execution

Configure Movement:

Open BP_DetailedEnemyController → Details Panel → Movement Evaluator:

Movement Evaluator:

There are a lot of movement related settings. 
Default values on `BP_SEC_EnemyController` work well for a smooth and realistic looking enemy. 
You can configure these settings further.
  
Debug:
  bDebugLog: false (enable to see movement decisions)

Configure Action Evaluation:

Details Panel → Action Evaluation:

CurrentActionSet: DA_DetailedEnemyActions (create next)
bDebugLog: true (enable to see action scoring)

ActionSet is updated by the StateTree depending on the current role. This is defined inside the AIConfig.


Step 3: Create Comprehensive ActionSet

Create Data Asset: DA_DetailedEnemyActions (type: ActionSet)

Add Multiple Actions for Variety:

Action 1: Light Attack (Close Range)

PropertyValueNotes
IdLightAttackUnique identifier
DisplayNameLight AttackEditor display
ExecutionModeGameplayAbilitySimple ability execution
AbilityTagSEC.Action.LightAttackTriggers GA_LightAttack
AbilityEndTagSEC.Action.EndCompletion signal
Distance
↳ MinValue0Valid from 0cm
↳ OptimalMin100Score = 1.0 starts
↳ OptimalMax250Score = 1.0 ends
↳ MaxValue400Invalid beyond
Angle
↳ MinValue0Must face target
↳ OptimalMin0Perfect facing
↳ OptimalMax30Up to 30° good
↳ MaxValue90Don't use >90°
Cooldown
↳ Duration2.02 second cooldown
↳ WarmupCooldown1.0Can't use first 1s
BaseWeight1.0Selection priority
bRequireLOStrueNeed line of sight

Action 2: Heavy Attack (Medium Range)

PropertyValueNotes
IdHeavyAttack
ExecutionModeGameplayAbility
AbilityTagSEC.Action.HeavyAttack
AbilityEndTagSEC.Action.End
Distance: OptimalMin150Slightly farther
Distance: OptimalMax300
Cooldown: Duration4.0Longer cooldown
BaseWeight0.8Lower priority
Chain FromLightAttackCan combo after light
Chain Bonus0.5+50% score if chaining

Action 3: Defensive Retreat (When Too Close)

PropertyValueNotes
IdQuickRetreat
ExecutionModeBehaviorTreeSequenceUses BT for movement
BehaviorTrees[BT_QuickBackstep]Array of BTs to run
Distance: OptimalMin0Use when very close
Distance: OptimalMax100
Cooldown: Duration3.0
BaseWeight1.5Higher priority
Context Modifiers:
↳ Tag: Player.AttackingMultiplier: 2.0Much higher score if player attacking

Step 4: Create Gameplay Abilities

For each action using GameplayAbility execution mode, create an ability Blueprint inheriting from GameplayAbilityBase.

Example: GA_LightAttack

Class Defaults:

  • Ability Tags: SEC.Action.LightAttack

Event Graph Implementation:

Event ActivateAbility
  ↓
[Branch: Check if montage valid]
  ↓ True
Play Montage and Wait
  • Montage: AM_LightAttack
  • Rate: 1.0
  ↓ On Completed
Send Gameplay Event to Actor
  • Target: Get Avatar Actor from Actor Info
  • Event Tag: SEC.Action.End
  • Payload: (optional ActionInfo)
  ↓
End Ability
  • Cancel: false
  
  ↓ On Cancelled/Interrupted
Send Gameplay Event to Actor (SEC.Action.End)
  ↓
End Ability

Important: All of this is covered inside the GA_SEC_Attack, if you choose to not derive from GameplayAbilityBase, always send the ability end tag event, even if interrupted. Otherwise, the AI gets stuck. Action evaluator needs to know when ability is done. This is automatically handled if you are using GameplayAbilityBase as your parent class for abilities.


Step 5: Configure Animation Montages

Create Montage: AM_LightAttack from your attack animation

Add Melee Trace Notify State:

  1. Right-click timeline at attack's active frames
  2. Add Notify State → SECMeleeTraceWindow
  3. Duration: Cover the weapon swing (e.g., frames 10-25)
  4. Add MotionWarping notify state if you want chase behavior during the attacks in certain frames.

Configure Notify State:

Details Panel:

Socket IDs: ["Blade"]  // Must match weapon trace socket, 
not the mesh socket, the trace socket that is registered on the SECMeleeTrace component

Timing Example:

Frame:     0    10    20    30    40    50
Animation: [━━━━][━━━━][━━━━][━━━━][━━━━]
           Windup Strike  Follow Recovery
Trace:          [═════════]
End Event:                          ▲

Step 6: Create Weapon

Create Blueprint: BP_Sword (inherits ASECWeaponBase)

Class Defaults:

Attachment:

AttachSocket: "RightHandSocket"  // Socket on character skeleton
AttackOffset: Relative offset that will be applied after attachment

Trace Sockets Array:

Add element [0]:

ID: "Blade"
Shape: CapsuleTwoPoint
SocketOrBoneName: "blade_start"    // Socket on weapon mesh
EndSocketOrBoneName: "blade_end"   // Socket on weapon mesh
Radius: 15.0
TraceChannel: ECC_Pawn

Damage Configuration:

DamageConfig: DA_SwordDamage  // Create data asset from `SECDamageConfig`

Weapon Mesh Setup:

  1. Components → WeaponMesh → Set your sword static/skeletal mesh
  2. Add sockets to weapon mesh:
    • blade_start at blade base
    • blade_end at blade tip
  3. Position sockets along the cutting edge

For different types of weapons, there are multiple selections for how should the trace work, for example, a hammer can use Sphere instead of CapsuleTwoPoint. You can select what works the best for your case.

What Happens Automatically:

  • On equip → Registers trace sockets with character's MeleeTraceComponent
  • During montage notify → Traces activate between sockets
  • On hit → Applies damage via DamageConfig

The Apply Damage function is called on the actor that has been hit, this function is from unreal. If you want to implement your own way of communicating the damage, you can just ignore this and implement it on top. Both SECMeleeTrace component has functions and delegates you can listen to easily.


Step 7: Create Damage Configuration

Create Data Asset: DA_SwordDamage (type: SECDamageConfig)

Damage: 25.0
DamageType: UDamageType (or custom class)

SECDamageConfig comes with common use-case variables, like "CanBeBlocked", "CanBeParried". 
If you need more, you can create a blueprint inheriting SECDamageConfig and extend the data.


Step 8: Build StateTree Logic

For this step, i highly recommend using "StateTree_SEC_Core" instead. For majority of the cases it will work as expected. Otherwise you can learn from it.

Create StateTree: ST_DetailedEnemy

Root State Configuration:


StateTree: (Core)

├─ Root State
│  │
│  ├─ Combat State
│  │  • Condition: (Is Object Valid) AND (Not SEC.Role.None contains exactly PollCombatRole.OutCombatRole)
│  │  │
│  │  ├─ Role State
│  │  │  • Condition: SEC.Role.* contains exactly PollCombatRole.OutCombatRole
│  │  │  └─ Linked Subtree: *_Subtree → StateTree_SEC_MoveAndAction
│  │
│  └─ Idle State
│     • Task: Delay 1.0

StateTree: StateTree_SEC_MoveAndAction

├─ Root State
│  • Task: Sync Action Set from Pawn
│  │
│  └─ Role State
│     • Tasks: PollTargetActor, Build Decision Context, Poll Action
│     │
│     ├─ Move State
│     │  • Condition: ASC Has Tag
│     │  • Task: AI Movement (Distance: 600)
│     │  └─ Transition → Action State
│     │
│     ├─ Action State
│     │  • Task: Do Action
│     │  ├─ Transition → Recovery State (Success)
│     │  └─ Transition → Role State (Failure)
│     │
│     └─ Recovery State
│        • Task: Delay Parameters.RecoveryDuration
│        └─ Transition → Role State

Step 9: Test Your Enemy

Place in Level:

  1. Drag BP_DetailedEnemy into level
  2. Details Panel → Pawn → AI Controller Class → BP_DetailedEnemyController

Debug Configuration:

Enable logging in controller:

ActionEvaluation → bDebugLog: true
MovementEvaluator → bDebugLog: true

Play and Observe:

Output Log Messages:

LogEvaluation: Evaluating 3 actions for BP_DetailedEnemy_1...
LogEvaluation: [LightAttack] Dist:180 Angle:15 Score:0.95 SELECTED
LogEvaluation: [HeavyAttack] Dist:180 Angle:15 Score:0.60 (cooldown)
LogEvaluation: [QuickRetreat] Dist:180 Angle:15 Score:0.10 (too far)

Expected Behavior:

  • Approaches to ideal distance range
  • Strafes around player
  • Executes light attack when in optimal range
  • Occasionally uses heavy attack
  • Retreats if player gets too close

Common Issues

ProblemCauseSolution
AI doesn't attackAbility not activatingCheck AbilityTag matches, verify ASC grants ability
AI repeats same actionOnly one action validAdd more actions with different ranges
AI doesn't moveMovement not enabledCheck STTask_AIMovement is ticking
Weapon doesn't hitSocket mismatchVerify notify Socket IDs match weapon TraceSockets IDs