Skip to main content

🎭 Working with Actors in Blueprints

Actors are the building blocks of every Unreal Engine levelβ€”from simple props to complex characters, from lights to sound emitters. Blueprints become truly powerful when they can create, find, communicate with, and destroy Actors dynamically at runtime. In this lesson, you'll learn to spawn enemies on demand, find nearby objects, pass information between Actors, and build systems where different game elements work together seamlessly. These skills are essential for creating dynamic, interactive games.

🎯 Learning Objectives

By the end of this lesson, you will be able to:

  • Spawn Actors dynamically at runtime using Blueprints
  • Destroy Actors and clean up resources properly
  • Get references to Actors in the level
  • Use casting to access Actor-specific functionality
  • Find all Actors of a specific class in the level
  • Implement Actor communication patterns effectively
  • Create spawner systems for enemies and objects
  • Understand Actor lifecycle and best practices

Estimated Time: 60-75 minutes

Prerequisites: Lesson 5.4 - Flow Control

πŸ“‘ In This Lesson

Why Dynamic Actor Management Matters

Imagine a wave-based shooter where enemies appear continuously, or an adventure game where treasure chests spawn loot when opened. You can't place every enemy or item by handβ€”you need to create and remove Actors dynamically during gameplay.

πŸ“– Key Concept

Dynamic Actor Management: The ability to create, find, modify, and destroy Actors at runtime through Blueprints rather than placing them manually in the editor. This is essential for creating responsive, replayable games where the world changes based on player actions and game state.

Static vs. Dynamic Actors

Static Actors (Placed in Editor)

Characteristics:

  • Placed manually in the level
  • Exist when level loads
  • Predictable locations
  • Easy to visualize and design

Examples:

  • Buildings and architecture
  • Fixed props and decorations
  • Lights and triggers
  • Quest NPCs in specific locations

Dynamic Actors (Spawned at Runtime)

Characteristics:

  • Created by Blueprints during gameplay
  • Appear/disappear as needed
  • Variable locations and quantities
  • Memory efficient (only exist when needed)

Examples:

  • Enemies spawned in waves
  • Projectiles (bullets, arrows)
  • Loot drops from defeated enemies
  • Particle effects and explosions

The Actor Lifecycle

flowchart TD
    A[Blueprint Calls Spawn Actor] --> B[Actor Created in Memory]
    B --> C[Construction Script Runs]
    C --> D[BeginPlay Event Fires]
    D --> E[Actor Exists in World]
    E --> F[Tick Events Fire Each Frame]
    F --> E
    E --> G[Destroy Actor Called]
    G --> H[EndPlay Event Fires]
    H --> I[Actor Removed from Memory]
    
    style A fill:#4CAF50,stroke:#2e7d32,color:#fff
    style B fill:#2196F3,stroke:#1565c0,color:#fff
    style C fill:#ff9800,stroke:#e65100,color:#fff
    style D fill:#9c27b0,stroke:#6a1b9a,color:#fff
    style E fill:#4CAF50,stroke:#2e7d32,color:#fff
    style F fill:#2196F3,stroke:#1565c0,color:#fff
    style G fill:#e74c3c,stroke:#c0392b,color:#fff
    style H fill:#ff9800,stroke:#e65100,color:#fff
    style I fill:#9e9e9e,stroke:#616161,color:#fff

Figure: Complete lifecycle of a dynamically spawned Actor from creation to destruction.

Common Use Cases

Use Case Description Example
Enemy Spawning Create enemies in waves or at spawn points Tower defense, wave shooters
Projectiles Spawn bullets, arrows, grenades when firing Any game with ranged combat
Loot Systems Drop items when containers open or enemies die RPGs, looter shooters
VFX & SFX Spawn particle effects and sound emitters Explosions, impacts, ambient effects
Procedural Content Generate level elements at runtime Procedural dungeons, random obstacles
Object Pooling Reuse Actors instead of constant spawn/destroy Particle systems, frequent spawns

Spawning Actors

