/ue-actor-component-architecture
Use this skill when working with Actor and component design in Unreal Engine. Triggers on: Actor, component, BeginPlay, Tick, SpawnActor, lifecycle, CreateDefaultSubobject, composition, EndPlay, PostInitializeComponents, UActorComponent, USceneComponent, UINTERFACE, attachment,
$ npx -y skills add quodsoler/unreal-engine-skills --skill ue-actor-component-architecture --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/ue-actor-component-architecture
Context preview
The summary Claude sees to decide when to auto-load this skill.
Use this skill when working with Actor and component design in Unreal Engine. Triggers on: Actor, component, BeginPlay, Tick, SpawnActor, lifecycle, CreateDefaultSubobject, composition, EndPlay, PostInitializeComponents, UActorComponent, USceneComponent, UINTERFACE, attachment,
SKILL.md
ue-actor-component-architecture.SKILL.mdname: ue-actor-component-architecture
description: "Use this skill when working with Actor and component design in Unreal Engine. Triggers on: Actor, component, BeginPlay, Tick, SpawnActor, lifecycle, CreateDefaultSubobject, composition, EndPlay, PostInitializeComponents, UActorComponent, USceneComponent, UINTERFACE, attachment, spawn, interface. See references/actor-lifecycle.md and references/component-types.md for detailed tables."
metadata:
version: 1.0.0
UE Actor-Component Architecture
You are an expert in Unreal Engine's Actor-Component architecture.
Project Context
Before responding, read `.agents/ue-project-context.md` for the project's subsystem inventory, coding conventions, and any existing actor hierarchies or component patterns. This tells you which base classes are established and what naming conventions apply.
Information Gathering
Clarify the developer's specific need before diving in:
- New actor from scratch, or adding behavior to an existing one?
- Logic-only (UActorComponent) or needs world position (USceneComponent)?
- Spawning requirement (deferred init, pooling, net-spawned)?
- Lifecycle bug (BeginPlay/Constructor confusion, component not initialized)?
- Cross-actor behavior via interfaces?
---
Core Architecture Mental Model
Unreal's Actor-Component system is **composition over inheritance**. An `AActor` is a container that owns components. Behavior, rendering, collision, and logic are all expressed through `UActorComponent` subclasses.
UObject
└── AActor (placeable/spawnable world entity)
└── owns N x UActorComponent (reusable behavior units)
└── USceneComponent (adds transform + attachment)
└── UPrimitiveComponent (adds collision + rendering)`AActor` is a full `UObject` — never `new`/`delete` an actor. Always use `SpawnActor` and `Destroy`.
---
Actor Lifecycle
Full event order and safety rules are in `references/actor-lifecycle.md`. Key sequence:
Constructor → CreateDefaultSubobject, tick config, default values
PostActorCreated → spawned actors only; before construction script
PostInitializeComponents → all components initialized; world accessible
BeginPlay → game running; full logic OK; components BeginPlay fires here
Tick(DeltaTime) → per-frame; each ticking component's TickComponent fires
EndPlay(EEndPlayReason) → cleanup; ClearAllTimers; call Super
Destroyed → pre-GC; avoid complex logic
Constructor vs BeginPlay
**Constructor** runs first on the **Class Default Object (CDO)** — an archetype used for default values. `GetWorld()` returns `nullptr` on the CDO. Never access the world or other actors in the constructor.
// CORRECT — constructor-time only
AMyActor::AMyActor()
{
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
SetRootComponent(MeshComp);
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.TickInterval = 0.1f;
}
// CORRECT — world-dependent code belongs in BeginPlay
void AMyActor::BeginPlay()
{
Super::BeginPlay(); // Required — always call Super
GetWorld()->SpawnActor<AProjectile>(...);
}PostInitializeComponents
Called before BeginPlay; components are initialized; world exists. Use it to bind delegates to own components.
void AMyCharacter::PostInitializeComponents()
{
Super::PostInitializeComponents();
HealthComponent->OnDeath.AddDynamic(this, &AMyCharacter::HandleDeath);
}EndPlay — reasons matter
| Reason | When | |---|---| | `Destroyed` | `Actor->Destroy()` called explicitly | | `LevelTransition` | Map change | | `EndPlayInEditor` | PIE session ended | | `RemovedFromWorld` | Level streaming unloaded the sublevel | | `Quit` | Application shutdown |
void AMyActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
GetWorld()->GetTimerManager().ClearAllTimersForObject(this);
Super::EndPlay(EndPlayReason);
}Network lifecycle note
**Replicated actors**: on clients, `BeginPlay` may fire before all replicated properties arrive. Use `OnRep_` callbacks for initialization that depends on replicated state. `PostNetReceive()` fires after each replication update (including the initial one); guard one-time setup inside it with a `bHasInitialized` flag. `PostNetInit` is not a standard `AActor` virtual and should not be used as a general init hook.
---
Component System
The three layers
| Class | Transform | Rendering/Collision | Use for | |---|---|---|---| | `UActorComponent` | No | No | Pure logic — health, inventory, AI data | | `USceneComponent` | Yes | No | Transform anchors, grouping, pivot points | | `UPrimitiveComponent` | Yes | Yes | Meshes, shapes, anything visible or collidable |
**Notable subclasses**: `UStaticMeshComponent`, `USkeletalMeshComponent`, shape primitives (`UCapsuleComponent`, `UBoxComponent`, `USphereComponent`), `UWidgetComponent` (3D UI in world space — requires `"UMG"` module), `USpringArmComponent` + `UCameraComponent`, `UChildActorComponent`. See `references/component-types.md`.
Component creation
**In the constructor** (for default components that appear in the Details panel):
AMyActor::AMyActor()
{
// CreateDefaultSubobject registers the component as a subobject —
// it is serialized with the actor and visible in Blueprint editors.
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
SetRootComponent(MeshComp);
ArrowComp = CreateDefaultSubobject<UArrowComponent>(TEXT("Arrow"));
ArrowComp->SetupAttachment(MeshComp); // Parent set here; no world needed
HealthComp = CreateDefaultSubobject<UHealthComponent>(TEXT("Health"));
// Logic-only components need no attachment
}**At runtime** (dynamic addition):
void AMyActor::AddLight()
{
// NewObject creates but does NOT register with the world
UPointLightRead more
name: ue-actor-component-architecture description: "Use this skill when working with Actor and component design in Unreal Engine. Triggers on: Actor, component, BeginPlay, Tick, SpawnActor, lifecycle, CreateDefaultSubobject, composition, EndPlay, PostInitializeComponents, UActorComponent, USceneComponent, UINTERFACE, attachment, spawn, interface. See references/actor-lifecycle.md and references/component-types.md for detailed tables." metadata: version: 1.0.0
UE Actor-Component Architecture
You are an expert in Unreal Engine's Actor-Component architecture.
Project Context
Before responding, read `.agents/ue-project-context.md` for the project's subsystem inventory, coding conventions, and any existing actor hierarchies or component patterns. This tells you which base classes are established and what naming conventions apply.
Information Gathering
Clarify the developer's specific need before diving in:
- New actor from scratch, or adding behavior to an existing one?
- Logic-only (UActorComponent) or needs world position (USceneComponent)?
- Spawning requirement (deferred init, pooling, net-spawned)?
- Lifecycle bug (BeginPlay/Constructor confusion, component not initialized)?
- Cross-actor behavior via interfaces?
---
Core Architecture Mental Model
Unreal's Actor-Component system is **composition over inheritance**. An `AActor` is a container that owns components. Behavior, rendering, collision, and logic are all expressed through `UActorComponent` subclasses.
UObject
└── AActor (placeable/spawnable world entity)
└── owns N x UActorComponent (reusable behavior units)
└── USceneComponent (adds transform + attachment)
└── UPrimitiveComponent (adds collision + rendering)`AActor` is a full `UObject` — never `new`/`delete` an actor. Always use `SpawnActor` and `Destroy`.
---
Actor Lifecycle
Full event order and safety rules are in `references/actor-lifecycle.md`. Key sequence:
Constructor → CreateDefaultSubobject, tick config, default values PostActorCreated → spawned actors only; before construction script PostInitializeComponents → all components initialized; world accessible BeginPlay → game running; full logic OK; components BeginPlay fires here Tick(DeltaTime) → per-frame; each ticking component's TickComponent fires EndPlay(EEndPlayReason) → cleanup; ClearAllTimers; call Super Destroyed → pre-GC; avoid complex logic
Constructor vs BeginPlay
**Constructor** runs first on the **Class Default Object (CDO)** — an archetype used for default values. `GetWorld()` returns `nullptr` on the CDO. Never access the world or other actors in the constructor.
// CORRECT — constructor-time only
AMyActor::AMyActor()
{
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
SetRootComponent(MeshComp);
PrimaryActorTick.bCanEverTick = true;
PrimaryActorTick.TickInterval = 0.1f;
}
// CORRECT — world-dependent code belongs in BeginPlay
void AMyActor::BeginPlay()
{
Super::BeginPlay(); // Required — always call Super
GetWorld()->SpawnActor<AProjectile>(...);
}PostInitializeComponents
Called before BeginPlay; components are initialized; world exists. Use it to bind delegates to own components.
void AMyCharacter::PostInitializeComponents()
{
Super::PostInitializeComponents();
HealthComponent->OnDeath.AddDynamic(this, &AMyCharacter::HandleDeath);
}EndPlay — reasons matter
| Reason | When | |---|---| | `Destroyed` | `Actor->Destroy()` called explicitly | | `LevelTransition` | Map change | | `EndPlayInEditor` | PIE session ended | | `RemovedFromWorld` | Level streaming unloaded the sublevel | | `Quit` | Application shutdown |
void AMyActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
GetWorld()->GetTimerManager().ClearAllTimersForObject(this);
Super::EndPlay(EndPlayReason);
}Network lifecycle note
**Replicated actors**: on clients, `BeginPlay` may fire before all replicated properties arrive. Use `OnRep_` callbacks for initialization that depends on replicated state. `PostNetReceive()` fires after each replication update (including the initial one); guard one-time setup inside it with a `bHasInitialized` flag. `PostNetInit` is not a standard `AActor` virtual and should not be used as a general init hook.
---
Component System
The three layers
| Class | Transform | Rendering/Collision | Use for | |---|---|---|---| | `UActorComponent` | No | No | Pure logic — health, inventory, AI data | | `USceneComponent` | Yes | No | Transform anchors, grouping, pivot points | | `UPrimitiveComponent` | Yes | Yes | Meshes, shapes, anything visible or collidable |
**Notable subclasses**: `UStaticMeshComponent`, `USkeletalMeshComponent`, shape primitives (`UCapsuleComponent`, `UBoxComponent`, `USphereComponent`), `UWidgetComponent` (3D UI in world space — requires `"UMG"` module), `USpringArmComponent` + `UCameraComponent`, `UChildActorComponent`. See `references/component-types.md`.
Component creation
**In the constructor** (for default components that appear in the Details panel):
AMyActor::AMyActor()
{
// CreateDefaultSubobject registers the component as a subobject —
// it is serialized with the actor and visible in Blueprint editors.
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
SetRootComponent(MeshComp);
ArrowComp = CreateDefaultSubobject<UArrowComponent>(TEXT("Arrow"));
ArrowComp->SetupAttachment(MeshComp); // Parent set here; no world needed
HealthComp = CreateDefaultSubobject<UHealthComponent>(TEXT("Health"));
// Logic-only components need no attachment
}**At runtime** (dynamic addition):
void AMyActor::AddLight()
{
// NewObject creates but does NOT register with the world
UPointLightA collection of 27 AI agent skills for Unreal Engine C++ development. Built for game developers who want AI coding agents to help write correct, production-quality UE5 C++ code.
Other skills on unreal-engine-skills.
- /ue-ai-navigation
Use this skill when implementing AI, AIController, behavior tree, blackboard, AI perception, NavMesh, EQS, navigation, pathfinding, State Tree, or Smart Objects in Unreal Engine. See references/behavior-tree-patterns.md for BT patterns and references/eqs-reference.md for EQS
Open skill - /ue-animation-system
Use this skill when working with Unreal Engine animation: AnimInstance, montage playback, blend space, state machine, anim notify, IK, AnimGraph, skeletal mesh, or linked anim graphs. See references/anim-notify-reference.md for notify patterns and references/locomotion-setup.md
Open skill - /ue-async-threading
Use this skill when working with Unreal Engine async operations, threading, parallel execution, or concurrency. Also use when the user mentions 'FRunnable', 'FAsyncTask', 'TaskGraph', 'UE::Tasks', 'ParallelFor', 'TFuture', 'TPromise', 'Async()', 'thread safety',
Open skill - /ue-audio-system
Use this skill when working with audio, sound, music, UAudioComponent, PlaySoundAtLocation, SoundCue, MetaSound, attenuation, submix, concurrency, SFX, or spatial audio in Unreal Engine. See references/audio-setup-patterns.md for music system and ambient soundscape
Open skill - /ue-character-movement
Use this skill when working with character movement, CharacterMovementComponent, CMC, movement modes, walking, falling, swimming, flying, custom movement, network prediction, FSavedMove, root motion, floor detection, step-up, or character physics. Also use for 'PhysWalking',
Open skill - /ue-cpp-foundations
Use when writing Unreal Engine C++ code involving UPROPERTY, UFUNCTION, UCLASS, TArray, TMap, delegates, FString, garbage collection, or smart pointers. Also use when the user asks about "UE C++", USTRUCT, UENUM, FName, FText, TObjectPtr, TWeakObjectPtr, UObject lifetime,
Open skill

