[UE5] Blueprint Components: A Design Pattern for Reusing Features

Created: 2025-12-12Last updated: 2026-07-19

An illustrated guide to reusing features with custom Blueprint Components. Covers ActorComponent vs SceneComponent, a hands-on health Component you can attach to any Actor, and communication patterns that keep it dependency-free.

You want enemies, breakable crates, and fortress towers to all have health. Copy-pasting the same health logic into three Blueprints works, at least for now. But every time the spec changes, you have to fix all three places.

The solution is a custom Blueprint Component. Build the feature once as a plug-in part, a kind of cartridge, and you can slot it into any Actor. No inheritance required. This article covers how Components work, the design principles behind them, and how to build a health Component you can attach to any Actor.

A figure plugging a heart-labeled cartridge into differently shaped boxes, illustrating Component reuse

What You'll Learn

  • Blueprint Components are feature cartridges that distribute behavior without inheritance
  • When to use ActorComponent vs SceneComponent (does it need a position or not?)
  • Hands-on: build a health Component that works on both enemies and crates
  • The rule that protects reusability: "a Component never picks its host" (no casting, use Event Dispatchers)

Sponsored

What Is a Blueprint Component: A Feature Cartridge

Just as StaticMeshComponent gives an Actor its appearance and MovementComponent gives it motion (see Actor and Component basics), a Component is a part that plugs a feature into an Actor. And in UE, you can build these parts yourself in Blueprint.

Diagram of one Health Component being distributed to three different Actors: an enemy, a crate, and a tower, with no inheritance involved
ActorComponent
RoleThe entity placed in the worldA part that adds a feature to an Actor
Can exist aloneYesNo (always attached to an Actor)
How it's reusedInheritance (requires a parent-child relationship)Attachment (works between completely unrelated Actors)

The biggest strength is that you can give the same behavior to entirely different Actors that share no inheritance. An enemy character and a crate can't be parent and child, but a health Component slots into both. Zero copy-paste, and fixes happen in exactly one place.

Sponsored

Choosing the Parent Class: ActorComponent vs SceneComponent

When you create a custom Component, the first thing you pick is the parent class. There's only one question to ask: does it need a Transform (a position)?

ActorComponent as a brain with no position, SceneComponent as a part with a position. Logic only means Actor, needing a location means Scene
Parent ClassCharacteristicsExamples
ActorComponentNo Transform. A container for pure logicHealth management, inventory, state management
SceneComponentHas a Transform and can sit in the Actor's hierarchyCamera arms, effect spawn points, collision placement

Remember it this way: features that are just data and calculation, like health or inventory, go in an ActorComponent. Features where the location itself carries meaning, like a muzzle position, go in a SceneComponent.

Sponsored

Hands-On: Building a Health Component for Any Actor

The fastest way to understand this is to build one. Our subject is a health system. Enemies in an action game, breakable crates in an exploration game, fortresses in a tower defense: "take damage, break when it runs out" is a universal mechanic across every genre.

Step 1: Create the Component

Right-click in the Content Browser, choose Blueprint Class, pick ActorComponent as the parent class, and name it BP_HealthComponent. (Health is pure logic, so ActorComponent is the right choice.)

Step 2: Design the Contents

The structure of BP_HealthComponent: MaxHealth and CurrentHealth data, ApplyDamage called from outside, and OnDied announced to the outside, exposing only the inlet and the broadcast port
TypeNameRole
VariableMaxHealth (Float, Instance Editable)Maximum health. Instance Editable so each instance can differ
VariableCurrentHealth (Float)Current health
FunctionApplyDamage (input: DamageAmount)The inlet: accepts incoming damage
Event DispatcherOnHealthChanged (output: NewHealth)A broadcast port: announces health changes
Event DispatcherOnDiedA broadcast port: announces that health ran out

Fill health to the maximum on BeginPlay, and reduce it in ApplyDamage. That's the whole thing.

Event BeginPlay (inside BP_HealthComponent)
  → Set CurrentHealth (= MaxHealth)        ← full health on spawn

Function: ApplyDamage (input: DamageAmount / Float)
  → Set CurrentHealth
      = Clamp (Value: Subtract (A: CurrentHealth, B: DamageAmount), Min: 0.0, Max: MaxHealth)
  → Call OnHealthChanged (NewHealth: CurrentHealth)   ← broadcast on every change
  → Branch (Condition: CurrentHealth <= 0.0)
      True → Call OnDied                              ← broadcast only when health runs out

Here's what that looks like as a graph. Subtract and Clamp are pure calculation nodes with no execution pins, so they join in from below with data wires only.

Node graph of the ApplyDamage function, updating CurrentHealth through Subtract and Clamp, broadcasting OnHealthChanged, and broadcasting OnDied when health drops to zero or below

Clamp is there so HP never punches through into negative numbers. A UI health bar computes its fill ratio as CurrentHealth / MaxHealth, so a negative value makes the bar stretch in the wrong direction.