The Spawn Actor from Class node creates a new Actor instance at runtime and places it in the world.

πŸ“– Definition

Spawn Actor: The process of instantiating a new Actor Blueprint during gameplay and placing it at a specified location and rotation in the world. The spawned Actor is fully functional and behaves exactly like one placed in the editor, but it only exists at runtime.

The Spawn Actor Node

Figure: Spawn Actor from Class node with all essential parameters.

Using Spawn Actor

  1. Right-click in Event Graph β†’ search "Spawn Actor from Class"
  2. Select the node
  3. Set the Class input: Choose which Blueprint to spawn
  4. Provide Spawn Transform: Where and how to orient it
  5. Set Collision Handling Override: What to do if location is blocked
  6. The node returns a reference to the spawned Actor

Essential Parameters

1. Class (Required)

The Blueprint class to instantiate. This must be an Actor-based Blueprint.

  • Click the dropdown to select from available Actor Blueprints
  • Can be set to a variable for dynamic spawning
  • Example: BP_Enemy, BP_Projectile, BP_Pickup

2. Spawn Transform (Required)

Defines where and how the Actor appears in the world.

  • Location: X, Y, Z coordinates in world space
  • Rotation: Pitch, Yaw, Roll orientation
  • Scale: Size multiplier (usually 1, 1, 1)

Common sources for Spawn Transform:

  • Get Actor Transform - Spawn at another Actor's location
  • Make Transform - Build custom transform from separate values
  • Get Socket Transform - Spawn at skeletal mesh socket
  • Manual values - Fixed world location

3. Collision Handling Override

Determines behavior when spawn location is blocked by collision:

Option Behavior
Default Use project settings
Always Spawn Spawn regardless of collision (may overlap)
Adjust If Necessary Move slightly to avoid collision
Don't Spawn Fail to spawn, return null reference

Basic Spawn Example

