What's Inside
Souls-like Combat
Telegraphed attacks: Windup → Active → Recovery. Parry system with stun.
Emotional AI
5 emotions: Calm, Curious, Aggressive, Frightened, Enraged. Each changes behavior.
Hearing / Stealth
AI hears noise based on player movement type. Sprint is loud, crouch is silent.
Threat / Aggro NEW
Full threat table. AI tracks who's the biggest threat. Taunt, decay, healer aggro.
Multiplayer NEW
Server-authoritative AI. Health, state, emotion replicate to all clients. One checkbox.
Multi-Target NEW
AI detects and tracks all players. Picks best target using threat or distance.
Knowledge Sharing
Monsters tell each other where the player is. Pack hunting without complex code.
Adaptive Difficulty
AI adjusts to player skill automatically. Dying a lot? AI gets easier.
Scripted Encounters
JumpScare, Dramatic reveal, Ambush. Trigger when you want.
Day / Night
AI gets more aggressive, faster, and detects further at night.
Health System
Built-in HP with regen. Events for damage, healing, death. No extra components.
Debug Visualization
See detection radius, attack range, hearing, FOV, state, HP — all in editor.
Quick Start — 3 Minutes Setup
1. Enable the Plugin
In Unreal, go to Edit → Plugins
Search "Simple Monster AI" → check the box → restart editor
2. Add Component to Your Enemy
Open your enemy Character Blueprint (must be a Character, not just an Actor)
Click Add Component → search "Simple Monster AI v2.1" → add it
3. Tag Your Player
This is the #1 mistake! Without the Player tag, the AI will never detect you.
Open your Player Character Blueprint
Click Class Defaults in the toolbar
In Details, search "Tags" → find Actor → Tags → click + → type Player
Compile & Save both Blueprints
4. Test It
Place your enemy in the level → Press Play → Walk close → The monster chases you!
Default settings: Wanderer mode, 1500cm detection, 200cm attack range, 400cm/s chase speed. Tweak everything in the Details panel.
How-To Guide (Blueprints)
Step-by-step Blueprint recipes. All function and event names are exact — search them in your Blueprint.
How to Deal Damage TO the Monster
The plugin does NOT automatically take damage from your weapons. You call the function yourself.
In your weapon/projectile Blueprint, when you detect a hit on the enemy
Get the hit actor → Get Component by Class → select SimpleMonsterAIComponent
Drag from the component pin → call Take Damage (input: Damage Amount as float)
Tip: If using Threat System, also call Add Threat right after, passing the player as Source and the damage as Amount.
How to Deal Damage FROM the Monster to the Player
Important: The plugin fires On Attack Started but does NOT automatically damage the player. You decide what happens.
In your enemy Blueprint Event Graph, right-click → search "On Attack Started" → add the event
From that event, call Get Detected Player on the AI component to get the target
Call Get Effective Damage on the AI component for final damage (includes all modifiers)
Apply damage to the player using your own health system (e.g. Apply Damage or a custom function)
How to Set Up Parry (Souls-like)
On the AI component, enable bUseSoulsLikeCombat and add attacks to the Attacks array
In your player Blueprint, when the parry button is pressed:
Get a reference to the enemy AI component → call Try Parry → returns a bool
If true: parry succeeded! Monster is stunned for ParryStunDuration seconds. Play your parry effect.
You can also check Is In Parry Window to show a UI indicator while parry is possible
How to Make Monsters Alert Each Other
On ALL monster AI components, enable bUseKnowledgeSharing
Make sure all monsters have the same AllyTag (default: Monster)
Done. When one monster sees the player, nearby allies investigate the same location.
How to Make Monsters Enrage When an Ally Dies
Enable bUseEmotionalAI on all monsters
Enable bEnrageOnAllyDeath (on by default)
Same AllyTag on all, within AllyDeathDetectionRadius (default: 1000cm)
Kill one → nearby allies become Enraged (+50% damage, +30% speed, -20% defense) for EnragedDuration seconds
How to Create a Jump Scare
Enable bUseScriptedEncounter, set EncounterType to Jump Scare
Enable bWaitForTrigger — monster stays dormant until triggered
Optionally assign EncounterMontage and EncounterSound
Place a Trigger Box in the level. On overlap → get AI component → call Trigger Encounter
How to Use Threat / Taunt in Multiplayer Co-op
Enable bUseThreatSystem and bEnableMultiplayer
Tag ALL player characters with PlayerTag (default: Player)
AI automatically tracks all players. Whoever deals most damage gets most threat.
Tank ability: call Taunt on AI component, passing tank actor as Source and desired Duration
Healer: on heal, call Report Heal Threat with healer actor and heal amount
How to React to AI State Changes
All events are on the AI component. In your enemy Blueprint Event Graph:
Right-click → search the event name (e.g. "On State Changed", "On Death", "On Emotion Changed")
Event node appears with output pins for parameters (see Events table)
Connect your logic: play effects, update UI, trigger sounds
Example: On Emotion Changed → Switch on NewEmotion → play different particles for Enraged vs Frightened.
How to Read AI Info at Runtime
Pure functions — call them any time, no side effects:
| Function | Returns | Use For |
|---|---|---|
GetCurrentState | EAIState | Show state on UI |
GetCurrentEmotion | EMonsterEmotion | Change enemy aura by emotion |
GetDetectedPlayer | Actor or null | Who is AI targeting? |
IsAIActive | bool | Is AI running? |
GetHealthPercent | float 0.0–1.0 | Health bar widget |
IsInParryWindow | bool | "Parry Now!" UI prompt |
GetEffectiveChaseSpeed | float | Debug speed display |
GetEffectiveDamage | float | Show effective damage |
GetThreat (Source) | float | Threat meter per player |
GetHighestThreatTarget | Actor | Who has aggro |
GetThreatTableSize | int | How many targets tracked |
IsServer | bool | Multiplayer authority check |
Core Systems
Health System
Enable: bUseHealthSystem = true (on by default)
| Property | Default | Description |
|---|---|---|
MaxHealth | 100.0 | Maximum HP |
CurrentHealth | 100.0 | Current HP (read-only, replicated in multiplayer) |
HealthRegenRate | 0.0 | HP per second (0 = no regen) |
HealthRegenDelay | 3.0 | Seconds after damage before regen starts |
Detection & Field of View
| Property | Default | Description |
|---|---|---|
DetectionRadius | 1500.0 | How far AI can see (cm) |
PlayerTag | "Player" | Tag on players the AI looks for |
DetectionInterval | 0.5 | Seconds between detection checks |
bRequireLineOfSight | false | Needs clear line to target? |
FieldOfView | 0.0 | View angle (0 = 360°, 90 = forward cone, 180 = front half) |
Movement
| Property | Default | Description |
|---|---|---|
PatrolSpeed | 200.0 | Speed when patrolling (cm/s) |
ChaseSpeed | 400.0 | Speed when chasing (cm/s) |
RotationSpeed | 5.0 | How fast the AI turns |
AcceptanceRadius | 100.0 | How close = "reached target" (cm) |
bStickToGround | true | Keep AI on ground with raycasts |
ObstacleCheckDistance | 150.0 | Obstacle avoidance look-ahead (cm) |
Behavior Modes
Set BehaviorMode to choose idle behavior:
| Mode | Behavior |
|---|---|
| Idle | Stands still. Waits for player. |
| Wanderer | Walks to random points within WanderRadius. Pauses if bPauseWhileWandering is on. Interval: WanderInterval. Pause: WanderPauseDuration. |
| Spline Patrol | Follows PatrolSpline component. Loops (bLoopPatrol) or ping-pongs. Waits PatrolWaitTime at each point. |
Basic Combat
| Property | Default | Description |
|---|---|---|
AttackRange | 200.0 | Distance to start attacking (cm) |
AttackCooldown | 2.0 | Seconds between attacks |
BaseDamage | 20.0 | Base damage per attack |
bStopOnAttack | true | Stop moving while attacking |
GiveUpDistance | 0.0 | Stop chasing if player this far (0 = never) |
Animations & Sounds
Assign in the Details panel. All optional — AI works without them.
| Slot | When It Plays |
|---|---|
AttackMontage / AttackSound | Basic attack (non Souls-like) |
PlayerFoundMontage / DetectionSound | First time AI spots player |
DeathMontage / DeathSound | AI dies |
StunnedMontage | AI gets stunned |
FleeMontage / FleeSound | AI starts fleeing |
InvestigateMontage | AI investigates a noise |
EnragedSound | AI enters Enraged state |
EncounterMontage / EncounterSound | Scripted encounter triggers |
DestroyDelay (default: 5.0) — seconds before actor is destroyed after death.
Debug Visualization
| Property | Default | Description |
|---|---|---|
bShowDebug | true | Show spheres/lines in editor |
bShowDebugInGame | false | Also show during Play In Editor |
bShowEmotionDebug | true | Show emotion text above AI |
Souls-like Combat
Enable: bUseSoulsLikeCombat = true
Every attack goes through 3 phases:
- Windup — telegraph, player can see it coming. Parry window active during first
ParryWindowseconds. - Active — damage lands. On Attack Started fires here.
- Recovery — AI is vulnerable, player can counter-attack.
Attack Definition (Attacks Array)
Add entries to Attacks. Each entry is an FMonsterAttack:
| Property | Default | Description |
|---|---|---|
AttackName | "BasicAttack" | Name for debugging |
WindupTime | 0.5 | Telegraph duration (seconds) |
ActiveTime | 0.3 | Damage window (seconds) |
RecoveryTime | 0.8 | Vulnerability window (seconds) |
Damage | 20.0 | Damage of this attack |
Range | 200.0 | Attack reach (cm) |
AttackMontage | none | Animation for this attack |
WindupSound | none | Sound during telegraph |
AttackSound | none | Sound on hit |
bCanBeParried | true | Can player parry this? |
SelectionWeight | 1.0 | Higher = AI uses this more often |
Parry Settings
| Property | Default | Description |
|---|---|---|
ParryWindow | 0.3 | How long player can parry (seconds) |
ParryStunDuration | 2.0 | How long AI is stunned after parry |
Visual Indicators
| Property | Default | Description |
|---|---|---|
bShowAttackIndicator | true | Show debug circles during attacks |
WindupIndicatorColor | orange (1, 0.5, 0, 0.5) | Circle color during windup |
AttackIndicatorColor | red (1, 0, 0, 0.7) | Circle color during active attack |
Emotional AI
Enable: bUseEmotionalAI = true
| Emotion | Trigger | Effect |
|---|---|---|
| Calm | Default | Normal behavior |
| Curious | Heard a noise | Investigates cautiously |
| Aggressive | Sees a player | Chases and attacks |
| Frightened | HP below threshold | Runs away, speed × FrightenedSpeedMultiplier |
| Enraged | Ally died nearby | Damage/speed/defense multiplied |
Settings
| Property | Default | Description |
|---|---|---|
FrightenedHealthThreshold | 0.25 | HP % to trigger fear |
FrightenedSpeedMultiplier | 1.5 | Speed boost when fleeing |
EnragedDamageMultiplier | 1.5 | +50% damage |
EnragedSpeedMultiplier | 1.3 | +30% speed |
EnragedDefenseMultiplier | 0.8 | Takes 20% more damage |
EnragedDuration | 15.0 | Rage duration (0 = ends naturally) |
bFleeWhenFrightened | true | AI runs when Frightened |
bEnrageOnAllyDeath | true | Enrage when ally dies |
AllyDeathDetectionRadius | 1000.0 | Range to detect ally death (cm) |
Hearing & Stealth
Enable: bUseHearingSystem = true
| Property | Default | Description |
|---|---|---|
HearingRadius | 2000.0 | Max hearing distance (cm) |
HearingSensitivity | 1.0 | Hearing multiplier |
SprintNoiseRadius | 1500.0 | How loud sprinting is (cm) |
WalkNoiseRadius | 500.0 | How loud walking is |
CrouchNoiseRadius | 100.0 | How loud crouching is |
InvestigateTime | 5.0 | How long AI searches (seconds) |
InvestigateSpeed | 150.0 | Speed when investigating (cm/s) |
Reporting Custom Sounds
Call Report Noise from any Blueprint:
Report Noise
Noise Location : FVector — where the sound came from
Loudness : float — 0.0-1.0+ multiplier (default: 1.0)
Noise Type : EMonsterNoiseType — Footstep, Gunshot, Explosion, Voice, Impact, Custom
Noise Instigator : Actor — who made the noise (optional)
Threat / Aggro System NEW v2.1
Enable: bUseThreatSystem = true
Every player in range builds threat. AI focuses whoever has the most. Threat decays when a target leaves range.
Settings
| Property | Default | Description |
|---|---|---|
ThreatPerDamage | 1.0 | Threat per 1 damage dealt to AI |
PassiveThreatPerSecond | 0.5 | Threat/sec just for being in range |
ThreatDecayRate | 2.0 | Threat lost/sec when out of range |
ThreatSwitchThreshold | 20.0 | Extra threat needed to switch targets (prevents flickering) |
HealThreatMultiplier | 0.5 | Threat per 1 HP healed |
DefaultTauntDuration | 5.0 | Taunt length when Duration=0 |
Threat Functions
| Function | Type | Description |
|---|---|---|
AddThreat (Source, Amount) | Callable | Add threat from an actor |
ClearThreat (Source) | Callable | Remove all threat from one actor |
ClearAllThreat | Callable | Reset entire threat table |
Taunt (Source, Duration) | Callable | Force AI to attack Source for Duration seconds |
GetThreat (Source) | Pure | Get current threat for an actor |
GetHighestThreatTarget | Pure | Get actor with most threat |
GetAllTargetsByThreat | Callable | Array sorted by threat (highest first) |
GetThreatTableSize | Pure | How many actors tracked |
ReportHealThreat (Healer, HealAmount) | Callable | Healer gains threat |
Multiplayer NEW v2.1
Enable: bEnableMultiplayer = true
AI logic runs on the server only. Key state replicates to all clients automatically.
What Replicates
| Property | Client Event |
|---|---|
CurrentHealth | On Health Changed fires on clients |
CurrentState (EAIState) | On State Changed fires on clients |
CurrentEmotion | On Emotion Changed fires on clients |
Setup
- Enable
bEnableMultiplayeron the AI component - Enemy Character must have
bReplicates = true(Class Defaults → Replication) - Tag ALL player characters with
PlayerTag - Movement replication handled by UE's Character Movement Component — no extra work
Best combo: Enable both bUseThreatSystem and bEnableMultiplayer for full multiplayer AI with tank/healer/DPS dynamics.
Use Is Server (returns bool) to check authority in your own Blueprints.
Advanced Systems
Adaptive Difficulty
Enable: bUseAdaptiveDifficulty = true
AI adjusts speed and damage based on player performance.
| Property | Default | Description |
|---|---|---|
PlayerSkillRating | 1.0 | Current rating (read-only; 0.5=easy, 2.0=hard) |
MinSkillRating | 0.5 | Floor |
MaxSkillRating | 2.0 | Ceiling |
AdaptationRate | 0.1 | How fast it adjusts |
bAdaptSpeed | true | Adjust AI speed |
bAdaptDamage | true | Adjust AI damage |
bAdaptAccuracy | true | Adjust AI timing |
Call from your game logic: Report Player Death, Report Player Hit AI, Report AI Hit Player
Knowledge Sharing
Enable: bUseKnowledgeSharing = true
| Property | Default | Description |
|---|---|---|
KnowledgeSharingRadius | 1500.0 | Range for sharing (cm) |
KnowledgeRetentionTime | 10.0 | How long knowledge lasts (sec) |
AllyTag | "Monster" | Tag identifying allies |
All monsters must have the same AllyTag to share knowledge!
Scripted Encounters
Enable: bUseScriptedEncounter = true
| Property | Default | Description |
|---|---|---|
EncounterType | Normal | Normal / JumpScare / Dramatic / Ambush |
bWaitForTrigger | false | AI stays dormant until Trigger Encounter |
EncounterMontage | none | Animation on trigger |
EncounterSound | none | Sound on trigger |
EncounterDelay | 0.5 | Seconds between trigger and AI activation |
Day / Night Behavior
Enable: bUseTimeOfDayBehavior = true
| Property | Default | Night Effect |
|---|---|---|
NightDetectionMultiplier | 1.5 | +50% detection range |
NightAggressionMultiplier | 1.5 | +50% damage |
NightSpeedMultiplier | 1.2 | +20% speed |
Call Set Night Time (bool) from your day/night system. bIsNightTime is also directly writable.
All Blueprint Events
Bind in your enemy Blueprint Event Graph. Right-click → search the name.
| Event | Parameters | When It Fires |
|---|---|---|
| On Player Detected | — | Player entered detection range |
| On Player Lost | — | Player escaped detection |
| On Attack Windup Started | — | Souls-like telegraph began (parry window open) |
| On Attack Started | — | Attack executes — apply damage to player here! |
| On Death | — | AI died |
| On State Changed | NewState (EAIState) | Patrolling, Chasing, Attacking, Investigating, Fleeing, Stunned, Dead |
| On Emotion Changed | NewEmotion (EMonsterEmotion) | Calm, Curious, Aggressive, Frightened, Enraged |
| On Health Changed | NewHealth, MaxHealth (float) | HP changed (damage or heal) |
| On Damage Taken | DamageAmount (float) | AI took damage |
| On Noise Heard | NoiseLocation (FVector) | AI heard a sound |
| On Encounter Triggered | — | Scripted encounter activated |
| On Knowledge Received | PlayerLastKnownLocation (FVector) | Got player info from ally |
| On Target Changed | NewTarget, PreviousTarget (Actor) | AI switched targets (threat system) |
| On Threat Changed | ThreatSource (Actor), NewThreatValue (float) | Threat value updated |
All Blueprint Functions
AI Control
| Function | Description |
|---|---|
StartAI | Activate the AI |
StopAI | Deactivate the AI |
Die | Kill the AI (death anim, On Death event, destroy after delay) |
Health
| Function | Description |
|---|---|
TakeDamage (DamageAmount) | Apply damage |
Heal (HealAmount) | Restore health |
GetHealthPercent | Returns 0.0–1.0 |
Combat
| Function | Description |
|---|---|
ForceAttack | Attack now (ignores cooldown) |
Stun (Duration) | Stun AI for seconds |
TryParry | Attempt parry → bool (true = success) |
IsInParryWindow | Is parry currently possible? |
GetEffectiveChaseSpeed | Chase speed with all modifiers |
GetEffectiveDamage | Damage with all modifiers |
State & Info
| Function | Description |
|---|---|
GetCurrentState | EAIState |
GetCurrentEmotion | EMonsterEmotion |
GetDetectedPlayer | Current target Actor (or null) |
IsAIActive | Is AI running? |
SetEmotion (NewEmotion) | Force emotion change |
Threat / Aggro
| Function | Description |
|---|---|
AddThreat (Source, Amount) | Add threat from actor |
ClearThreat (Source) | Remove threat from one actor |
ClearAllThreat | Reset entire table |
Taunt (Source, Duration) | Force target (Duration=0 uses DefaultTauntDuration) |
GetThreat (Source) | Threat value for actor |
GetHighestThreatTarget | Top-threat actor |
GetAllTargetsByThreat | Sorted array (highest first) |
GetThreatTableSize | Number of tracked targets |
ReportHealThreat (Healer, HealAmount) | Healer generates threat |
Systems
| Function | Description |
|---|---|
ReportNoise (Location, Loudness, Type, Instigator) | Make AI hear a sound |
ShareKnowledge (PlayerLocation) | Share player position with allies |
ReceiveKnowledge (PlayerLocation, KnowledgeAge) | Receive from ally |
TriggerEncounter | Start scripted encounter |
SetNightTime (bNight) | Toggle night mode |
ReportPlayerDeath | Adaptive difficulty: player died |
ReportPlayerHitAI | Adaptive difficulty: player hit AI |
ReportAIHitPlayer | Adaptive difficulty: AI hit player |
IsServer | Running on server? (multiplayer) |
Troubleshooting
AI doesn't move
- Check
bAutoStartis enabled - Enemy must be a Character (with Character Movement Component), not a plain Actor
- Speeds (
PatrolSpeed,ChaseSpeed) must be greater than zero - Spline Patrol mode: assign a
PatrolSplinecomponent
AI doesn't detect player
#1 issue: Player missing Player tag. Player Blueprint → Class Defaults → Tags → add "Player".
- Check
DetectionRadiusis large enough - If using FOV: player must be in front of AI
- If using Line of Sight: nothing blocking the view
- Enable
bShowDebug+bShowDebugInGameto see detection sphere
AI doesn't attack
- Player must be within
AttackRange - Souls-like:
Attacksarray must have at least one entry - Check
AttackCooldown
Animations not playing
- Montages assigned in Details panel?
- Character has Animation Blueprint?
- Test montages manually first
Knowledge Sharing not working
- All monsters need same
AllyTag bUseKnowledgeSharingenabled on ALL monsters- Check
KnowledgeSharingRadius
Multiplayer: AI only works on host
- Enable
bEnableMultiplayer - Enemy Character:
bReplicates = true - AI logic is server-only by design — clients get replicated state
Performance tips
- Increase
DetectionIntervalto 1.0+ for many AI - Disable
bShowDebugin shipping builds - Disable unused systems (hearing, knowledge, emotional, etc.)