Step 3: Attach, Wire Up, and Play

  1. Attach it to the enemy: Open BP_Enemy and add BP_HealthComponent via "+ Add" in the Components panel. Set MaxHealth to 100 in the Details panel

  2. Write the reaction: Select the Component you just added, then click the "+" next to OnDied under Events in the Details panel. UE generates a pre-bound event in the Event Graph

    BP_Enemy Event Graph
    Event On Died (from BP_HealthComponent)
      → Print String ("Enemy defeated")
      → Destroy Actor (Target: self)
    

    The key point is that the host decides what dying actually means

  3. Attach it to the crate too: Repeat the same steps in BP_Crate. This time set MaxHealth to 30 and change only the OnDied reaction

    BP_Crate Event Graph
    Event On Died (from BP_HealthComponent)
      → Spawn System at Location (a Niagara debris effect)
      → Destroy Actor (Target: self)
    
  4. Call it from the attacker: The bullet or sword collision logic doesn't care who it hit

    On Component Begin Overlap (bullet Collision)
      → Get Component by Class (Target: Other Actor, Component Class: BP_HealthComponent)
      → Is Valid ?
          Valid → ApplyDamage (Target: the retrieved Component, DamageAmount: 25.0)
      → Destroy Actor (remove the bullet)
    
    Node graph from the bullet's Overlap, getting the health component with Get Component by Class, passing through Is Valid, and calling ApplyDamage

    Notice that Cast To BP_Enemy appears nowhere. The attacker only checks whether the target has a health component.

An enemy, a crate, and a tower all with health bars, with only the crate hit by a bullet losing health, showing that everything you attach the Component to becomes breakable

Hit Play and start attacking. The enemy breaks in 4 hits (100 ÷ 25) and the crate in 2 (30 ÷ 25, rounded up), each dying in its own way. Yet there's exactly one copy of the health logic in the entire project. Try adding a single node at the start of ApplyDamage that reduces damage by 10%. Enemies, crates, every Actor picks it up instantly. That's the payoff of Component-based design.

Two things to take away.

  • Expose only the inlet (functions) and the broadcast ports (Dispatchers): never let outsiders touch the internal variables directly. That discipline is what keeps the Component reusable
  • The host is free to decide what dying means: the Component just announces "I died." Whether that means exploding or dropping loot is up to the receiver. That division of labor is the topic of the next section
Sponsored

Component Communication Patterns: Designing Host-Agnostic Parts

There's one rule that makes a Component genuinely reusable: it must not know who its Owner is.

Casting from Get Owner locks a Component to a specific Actor, while an Event Dispatcher broadcast can be received by anyone, keeping the Component host-agnostic
  • Component → Owner: broadcast with an Event Dispatcher, like OnDied. The Owner binds to it and implements whatever reaction suits it (death animation, item drop)
  • Owner → Component: calling functions directly is fine (ApplyDamage and friends). Commanding a part is always allowed
  • Component → external systems: when you don't want to depend on the other side's type, send a generic message via a Blueprint Interface (see the Blueprint Interface article)

What you must never do is Get OwnerCast to a specific class inside the Component.

Bad example (inside a Component)
Get Owner → Cast To BP_PlayerCharacter → call a player-specific function

The moment you do that, your Component is demoted to a BP_PlayerCharacter-only part. Attach it to a crate and the Cast fails, so nothing works. While designing, keep asking yourself: "would this Component still work if I attached it to a person, a box, or a tower?"

Bonus: Good to Know for Later

  • Components have Tick too: custom Components have Tick enabled by default. If you don't need per-frame processing, turn off Start with Tick Enabled in Class Defaults (see designing without Event Tick)
  • Built-in Components work the same way: the engine ships plenty of handy parts, like RotatingMovementComponent (attach it and things rotate) and ProjectileMovementComponent (attach it and things fly along a trajectory). Get in the habit of searching for an existing solution before building your own
  • Unbinding Dispatchers: if an object that outlives the Owner is bound, failing to Unbind on destruction leads to calls into null references. The standard pattern of "the Owner binds to its own Component" is safe because their lifetimes match

Summary

Key PointDetails
What a Component really isA feature cartridge. It distributes the same behavior to unrelated Actors without inheritance
Picking the parent classLogic only → ActorComponent. Needs a position → SceneComponent
The design ruleNever pick your host. Expose only the inlet (functions) and broadcast ports (Event Dispatchers), and never Cast
Where it appliesHealth, inventory, interaction checks, special movement: any feature shared by multiple Actors

After health, the next thing you'll want to turn into a Component might be the notification mechanism itself. For serious use of Event Dispatchers, head to event-driven design with Event Dispatchers, and for the full picture of Actor-to-Actor communication, see three ways Actors communicate.

What logic in your project is currently copy-pasted in two or more places? That's the name of the next cartridge you should build.