Unreal's Core Classes
Everything you make in Unreal is built from a handful of base classes: objects, actors, components, pawns, controllers, and widgets. This guide explains what each one is for, how they relate to each other, and — the question every new Unreal developer asks — which one you should derive from.
1. The Big Picture
Two relationships explain almost everything: inheritance (which class derives from which) and composition (which object owns or contains which at runtime). Beginners often confuse the two — an actor doesn't inherit its mesh, it owns a mesh component.
The inheritance tree
Class names link to their reference entries. Some intermediate classes are omitted for clarity.
Every class here ultimately derives from UObject. The three branches — actors, components, widgets — are the three kinds of thing you'll subclass 95% of the time.
How it fits together at runtime
A running game: the world owns actors, actors own components, and UI lives on the viewport — outside the world entirely.
The world owns actors; each actor owns a tree of components (one of them is the root and provides the actor's transform). The PlayerController possesses a pawn to drive it, and creates widgets that live on the viewport — a 2D layer with no world position.
Decoding the prefixes
Unreal class names carry a one-letter prefix that tells you what kind of type you're looking at. You'll see these everywhere, so learn them first:
| Prefix | Means | Examples |
|---|---|---|
| A | An Actor — can be placed or spawned in a level | AActor, APawn, ACharacter |
| U | A UObject that is not an actor | UObject, UActorComponent, UUserWidget |
| F | A plain struct or class — no reflection-managed lifetime, no GC | FVector, FRotator, FHitResult |
| E | An enum | EEndPlayReason, ECollisionChannel |
| I | An interface | IAbilitySystemInterface |
| T | A template | TArray, TMap, TObjectPtr |
| S | A low-level Slate UI widget (you'll rarely touch these directly) | SButton, SCompoundWidget |
2. Which Class Should I Derive From?
The single most common beginner question. Match what you're building to the left column:
| You want to build… | Derive from | Why |
|---|---|---|
| A thing with a position in the level — a pickup, door, projectile, trap | AActor | Actors are the unit of "stuff in the world": they can be placed, spawned, moved, and destroyed. |
| Reusable behaviour to bolt onto any actor — health, inventory, interaction | UActorComponent | One component class can be added to a character, a crate, and a turret. No transform, pure logic. |
| A part with its own position on an actor — a muzzle point, camera boom, attach socket | USceneComponent | Scene components add a transform and can be attached into the actor's component tree. |
| A new kind of visible / collidable part (rare) | UPrimitiveComponent | Adds rendering and collision. Usually you just use existing ones (static mesh, capsule) instead of subclassing. |
| Something a player or AI controls | APawn / ACharacter | Pawns can be possessed by a controller. Character adds walking, jumping, and networking for humanoids. |
| The "brain" driving a pawn | APlayerController / AAIController | Controllers hold intent (input or AI decisions) and survive when the pawn dies and respawns. |
| Match rules — scoring, win conditions, spawning players | AGameModeBase | One per match, server-only. See §7. |
| Pure data or logic with no world presence — save data, settings, an algorithm | UObject | Cheapest option: reflection, GC, and serialization without any actor overhead. |
| On-screen UI — HUD, menus, health bars | UUserWidget | Widgets live on the viewport, laid out by UMG, not placed in the world. |
3. UObject — the Base of Everything
UObject is the root of Unreal's managed object
system. Deriving from it (and tagging your class with UCLASS())
buys you four things plain C++ classes don't get:
- Reflection — the engine knows your class's properties and
functions at runtime. This is what makes the editor's Details panel, Blueprint access, and
serialization work. You opt fields in with
UPROPERTY()and functions withUFUNCTION(). - Garbage collection — you never
deletea UObject. The GC frees objects that are no longer referenced by anyUPROPERTY()pointer. - Serialization — properties save/load automatically with assets, levels, and (with SaveGame) save files.
- Networking support — property replication and RPCs are built on the same reflection data.
Creating UObjects
// NEVER: UMyData* Data = new UMyData(); — invisible to the GC, will crash or leak
// ALWAYS:
UMyData* Data = NewObject<UMyData>(this); // 'this' becomes the Outer (owner)
// And keep a UPROPERTY reference so the GC knows it's still in use:
UPROPERTY()
TObjectPtr<UMyData> MyData; UMyData* member
without UPROPERTY() is invisible to the garbage collector — the object can be
destroyed while you still hold the pointer, giving you crashes that appear random.
This is one of the most common sources of mystery crashes in UE projects.
The Class Default Object (CDO)
At startup the engine constructs one instance of every UCLASS — the Class Default Object — as the template for all future instances. Your C++ constructor runs on the CDO, long before any level exists. That's why constructors must only set defaults and create default subobjects, never touch the world. (More in the Execution Order guide.)
What a plain UObject can't do
- No transform — it has no position, rotation, or scale
- Can't be placed in a level or spawned into the world
- Doesn't tick by default (actors and components do)
GetWorld()returns null unless its Outer chain leads to something in a world
If you find yourself needing any of those, you want an actor or a component instead.
4. AActor — Things in the World
An AActor is anything that can exist in a level: placed by hand in the editor, or spawned at runtime. Actors are the unit of gameplay — they tick, they can be replicated over the network, and they own components.
GetActorLocation() just forwards
to RootComponent.
Spawning and destroying
// Spawn at runtime (from any actor or component):
FActorSpawnParameters Params;
Params.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
AMyProjectile* Proj = GetWorld()->SpawnActor<AMyProjectile>(
ProjectileClass, MuzzleLocation, MuzzleRotation, Params);
// Remove from the world (GC frees the memory later):
Proj->Destroy();
Every actor runs through a fixed lifecycle: construction → registration →
BeginPlay → Tick every
frame → EndPlay → garbage collection. The
Execution Order guide covers every
step in detail — the short version: gameplay setup goes in
BeginPlay, cleanup goes in EndPlay,
and the constructor is only for defaults and default subobjects.
Actors and multiplayer
Replication is actor-centric: the server owns the authoritative copy of a replicated actor and pushes property changes to clients. If a thing needs to exist across the network, it's almost certainly an actor (components replicate as part of their owner).
5. Components — Behaviour You Compose
Components are how actors get their parts. There are three tiers, each adding one capability on top of the last:
| Class | Adds | Examples |
|---|---|---|
| UActorComponent | Ticking logic attached to an actor. No transform. | Health, inventory, ability systems, UCharacterMovementComponent |
| USceneComponent | A transform + attachment: can be a parent or child in the component tree | Spring arm (camera boom), arrow, attach points |
| UPrimitiveComponent | Geometry: rendering and/or collision | UStaticMeshComponent, skeletal meshes, capsules, box/sphere colliders |
The root component and the attach tree
Every actor placed in a world has exactly one root component (a scene component). The root's transform is the actor's transform; every other scene component attaches under it, moving with its parent like bones in a skeleton. Plain actor components (no transform) sit outside this tree — they're owned by the actor but not attached to anything.
Creating components
// In the constructor — the standard way to define an actor's parts:
AMyTurret::AMyTurret()
{
Base = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Base"));
SetRootComponent(Base);
Barrel = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Barrel"));
Barrel->SetupAttachment(Base); // child of the root
Health = CreateDefaultSubobject<UHealthComponent>(TEXT("Health"));
// no attachment — UActorComponent has no transform
}
// At runtime, on an already-spawned actor:
UHealthComponent* HC = NewObject<UHealthComponent>(SomeActor);
HC->RegisterComponent(); // required for runtime-added components ABaseEnemy → AArmoredEnemy → AFlyingArmoredEnemy, build enemies from
components: a health component, an armor component, a flying-movement component.
Deep actor hierarchies become rigid fast; components can be mixed freely and reused
on things you haven't invented yet.
6. Pawns, Characters & Controllers
Unreal splits "the player" into two objects: the body (a pawn in the world) and the brain (a controller that drives it). The link between them is called possession.
- APawn — an actor that can be possessed by a controller. Use it directly for vehicles, turrets, drones — anything controllable that doesn't walk like a person.
- ACharacter — a pawn with the humanoid kit pre-installed: a capsule for collision, a skeletal mesh for the body, and UCharacterMovementComponent for walking, jumping, falling, swimming — with client-server movement prediction built in. If your pawn is a person, start here.
- AController — the brain. APlayerController turns hardware input into pawn commands and owns the local player's camera; AAIController runs behavior trees instead of reading a gamepad.
Pawn or Character?
| Situation | Choose |
|---|---|
| Humanoid that walks, runs, jumps, crouches | ACharacter |
| Car, spaceship, drone, camera pawn, board-game piece | APawn + your own movement |
| Anything that's never possessed | AActor — it doesn't need to be a pawn at all |
Input bindings live in APawn::SetupPlayerInputComponent,
which runs when a player controller possesses the pawn. The exact sequence of possession
callbacks is in the
Execution Order guide §12.
7. The Gameplay Framework
Around your pawns and controllers, the engine spins up a standard cast of framework objects for every game session: AGameModeBase, AGameStateBase, APlayerController, APlayerState, UGameInstance, and the UWorld they all live in. You don't create these yourself — you subclass them and tell your project which subclasses to use.
This topic now has a guide of its own: what each class is for, who creates what, what replicates where, and why the whole design is multiplayer-first — see The Gameplay Framework guide.
8. Widgets — UI Outside the World
UI in Unreal is built from widgets, and widgets are not actors. They don't live in the world, have no world transform, and are laid out in 2D screen space by UMG (Unreal Motion Graphics). Under the hood UMG is a friendly wrapper over Slate, the engine's low-level C++ UI framework — you'll rarely need to touch Slate directly.
- UWidget — one control: a button, a text block, a progress bar, an image. These are the building blocks you drag into the UMG designer.
- UUserWidget — a composition of widgets: your HUD, your main menu, one row of your inventory grid. When you create a Widget Blueprint, you're subclassing UUserWidget. This is the class you derive from in C++ to add logic behind a designed widget.
Creating and showing a widget
// Typically from your PlayerController or HUD class:
UUserWidget* HUDWidget = CreateWidget<UUserWidget>(PlayerController, HUDWidgetClass);
HUDWidget->AddToViewport(); // now it renders on screen
HUDWidget->RemoveFromParent(); // hide/remove it again
Widgets have their own lifecycle (NativeConstruct /
NativeTick / NativeDestruct
rather than BeginPlay/Tick/EndPlay) and their own coordinate system. Positions are managed by
layout panels (canvas, vertical box, grid) rather than transforms — to connect a widget to
something in the world (a health bar over an enemy's head), you project the world position
into screen space each frame.
9. Common Gotchas
"I used new / delete on a UObject"
UObjects are owned by the garbage collector. Create them with
NewObject (or CreateDefaultSubobject
in constructors, SpawnActor for actors) and never call
delete — mark actors with Destroy()
and let the GC free the memory.
"My object pointer randomly became garbage"
A UObject pointer stored without UPROPERTY() is invisible
to the GC — the object gets collected while you still hold the pointer. Use
UPROPERTY() TObjectPtr<T> for owning references and
TWeakObjectPtr<T> for references that shouldn't keep
the object alive.
"I tried to spawn a component into the world"
Components aren't actors — they can't exist on their own. Spawn an actor that owns
the component, or add the component to an existing actor with
NewObject + RegisterComponent.
The reverse also trips people up: to stick one actor onto another, use
AttachToActor — the attached actor is still its own actor,
not a component.
"GetWorld() returns null in my UObject"
Plain UObjects don't know what world they're in — GetWorld()
works by walking the Outer chain, which for actors and components ends at a world. For your
own UObjects, create them with an actor as Outer, or pass a world context in explicitly.
"My widget needs a world position"
Widgets live in screen space; there's no GetActorLocation().
To pin UI to a world object, convert with
ProjectWorldLocationToScreen (or a WidgetComponent for
fully in-world UI). See the
coordinate spaces guide before
hand-rolling conversions.
"I put gameplay logic in the constructor"
Constructors run on the Class Default Object at engine startup — no world, no other actors,
no players. Constructors are for defaults and CreateDefaultSubobject
only; gameplay setup belongs in BeginPlay. The
Execution Order guide shows exactly
what's safe when.