Event BeginPlay
  β†’ Get Actor Location (this spawner's position)
  β†’ Spawn Actor from Class:
      Class = BP_Enemy
      Spawn Transform = Actor Location (from above)
      Collision = Adjust If Necessary
  β†’ Print String: "Enemy spawned!"

Spawn at Multiple Locations

Use a For Loop to spawn multiple Actors:

Event: Spawn Wave
  β†’ For Loop (0 to 9)  // Spawn 10 enemies
      Loop Body:
        β†’ Get Random Point in Radius (Center, Radius=1000)
        β†’ Spawn Actor:
            Class = BP_Enemy
            Transform = Random Point + Ground Height
        β†’ Print: "Spawned enemy " + Loop Index

Storing the Spawned Actor Reference

The Spawn Actor node returns a reference to the newly created Actor. Always store this reference if you need to control the Actor later!

flowchart LR
    A[Spawn Actor] --> B[Returns Reference]
    B --> C[Store in Variable]
    C --> D[Use Later to Control Actor]
    
    B --> E[Don't Store]
    E --> F[Can't Access Later!]
    
    style A fill:#4CAF50,stroke:#2e7d32,color:#fff
    style B fill:#2196F3,stroke:#1565c0,color:#fff
    style C fill:#4CAF50,stroke:#2e7d32,color:#fff
    style D fill:#4CAF50,stroke:#2e7d32,color:#fff
    style E fill:#e74c3c,stroke:#c0392b,color:#fff
    style F fill:#e74c3c,stroke:#c0392b,color:#fff

Figure: Always store the returned Actor reference if you need to interact with it later.

Example: Store spawned enemy to control it:

Spawn Actor (BP_Enemy)
  β†’ Set Variable: SpawnedEnemy = Return Value
  
Later, in another event:
  β†’ Get SpawnedEnemy variable
  β†’ Call function on it: TakeDamage(50)

Common Spawning Patterns

Pattern 1: Spawn at Spawn Points

1. Place empty Actors in level as spawn points
2. Tag them "EnemySpawn"
3. Get All Actors of Class (TargetPoint)
4. Filter by tag
5. For each spawn point:
   β†’ Spawn enemy at that location

Pattern 2: Spawn on Timer

Event BeginPlay
  β†’ Set Timer by Event:
      Event = SpawnEnemy
      Time = 5.0 seconds
      Looping = True

Custom Event: SpawnEnemy
  β†’ Spawn Actor at random location

Pattern 3: Spawn with Custom Properties

Spawn Actor (BP_Enemy)
  β†’ Store reference
  β†’ Cast to BP_Enemy
  β†’ Set enemy properties:
      Health = 100
      Speed = 400
      Difficulty = Hard

βœ… Spawning Best Practices

  • Always check if spawn succeeded (reference not null)
  • Store references if you need to control Actors later
  • Use "Adjust If Necessary" collision handling for reliability
  • Avoid spawning in Event Tick (performance issue)
  • Consider object pooling for frequently spawned Actors
  • Clean up spawned Actors when no longer needed

Destroying Actors

What goes up must come downβ€”spawned Actors should be destroyed when no longer needed to free memory and maintain performance.

πŸ“– Definition

Destroy Actor: The process of removing an Actor from the world and cleaning up its memory. The Actor's EndPlay event fires, components are detached, and the Actor is marked for garbage collection. All references to the destroyed Actor become invalid.

The Destroy Actor Node

Destroy Actor Node Destroy Actor Target (Actor to destroy) Execution in β†’ Actor reference β†’ β†’ Continues after destroy What Happens When Actor is Destroyed: 1. EndPlay event fires on the Actor 2. Actor removed from world (no longer visible/interactive) 3. Memory freed (eventually by garbage collection) 4. All references to Actor become invalid

Figure: Destroy Actor node removes an Actor from the world permanently.

Destroying Actors: The Basics

To destroy an Actor:

  1. Right-click in Event Graph β†’ search "Destroy Actor"
  2. Connect execution flow to it
  3. Provide Target: The Actor to destroy
    • Self - Destroy this Blueprint
    • Variable reference - Destroy another Actor
    • Function return value - Destroy result of query

Common Destroy Patterns

Pattern 1: Self-Destruct

An Actor destroys itself (e.g., projectile hits wall):

Event: OnHit (projectile hits something)
  β†’ Spawn particle effect at impact
  β†’ Play sound at impact location
  β†’ Destroy Actor (Target = Self)

Pattern 2: Destroy After Delay

Automatically clean up after a set time:

Event BeginPlay
  β†’ Delay (5.0 seconds)
  β†’ Destroy Actor (Self)
  
// Useful for: temporary VFX, timed pickups, decals

Pattern 3: Destroy on Condition

Remove Actor when it's no longer needed:

Enemy Health reaches 0
  β†’ Play death animation
  β†’ Delay (2.0 seconds)  // Let animation play
  β†’ Spawn loot
  β†’ Destroy Actor (Self)

Pattern 4: Destroy Multiple Actors

Get All Actors of Class (BP_Enemy)
  β†’ ForEach Loop:
      β†’ Destroy Actor (Array Element)
      
// Clears all enemies from level

Destroy vs. Hide

Aspect Destroy Actor Set Actor Hidden
Visibility Removed completely Invisible but still exists
Collision All collision removed Collision still active (unless disabled separately)
Memory Freed (eventually) Still uses memory
Reversible ❌ Permanent βœ… Can unhide
Performance Better for permanent removal Better for temporary hiding
Use Case Dead enemies, used pickups, projectiles Temporary stealth, cutscenes, level streaming

⚠️ Important: Destroyed Actor References

After destroying an Actor, all references to it become invalid. Attempting to use them causes errors!

Always validate:

Get stored enemy reference
β†’ Branch (Is Valid?)
   True: Call function on enemy
   False: Do nothing (already destroyed)

Use the Is Valid node before accessing potentially destroyed Actors.

Getting References to Actors

To interact with an Actor, you need a reference to itβ€”a way to point to that specific Actor. There are multiple ways to get references.

πŸ“– Key Concept

Actor Reference: A variable that points to a specific Actor in the world, allowing you to access its properties, call its functions, and interact with it. Think of it like a contact in your phoneβ€”it's how you "reach" that Actor.

Five Ways to Get Actor References

flowchart TD
    A[Need Actor Reference?] --> B[Method 1: Self]
    A --> C[Method 2: Spawn Return]
    A --> D[Method 3: Overlap Event]
    A --> E[Method 4: Manual Selection]
    A --> F[Method 5: Search Functions]
    
    B --> B1[Use Self node
References this Blueprint] C --> C1[Store Spawn Actor return
References spawned Actor] D --> D1[Overlap/Hit provides Other Actor
References colliding Actor] E --> E1[Instance Editable variable
Assign in editor] F --> F1[Get Actor of Class
Get All Actors of Class
Get Overlapping Actors] style A fill:#667eea,stroke:#4527a0,color:#fff style B fill:#4CAF50,stroke:#2e7d32,color:#fff style C fill:#2196F3,stroke:#1565c0,color:#fff style D fill:#ff9800,stroke:#e65100,color:#fff style E fill:#9c27b0,stroke:#6a1b9a,color:#fff style F fill:#e74c3c,stroke:#c0392b,color:#fff style B1 fill:#e8f5e9,stroke:#4CAF50 style C1 fill:#e3f2fd,stroke:#2196F3 style D1 fill:#fff3e0,stroke:#ff9800 style E1 fill:#f3e5f5,stroke:#9c27b0 style F1 fill:#ffebee,stroke:#e74c3c

Figure: Five common methods for obtaining Actor references in Blueprints.

Method 1: Self Reference

The Self node references the Blueprint you're currently in.

  • Right-click β†’ "Get a reference to self"
  • Use when a Blueprint needs to reference itself
  • Example: Pass yourself to another Actor
Enemy Blueprint:
  OnBeginPlay
    β†’ Get Self
    β†’ Call function on GameMode: RegisterEnemy(Self)
    
// GameMode now has reference to this enemy

Method 2: Store Spawn Return Value

When you spawn an Actor, store the returned reference:

Create variable: SpawnedProjectile (Type: BP_Projectile)

Fire Weapon:
  β†’ Spawn Actor (BP_Projectile)
  β†’ Set SpawnedProjectile = Return Value
  
Later:
  β†’ Get SpawnedProjectile
  β†’ Call SetVelocity on it

Method 3: Collision Events Provide References

Overlap and Hit events automatically provide references to the other Actor:

Event: OnComponentBeginOverlap
  β†’ Other Actor (output pin) = the Actor that overlapped
  β†’ Use this reference directly
  
Example:
  OnOverlap
    β†’ Get Other Actor
    β†’ Cast to BP_Player
    β†’ If successful: Apply damage to player

Method 4: Manual Assignment (Instance Editable)

Create a variable and assign it manually in the editor:

  1. Create variable: DoorToOpen (Type: Actor or BP_Door)
  2. Check Instance Editable
  3. Place Blueprint in level
  4. Select it, find variable in Details panel
  5. Use eyedropper to select target Actor in level
Pressure Plate Blueprint:
  Variable: DoorToOpen (Instance Editable)
  
  OnOverlap:
    β†’ Get DoorToOpen
    β†’ Call Open() on it

Method 5: Search Functions

Find Actors dynamically using search functions:

Get Actor of Class

Finds the first Actor of a specific class:

Get Actor of Class (BP_Player)
  β†’ Returns first player Actor found
  β†’ Returns None if not found

Get All Actors of Class

Returns array of all Actors of a class (covered in detail next section)

Get Overlapping Actors

Gets all Actors currently overlapping a component:

Get Overlapping Actors (from collision component)
  β†’ Class Filter = BP_Enemy
  β†’ Returns array of overlapping enemies

βœ… Reference Best Practices

  • Validate references: Always use Is Valid before accessing
  • Store wisely: Cache frequently-used references (e.g., player)
  • Clear when done: Set to None when Actor is destroyed
  • Avoid searches in Tick: Finding Actors is expensive
  • Use appropriate method: Manual for design, search for dynamic

Casting Explained

Casting is how you tell Unreal "I know this generic Actor is actually a specific type, let me access its unique features."

πŸ“– Definition

Casting: The process of treating a generic Actor reference as a specific Blueprint type to access its unique variables and functions. It's like recognizing that a generic "person" is actually a "doctor" so you can ask medical questions. Casting either succeeds (it is that type) or fails (it's not).

Why Casting is Necessary

Many nodes return generic Actor references:

  • OnOverlap gives "Other Actor" (generic)
  • Get Actor of Class returns "Actor" (generic)
  • Spawn Actor returns "Actor" (generic)

But you need access to specific Blueprint's variables/functions!

Figure: Casting converts generic Actor reference to specific type with access to custom functionality.

How to Cast

  1. Have an Actor reference (from overlap, spawn, variable, etc.)
  2. Right-click β†’ search "Cast to [BlueprintName]"
  3. Connect the Actor reference to the Object input pin
  4. Use the two output execution pins:
    • Cast Succeeded: It IS that type (use the typed reference)
    • Cast Failed: It's NOT that type (handle appropriately)

Casting Example: Damage Only Players

Event: OnComponentBeginOverlap (explosion radius)
  β†’ Get Other Actor (generic Actor reference)
  β†’ Cast to BP_Player
     Cast Succeeded:
       β†’ Get "As BP Player" output (typed reference)
       β†’ Call TakeDamage(50) on player
     Cast Failed:
       β†’ Do nothing (wasn't a player)

When to Cast

Situation Need to Cast?
Overlap gives generic "Other Actor" βœ… Yes - Cast to specific type
Need to access custom variables/functions βœ… Yes - Cast to that Blueprint
Only using basic Actor functions (Location, Rotation) ❌ No - Generic Actor is fine
Variable already correct type ❌ No - Already specific
Using Interface functions ❌ No - Interface doesn't need casting

βœ… Casting Best Practices

  • Always handle Cast Failed: Don't leave it disconnected
  • Store cast results: Don't cast repeatedly if you need multiple accesses
  • Avoid casting in Tick: Performance costβ€”cache references in BeginPlay
  • Consider Interfaces: For flexible communication, interfaces are better than casting
  • Cast to parent classes: Cast to more general types when appropriate

Get All Actors of Class

Sometimes you need to find and interact with every Actor of a specific type in the levelβ€”all enemies, all pickups, all lights.

πŸ“– Definition

Get All Actors of Class: A function that searches the entire level and returns an array containing references to every Actor of the specified class. This is your "find all" toolβ€”powerful but expensive, so use wisely.

Using Get All Actors of Class

Get All Actors of Class Node Get All Actors of Class Actor Class Out Actors (Array of Actors) Returns Array of All Matching Actors in Level Enemy 1 Enemy 2 Enemy 3 Enemy 4 ...

Figure: Get All Actors of Class returns an array with references to every matching Actor.

Basic Usage

Get All Actors of Class
  Actor Class = BP_Enemy
  
Returns: Array of all BP_Enemy instances in level

Common Patterns with Get All Actors

Pattern 1: Damage All Enemies

Explosion Event:
  β†’ Get All Actors of Class (BP_Enemy)
  β†’ ForEach Loop:
      Array Element (each enemy):
        β†’ Get Distance between Explosion and Enemy
        β†’ Branch (Distance < ExplosionRadius)
           True: Call TakeDamage on enemy

Pattern 2: Count Specific Actors

Get All Actors of Class (BP_Collectible)
  β†’ Get array Length
  β†’ Display: "Collectibles remaining: " + Length

Pattern 3: Find Closest Actor

Get All Actors of Class (BP_Enemy)
  β†’ ForEach Loop:
      β†’ Get Distance between Player and Enemy
      β†’ Branch (Distance < ClosestDistance):
         True: 
           β†’ Set ClosestDistance = Distance
           β†’ Set ClosestEnemy = Enemy
  After loop:
    β†’ ClosestEnemy contains nearest enemy reference

Pattern 4: Modify All Actors

Night Mode Activated:
  β†’ Get All Actors of Class (PointLight)
  β†’ ForEach Loop:
      β†’ Set Light Intensity = 2.0
      β†’ Set Light Color = Blue

Performance Considerations

⚠️ Performance Warning

Get All Actors of Class is expensive! It searches the entire level every time called.

Do:

  • βœ… Call in BeginPlay or on player action
  • βœ… Cache results if needed frequently
  • βœ… Use for occasional queries

Don't:

  • ❌ Call in Event Tick (every frame)
  • ❌ Call multiple times for same purpose
  • ❌ Use for very large Actor counts (100s+)

Alternatives to Get All Actors

Alternative When to Use
Manual Array Register Actors as they spawn, keep your own list
Get Overlapping Actors Only need Actors in specific area
Sphere/Box Overlap Find Actors within radius
Tag System Get Actors with specific tag (still uses search)
Event Dispatcher Let Actors report to manager instead of searching

Actor Communication Patterns

Actors rarely work in isolationβ€”they need to talk to each other. Here are the most common patterns.

Pattern 1: Direct Reference Communication

When: You know exactly which Actors need to communicate
How: Store reference, call functions directly

flowchart LR
    A[Button] -->|Has Reference| B[Door]
    A -->|Calls Function| C[Open Door]
    
    style A fill:#2196F3,stroke:#1565c0,color:#fff
    style B fill:#4CAF50,stroke:#2e7d32,color:#fff
    style C fill:#ff9800,stroke:#e65100,color:#fff

Figure: Direct referenceβ€”Button stores Door reference, calls function.

BP_Button:
  Variable: DoorToOpen (Instance Editable, Type: BP_Door)
  
  OnInteract:
    β†’ Get DoorToOpen
    β†’ Call Open() function on door

Pattern 2: Overlap-Based Communication

When: Communication triggered by collision
How: Use overlap events, cast to specific type

BP_DamageZone:
  OnComponentBeginOverlap:
    β†’ Get Other Actor
    β†’ Cast to BP_Player
       Success: Call TakeDamage on player
       Failed: Ignore (not a player)

Pattern 3: Search and Communicate

When: Need to find and affect multiple Actors
How: Get All Actors, loop, communicate

BP_PowerupManager:
  OnPowerupActivated:
    β†’ Get All Actors of Class (BP_Enemy)
    β†’ ForEach Loop:
        β†’ Call SlowDown() on each enemy

Pattern 4: Manager/Registry Pattern

When: Many Actors need coordination
How: Actors register with central manager

BP_Enemy:
  BeginPlay:
    β†’ Get Actor of Class (BP_EnemyManager)
    β†’ Call RegisterEnemy(Self)
    
BP_EnemyManager:
  Variable: EnemyArray (Array of BP_Enemy)
  
  Function: RegisterEnemy(Enemy)
    β†’ Add Enemy to EnemyArray
  
  Function: GetAllEnemies()
    β†’ Return EnemyArray

Pattern 5: Interface Communication

When: Multiple different Actor types need same message
How: Create Blueprint Interface, implement in all types

BPI_Damageable Interface:
  Function: TakeDamage(Amount)
  
Implement in: BP_Player, BP_Enemy, BP_Crate
  
BP_Weapon:
  OnHit:
    β†’ Get Hit Actor
    β†’ Send interface message: TakeDamage(50)
    β†’ If Actor implements interface, it receives message
    β†’ If not, nothing happens (safe)

Choosing Communication Pattern

flowchart TD
    A{Know exact Actors?} -->|Yes| B[Direct Reference]
    A -->|No| C{Triggered by collision?}
    C -->|Yes| D[Overlap + Cast]
    C -->|No| E{Many same-type Actors?}
    E -->|Yes| F[Get All Actors + Loop]
    E -->|No| G{Different types, same message?}
    G -->|Yes| H[Interface]
    G -->|No| I[Manager/Registry Pattern]
    
    style B fill:#4CAF50,stroke:#2e7d32,color:#fff
    style D fill:#2196F3,stroke:#1565c0,color:#fff
    style F fill:#ff9800,stroke:#e65100,color:#fff
    style H fill:#9c27b0,stroke:#6a1b9a,color:#fff
    style I fill:#e74c3c,stroke:#c0392b,color:#fff

Figure: Decision tree for selecting appropriate Actor communication pattern.

πŸ‹οΈ Hands-On Exercise: Create a Spawner Blueprint

Build a complete enemy spawner system that demonstrates spawning, references, and Actor management.

Part 1: Create the Enemy Blueprint

  1. Create BP_SimpleEnemy (Actor)
  2. Add Static Mesh Component:
    • Use Cube or any mesh
    • Set Material to red color
  3. Add variables:
    • Health (Float) = 100.0
    • MoveSpeed (Float) = 200.0
  4. Event BeginPlay:
    • Print: "Enemy spawned!"
  5. Create function: TakeDamage
    • Input: DamageAmount (Float)
    • Subtract from Health
    • Branch: If Health <= 0
      • True: Print "Enemy died!" β†’ Destroy Actor (Self)
      • False: Print "Enemy took damage, health: " + Health

Part 2: Create the Spawner Blueprint

  1. Create BP_EnemySpawner (Actor)
  2. Add Billboard Component (makes it visible in editor)
  3. Add variables:
    • EnemyClass (Class Reference to Actor) = BP_SimpleEnemy
    • SpawnCount (Integer, Instance Editable) = 5
    • SpawnRadius (Float, Instance Editable) = 500.0
    • SpawnInterval (Float, Instance Editable) = 2.0
    • SpawnedEnemies (Array of BP_SimpleEnemy)
    • CurrentSpawnCount (Integer) = 0
  4. Event BeginPlay:
    Set Timer by Event:
      Event = SpawnSingleEnemy
      Time = SpawnInterval
      Looping = True
  5. Custom Event: SpawnSingleEnemy
    Branch: CurrentSpawnCount < SpawnCount
      True:
        β†’ Get Actor Location (spawner position)
        β†’ Get Random Point in Navigable Radius:
            Origin = Actor Location
            Radius = SpawnRadius
        β†’ Spawn Actor from Class:
            Class = EnemyClass
            Spawn Transform = Random Point
            Collision = Adjust If Necessary
        β†’ Store return value in variable: NewEnemy
        β†’ Add NewEnemy to SpawnedEnemies array
        β†’ Increment CurrentSpawnCount
        β†’ Print: "Spawned enemy " + CurrentSpawnCount + " of " + SpawnCount
      False:
        β†’ Clear Timer by Handle (stop spawning)

Part 3: Add Spawner Management

Add keyboard controls to the spawner:

  1. Input Event: Keyboard K (Kill All Enemies)
    Get SpawnedEnemies array
    β†’ ForEach Loop:
        β†’ Is Valid? (check if enemy still exists)
           True: Destroy Actor (Array Element)
    β†’ Clear SpawnedEnemies array
    β†’ Print: "All enemies destroyed!"
  2. Input Event: Keyboard D (Damage All Enemies)
    Get SpawnedEnemies array
    β†’ ForEach Loop:
        β†’ Is Valid? (check if enemy still exists)
           True: 
             β†’ Cast to BP_SimpleEnemy
                Success: Call TakeDamage(25)
  3. Input Event: Keyboard C (Count Living Enemies)
    Get All Actors of Class (BP_SimpleEnemy)
    β†’ Get array Length
    β†’ Print: "Living enemies: " + Length

Part 4: Test Your Spawner

  1. Place BP_EnemySpawner in level
  2. Set SpawnCount to 10 in Details panel
  3. Play game
  4. Watch enemies spawn every 2 seconds
  5. Press D to damage all enemies
  6. Press K to kill all enemies
  7. Press C to count living enemies
βœ… Checkpoint: What did you learn?

This exercise demonstrated:

  • Spawning: Used Spawn Actor with random locations
  • References: Stored spawned enemies in array
  • Timers: Used Set Timer for repeated spawning
  • Casting: Cast to BP_SimpleEnemy to call TakeDamage
  • Is Valid: Checked if references still valid before using
  • Get All Actors: Found all enemies for counting
  • ForEach Loops: Processed arrays of Actors
  • Destroying: Cleaned up Actors properly
You've built a production-ready spawner system!

Challenge: Advanced Spawner Features

  1. Wave System: After spawning all enemies, wait for them to die, then start next wave
  2. Spawn Points: Create multiple spawn locations, spawn at different points
  3. Enemy Variety: Add SpawnableClasses array, randomly pick which enemy to spawn
  4. Visual Feedback: Spawn particle effect at spawn location
  5. Manager Integration: Create BP_GameManager that tracks total enemies spawned/killed

Summary

Dynamic Actor management is fundamental to creating interactive, responsive games. You now know how to spawn, destroy, find, and communicate with Actors at runtime.

Key Takeaways

  • 🎭 Dynamic Actors are created/destroyed at runtime vs. static placement in editor
  • 🌟 Spawn Actor from Class creates new Actors with transform and collision handling
  • πŸ’₯ Destroy Actor removes Actors and frees memoryβ€”always validate references afterward
  • πŸ”— References are pointers to Actors obtained via Self, Spawn Return, Overlaps, Manual Assignment, or Search
  • 🎯 Casting converts generic Actor references to specific types to access custom functionality
  • πŸ” Get All Actors of Class finds every Actor of a typeβ€”powerful but expensive, avoid in Tick
  • πŸ’¬ Communication Patterns: Direct Reference, Overlap-Based, Search-Based, Manager/Registry, Interface
  • βœ… Best Practices: Store references, validate with Is Valid, avoid searches in Tick, handle Cast Failed, clean up properly

What's Next?

You've completed Module 5: Introduction to Blueprints! You've learned visual scripting fundamentals, variables, flow control, functions, and Actor management. The next module, Module 6: Player Interaction and Input, builds on this foundation by teaching you how to capture player input, control characters, detect collisions, and create interactive objects that respond to player actions.

βœ… Self-Check Quiz

Before moving on, make sure you can answer these questions:

  1. What's the difference between static Actors and dynamic Actors?
  2. What are the three essential parameters for Spawn Actor from Class?
  3. Why should you store the return value from Spawn Actor?
  4. What happens when you Destroy Actor? Can you use its reference afterward?
  5. Name three ways to get a reference to an Actor.
  6. What is casting and why is it necessary?
  7. Why should you avoid calling Get All Actors of Class in Event Tick?
  8. What are two alternatives to Get All Actors of Class?
πŸ“ Show Answers
  1. Static Actors are placed manually in the editor and exist when the level loads. Dynamic Actors are spawned at runtime via Blueprints and only exist when created.
  2. Class (which Blueprint to spawn), Spawn Transform (location/rotation), and Collision Handling Override (what to do if location blocked).
  3. To control the Actor laterβ€”without storing the reference, you can't access the spawned Actor to call functions or modify it.
  4. The Actor is removed from the world, EndPlay fires, and memory is freed. All references become invalidβ€”you must use Is Valid before accessing destroyed Actor references.
  5. Self node, Spawn Actor return value, Overlap events (Other Actor), Manual assignment (Instance Editable variables), Search functions (Get Actor of Class, Get All Actors of Class).
  6. Casting converts a generic Actor reference to a specific Blueprint type so you can access its unique variables and functions. It's necessary because many nodes return generic references but you need specific functionality.
  7. It searches the entire level every frame (60+ times per second), causing severe performance issues. Cache the result in BeginPlay instead.
  8. Manual array (register Actors as spawned), Manager/Registry pattern (Actors report to central manager), Get Overlapping Actors (for specific area), Sphere/Box Overlap (radius-based).