How: Developed by Epic Games, first released in 1998 with the game Unreal. UE4 (2014) brought it to modern PBR/physically-based era. UE5 (2022) introduced Nanite and Lumen.
Who: Founded by Tim Sweeney. Epic Games continues active development.
Why: To push real-time graphics to cinematic quality — used in AAA games, films, archviz, automotive, and XR.
Introduction
Unreal Engine 5 is the industry-leading real-time 3D engine. It uses C++ for core gameplay and Blueprints (visual scripting) for rapid prototyping. UE5 features Nanite (virtualized geometry), Lumen (dynamic GI), and a full suite of tools for games, film, and simulation.
Advantages
Nanite — render billions of polygons with no LOD setup.
Lumen — fully dynamic global illumination and reflections.
Blueprint visual scripting — no C++ needed to prototype.
World Partition — seamless open-world streaming.
MetaHuman — photorealistic human characters.
Free to use — 5% royalty only after $1M revenue.
Source code available on GitHub.
Disadvantages
Very heavy — editor uses 8–16GB RAM, needs a powerful GPU.
Steep learning curve — massive feature set.
Compile times for C++ can be long.
Overkill for simple 2D or small indie games.
Editor & Project Setup
Editor Layout
Viewport — 3D scene view (perspective/orthographic)
Content Browser — All project assets (bottom panel)
Outliner — Scene hierarchy (top right)
Details Panel — Properties of selected actor (right)
Toolbar — Play, Build, Source Control buttons (top)
Modes Panel — Select, Landscape, Foliage, Mesh Paint modes
Viewport Navigation
RMB + WASD — Fly through scene
RMB + QE — Move up/down
Alt + LMB — Orbit around selection
Alt + RMB — Zoom
F — Focus on selected actor
G — Toggle game view (hide editor gizmos)
Ctrl + Space — Open Content Browser
Project Structure
/Content/ All game assets (textures, meshes, blueprints, maps)
/Source/ C++ source files
/Config/ Project settings (.ini files)
/Plugins/ Engine and project plugins
/Saved/ Logs, screenshots, autosaves
/Intermediate/ Compiled binaries (auto-generated)
Key files:
MyProject.uproject — Project descriptor
MyProject.sln — Visual Studio solution
Key Shortcuts
Ctrl+S Save current level
Ctrl+Z / Y Undo / Redo
W / E / R Translate / Rotate / Scale gizmo
Alt+drag Duplicate actor
End Snap actor to floor
P Toggle Play-in-Editor (PIE)
Ctrl+P Quick asset search (Content Browser)
Shift+F1 Release mouse during PIE
Core Concepts — Actors & Components
Actor
Actor — the base class for everything placed in a level.
Every object in the world (character, light, camera, trigger) is an Actor.
Lifecycle:
Constructor → object created (CDO — Class Default Object)
BeginPlay() → actor enters the game world
Tick(DeltaTime) → called every frame
EndPlay() → actor removed from world
Destroyed() → actor fully destroyed
Components
Components add functionality to Actors.
Common Components:
UStaticMeshComponent — renders a static 3D mesh
USkeletalMeshComponent — renders an animated mesh with skeleton
UCapsuleComponent — collision capsule (used for characters)
UBoxComponent — box collision
USphereComponent — sphere collision
UCharacterMovementComponent — handles character physics/movement
UCameraComponent — camera view
USpringArmComponent — camera boom (follows character)
UAudioComponent — plays audio
UPointLightComponent — point light
UParticleSystemComponent — particle effects (Cascade)
UNiagaraComponent — particle effects (Niagara, modern)
UWidgetComponent — 3D UI widget in world space
Blueprints are Unreal's node-based visual scripting system.
Every Blueprint is a class — it can extend any C++ class.
Types:
Blueprint Class — extends Actor, Character, etc. (most common)
Level Blueprint — per-level scripting (triggers, cinematics)
Blueprint Interface — define functions any Blueprint can implement
Blueprint Macro Library — reusable macro nodes
Blueprint Function Library — reusable static functions
Animation Blueprint — controls skeletal animation state machine
Blueprint Basics
Event Graph:
Event BeginPlay → executes once when game starts
Event Tick → executes every frame (has DeltaSeconds pin)
Event Hit → called on collision
Event Overlap → called on overlap begin/end
Nodes:
Function call — white exec pin (sequence)
Pure function — no exec pin (math, getters)
Variable get/set — blue (object ref), green (bool), red (float), etc.
Branch — if/else
Sequence — run multiple outputs in order
ForEach Loop — iterate array
Cast To — safe downcast (Cast To AMyCharacter)
Delay — wait N seconds then continue
Blueprint Communication
Direct Reference:
Get reference to actor → call function on it
Cast To:
Cast To APlayerCharacter → access player-specific functions
Event Dispatcher (like signals):
Define dispatcher → bind in other BP → call to broadcast
Blueprint Interface:
Define interface function → implement in any BP
Call without knowing exact type (polymorphism)
Game Instance:
Persistent data across levels (score, settings)
Blueprint vs C++
Blueprints:
+ Fast to prototype
+ Visual, designer-friendly
+ No compile step
- Slower execution than C++
- Hard to diff/merge in version control
- Gets messy at scale ("spaghetti blueprints")
C++:
+ Full performance
+ Better for complex logic, algorithms
+ Version control friendly
- Requires compile
- Steeper learning curve
Best practice: Core systems in C++, expose to Blueprint for designers.
C++ in Unreal Engine
UObject & Macros
// All Unreal classes use UCLASS, UPROPERTY, UFUNCTION macros// These enable reflection, serialization, Blueprint exposure, GCUCLASS()class MYGAME_API AMyActor : public AActor{ GENERATED_BODY()public: AMyActor(); // Exposed to Blueprint and editor UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Stats") float Health = 100.f; UPROPERTY(VisibleAnywhere, BlueprintReadOnly) UStaticMeshComponent* Mesh; // Callable from Blueprint UFUNCTION(BlueprintCallable, Category = "Combat") void TakeDamage(float Amount); // Implementable in Blueprint UFUNCTION(BlueprintImplementableEvent) void OnDeath(); // C++ default, overridable in Blueprint UFUNCTION(BlueprintNativeEvent) void OnHit(); virtual void OnHit_Implementation();protected: virtual void BeginPlay() override; virtual void Tick(float DeltaTime) override;};
UPROPERTY Specifiers
UPROPERTY(EditAnywhere) // editable in editor (instance + CDO)UPROPERTY(EditDefaultsOnly) // editable only in Blueprint defaultsUPROPERTY(EditInstanceOnly) // editable only on placed instancesUPROPERTY(VisibleAnywhere) // visible but not editableUPROPERTY(BlueprintReadWrite) // read + write from BlueprintUPROPERTY(BlueprintReadOnly) // read only from BlueprintUPROPERTY(Replicated) // synced over networkUPROPERTY(ReplicatedUsing=OnRep_Health) // replicated with callbackUPROPERTY(Transient) // not saved to diskUPROPERTY(SaveGame) // included in save game serializationUPROPERTY(Category = "Combat") // organizes in Details panelUPROPERTY(meta = (ClampMin = "0", ClampMax = "100"))
UFUNCTION Specifiers
UFUNCTION(BlueprintCallable) // callable from BlueprintUFUNCTION(BlueprintPure) // no exec pin, no side effectsUFUNCTION(BlueprintImplementableEvent) // implemented in BlueprintUFUNCTION(BlueprintNativeEvent) // C++ default + Blueprint overrideUFUNCTION(Server, Reliable) // runs on server (RPC)UFUNCTION(Client, Reliable) // runs on owning client (RPC)UFUNCTION(NetMulticast, Unreliable) // runs on all clientsUFUNCTION(Exec) // console commandUFUNCTION(CallInEditor) // button in editor Details panel
APawn — Any actor that can be possessed/controlled
ACharacter — Pawn with mesh, capsule, movement component
APlayerController — Translates player input → Pawn actions
AAIController — Controls AI Pawns
AGameModeBase — Rules of the game (win/lose, spawn, teams)
AGameStateBase — Replicated game state (score, timer)
APlayerState — Per-player replicated state (name, score)
UGameInstance — Persistent across levels (settings, session)
AHUD — Heads-up display (legacy, prefer UMG)
APlayerCameraManager — Controls camera behavior
// Declare delegate typeDECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnHealthChanged, float, NewHealth);// In class:UPROPERTY(BlueprintAssignable)FOnHealthChanged OnHealthChanged;// Broadcast (fire event)OnHealthChanged.Broadcast(Health);// Bind in C++OnHealthChanged.AddDynamic(this, &AMyHUD::UpdateHealthBar);// Bind in Blueprint: assign to OnHealthChanged event// Single-cast delegate (not multicast)DECLARE_DELEGATE_OneParam(FOnDeath, AActor*);FOnDeath OnDeath;OnDeath.BindUObject(this, &AMyActor::HandleDeath);OnDeath.ExecuteIfBound(this);
Casting & Type Checking
// Cast (returns nullptr if wrong type)AMyCharacter* Player = Cast<AMyCharacter>(OtherActor);if (Player){ Player->TakeDamage(25.f);}// IsA — type check without castif (OtherActor->IsA<AEnemy>()){ // it's an enemy}// GetClassUE_LOG(LogTemp, Log, TEXT("Class: %s"), *OtherActor->GetClass()->GetName());
// In constructor — enable overlapTriggerBox->SetGenerateOverlapEvents(true);// Bind in BeginPlayTriggerBox->OnComponentBeginOverlap.AddDynamic(this, &AMyTrigger::OnOverlapBegin);TriggerBox->OnComponentEndOverlap.AddDynamic(this, &AMyTrigger::OnOverlapEnd);void AMyTrigger::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult){ if (AMyCharacter* Player = Cast<AMyCharacter>(OtherActor)) { Player->EnterZone(this); }}
Physics Bodies
// Enable physics simulation on meshMesh->SetSimulatePhysics(true);Mesh->SetEnableGravity(true);// Apply impulseMesh->AddImpulse(FVector(0, 0, 1000.f), NAME_None, true); // true = velocity change// Apply forceMesh->AddForce(FVector(500.f, 0, 0));// Set linear velocityMesh->SetPhysicsLinearVelocity(FVector(0, 0, 500.f));// Set massMesh->SetMassOverrideInKg(NAME_None, 50.f);
Animation System
Animation Blueprint
Animation Blueprint (ABP) controls skeletal mesh animation.
Two graphs:
Event Graph — logic (update variables: speed, is_jumping, etc.)
Anim Graph — state machine / blend tree (outputs final pose)
State Machine:
States: Idle, Walk, Run, Jump, Fall, Land
Transitions: conditions between states (Speed > 10 → Walk)
Blend Spaces:
1D BlendSpace — blend animations by one axis (speed: idle→walk→run)
2D BlendSpace — blend by two axes (speed + direction → strafe)
Anim Notifies
Anim Notify — event fired at a specific frame in an animation
Uses:
- Play footstep sound at foot-down frame
- Spawn projectile at attack frame
- Enable/disable collision during attack
In C++:
// Override in AnimInstance or listen via delegateUFUNCTION()void OnFootstep(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, FName NotifyName);
Inverse Kinematics (IK)
IK solves joint positions to reach a target.
Common uses:
Foot IK — feet conform to uneven terrain
Hand IK — hands grip weapons/objects correctly
Look At IK — head/eyes track a target
UE5 IK Rig + IK Retargeter:
- IK Rig: define IK chains and goals
- IK Retargeter: retarget animations between different skeletons
Control Rig:
- Procedural animation system
- Full-body IK, custom rigs, runtime deformation
UMG is Unreal's UI system — drag-and-drop widget designer.
Common Widgets:
Text Block — display text
Button — clickable button
Image — display texture/material
Progress Bar — health/loading bar
Slider — value slider
Check Box — toggle
Editable Text — text input
Canvas Panel — free-position layout
Vertical/Horizontal Box — stacked layout
Grid Panel — grid layout
Scroll Box — scrollable container
Overlay — stack widgets on top of each other
// In Widget Blueprint C++ classUCLASS()class UMyHUDWidget : public UUserWidget{ GENERATED_BODY()public: // Bind to widget in designer (must match widget name) UPROPERTY(meta = (BindWidget)) UProgressBar* HealthBar; UPROPERTY(meta = (BindWidget)) UTextBlock* ScoreText; // Optional bind (won't error if missing) UPROPERTY(meta = (BindWidgetOptional)) UButton* PauseButton; void UpdateHealth(float Percent) { HealthBar->SetPercent(Percent); } void UpdateScore(int32 Score) { ScoreText->SetText(FText::AsNumber(Score)); }};
Audio System
Sound Assets
Sound Wave — raw audio file (.wav, .ogg)
Sound Cue — node-based audio graph (randomize, loop, mix)
Sound Attenuation — defines 3D falloff, spatialization settings
Sound Class — volume group (Master, Music, SFX, Voice)
Sound Mix — adjust class volumes (e.g., duck music during dialogue)
MetaSound — UE5 procedural audio system (replaces Sound Cue)
Playing Audio
#include "Kismet/GameplayStatics.h"// Play at location (fire and forget)UGameplayStatics::PlaySoundAtLocation(this, JumpSound, GetActorLocation());// Play 2D (non-spatial, UI/music)UGameplayStatics::PlaySound2D(this, MenuMusic);// Spawn persistent audio componentUAudioComponent* AudioComp = UGameplayStatics::SpawnSoundAtLocation( this, FootstepSound, GetActorLocation());AudioComp->SetVolumeMultiplier(0.8f);AudioComp->SetPitchMultiplier(FMath::RandRange(0.9f, 1.1f));// StopAudioComp->Stop();// Attached audio component (follows actor)UAudioComponent* Comp = UGameplayStatics::SpawnSoundAttached( EngineSound, RootComponent);
AI System
Behavior Tree + Blackboard
Blackboard — shared data store for AI (key-value pairs)
Keys: TargetActor, PatrolPoint, IsAlerted, Health
Behavior Tree — hierarchical task graph
Selector — try children until one succeeds
Sequence — run children in order until one fails
Task — leaf node (Move To, Wait, Play Animation, custom)
Decorator — condition gate (Is Target Visible?, Has Ammo?)
Service — runs in background (update target location every 0.5s)
// Move to actorMoveToActor(TargetActor, 150.f); // 150 = acceptance radius// Move to locationMoveToLocation(TargetLocation);// Check if path existsUNavigationSystemV1* NavSys = UNavigationSystemV1::GetCurrent(GetWorld());FNavLocation Result;bool bFound = NavSys->GetRandomReachablePointInRadius( GetActorLocation(), 1000.f, Result);// NavMesh setup: place NavMeshBoundsVolume in level, press P to visualize
Multiplayer & Networking
Replication Basics
Unreal uses a Client-Server model.
Server is authoritative — owns game state.
Clients predict locally, server corrects.
Enable replication on Actor:
bReplicates = true; // replicate actor existence
SetReplicateMovement(true); // replicate transform
Replicate a variable:
UPROPERTY(Replicated)
float Health;
// Must implement GetLifetimeReplicatedProps:
void AMyActor::GetLifetimeReplicatedProps(
TArray<FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AMyActor, Health);
DOREPLIFETIME_CONDITION(AMyActor, Ammo, COND_OwnerOnly);
}
RepNotify
// Called on clients when variable changesUPROPERTY(ReplicatedUsing = OnRep_Health)float Health;UFUNCTION()void OnRep_Health(){ // Update health bar UI UpdateHealthBar(Health);}
RPCs (Remote Procedure Calls)
// Server RPC — client calls, runs on serverUFUNCTION(Server, Reliable, WithValidation)void ServerFire(FVector Direction);void AMyCharacter::ServerFire_Implementation(FVector Direction){ // Authoritative fire logic SpawnProjectile(Direction);}bool AMyCharacter::ServerFire_Validate(FVector Direction){ return Direction.IsNormalized(); // anti-cheat validation}// Multicast RPC — server calls, runs on all clientsUFUNCTION(NetMulticast, Unreliable)void MulticastPlayEffect(FVector Location);void AMyCharacter::MulticastPlayEffect_Implementation(FVector Location){ UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), HitEffect, Location);}// Client RPC — server calls, runs on owning client onlyUFUNCTION(Client, Reliable)void ClientShowMessage(const FString& Message);
Network Roles
// Check where code is runningHasAuthority() // true on serverIsLocallyControlled() // true on owning clientGetLocalRole() == ROLE_Authority // serverGetLocalRole() == ROLE_AutonomousProxy // owning clientGetLocalRole() == ROLE_SimulatedProxy // other clients// Common patternif (HasAuthority()){ // Server-only logic (damage, scoring, spawning)}
Rendering — UE5 Features
Nanite (Virtualized Geometry)
Nanite renders micro-polygon geometry — billions of triangles with no LOD setup.
How it works:
- Meshes stored as hierarchical clusters
- GPU selects which clusters to render based on screen size
- Only pixels that matter are shaded
- Effectively unlimited polygon count
Enable: Static Mesh → Details → Nanite → Enable Nanite Support
Limitations:
- No deforming meshes (skeletal, cloth, particles)
- No translucency
- Requires DX12 / Vulkan
Lumen (Dynamic Global Illumination)
Lumen provides fully dynamic GI and reflections — no baking required.
How it works:
- Traces rays against Signed Distance Fields (SDF) of meshes
- Screen traces for near-field detail
- Hardware ray tracing optional for higher quality
Enable: Project Settings → Rendering → Global Illumination → Lumen
Quality modes:
Software Lumen — runs on any DX11+ GPU
Hardware Lumen — requires RTX/RDNA2, higher quality reflections
Virtual Shadow Maps (VSM)
VSM replaces traditional shadow maps in UE5.
Features:
- Very high resolution (16k virtual resolution)
- Only renders shadow pages that are visible
- Works with Nanite geometry
- Supports many dynamic lights efficiently
Enable: Project Settings → Rendering → Shadows → Virtual Shadow Maps
Materials & Shaders
Material Editor — node-based shader graph
Key output pins:
Base Color — albedo texture/color
Metallic — 0 = dielectric, 1 = metal
Roughness — 0 = mirror, 1 = diffuse
Normal — normal map
Emissive — self-illumination (drives bloom)
Opacity — transparency (Blend Mode: Translucent)
Ambient Occlusion — baked AO texture
Material Domains:
Surface — standard 3D surface
Deferred Decal — projected onto surfaces
Light Function — modulate light shape
Post Process — full-screen effect
UI — for UMG widgets
Material Instances:
Child of a Material — override parameters without recompile
Dynamic Material Instance (MID) — change params at runtime
// Create dynamic material instance at runtimeUMaterialInstanceDynamic* MID = UMaterialInstanceDynamic::Create(BaseMaterial, this);Mesh->SetMaterial(0, MID);MID->SetScalarParameterValue(TEXT("Roughness"), 0.3f);MID->SetVectorParameterValue(TEXT("Color"), FLinearColor::Red);MID->SetTextureParameterValue(TEXT("Albedo"), MyTexture);
Niagara Particle System
Overview
Niagara is UE5's GPU particle system (replaces Cascade).
Structure:
System — top-level asset, contains emitters
Emitter — defines particle behavior
Module — reusable behavior block (spawn rate, velocity, color)
Emitter update stages:
Emitter Spawn — runs once when emitter starts
Emitter Update — runs every frame
Particle Spawn — runs when each particle is born
Particle Update — runs every frame per particle
Render — how particles are drawn (sprite, mesh, ribbon)
Tags are hierarchical strings: "Status.Burning", "Ability.Jump", "Character.Dead"
Register in Project Settings → GameplayTags
Uses:
- Block abilities while stunned: block tag "Status.Stunned"
- Cancel abilities: cancel tag "Ability.Jump" cancels jump
- Trigger effects: GameplayCue.Explosion
- Query: HasMatchingGameplayTag, HasAllMatchingGameplayTags
World Building Tools
Landscape
Landscape — large outdoor terrain system
Workflow:
1. Create Landscape (Modes → Landscape → Manage → New)
2. Sculpt: raise, lower, smooth, flatten, erosion
3. Paint: layer materials (grass, rock, dirt, snow)
4. Foliage: scatter trees, rocks, grass automatically
Landscape Material:
- Layer blend node
- Each layer: albedo + normal + roughness
- Weight-painted in editor
Nanite Tessellation (UE5.1+):
- Displace landscape geometry at render time
- No pre-tessellation needed
World Partition (UE5 Open World)
World Partition replaces World Composition for large worlds.
Features:
- Automatic streaming — cells load/unload based on player position
- One persistent level — no manual sub-level management
- Data Layers — toggle content visibility (day/night, seasons)
- HLOD (Hierarchical LOD) — distant merged meshes
Setup:
World Settings → Enable World Partition
Set streaming distance per actor class
Stat commands (console ~ key):
stat fps — frame rate
stat unit — frame, game, draw, GPU times
stat game — gameplay tick times
stat scenerendering — draw calls, triangles
stat memory — memory usage
stat streaming — asset streaming info
Unreal Insights:
- Full frame profiler (CPU + GPU)
- Network profiling
- Memory tracking
Run: UnrealInsights.exe, launch game with -trace=cpu,gpu,memory
GPU Visualizer (Ctrl+Shift+,):
- Per-pass GPU timing breakdown
RenderDoc integration:
- Full GPU frame capture and analysis
Common Optimizations
Draw Calls:
- Merge static meshes (HLOD, Merge Actors tool)
- Use Instanced Static Mesh (ISM) for repeated objects
- Use Hierarchical ISM (HISM) for foliage
- Enable Nanite on high-poly static meshes
Tick:
- Disable tick on actors that don't need it
PrimaryActorTick.bCanEverTick = false;
- Reduce tick interval
PrimaryActorTick.TickInterval = 0.1f; // 10 times/sec
- Use timers instead of tick for infrequent updates
Memory:
- Stream assets (don't load everything upfront)
- Use Soft Object References for optional assets
- Pool frequently spawned actors
Shadows:
- Use Virtual Shadow Maps (VSM) — more efficient
- Limit dynamic shadow casters
- Use baked lightmaps for static geometry
Soft References & Async Loading
// Hard reference — loads immediately (avoid for large assets)UPROPERTY(EditDefaultsOnly)UTexture2D* Texture;// Soft reference — loads on demandUPROPERTY(EditDefaultsOnly)TSoftObjectPtr<UTexture2D> TextureSoft;// Async loadFStreamableManager& Streamable = UAssetManager::GetStreamableManager();Streamable.RequestAsyncLoad(TextureSoft.ToSoftObjectPath(), FStreamableDelegate::CreateUObject(this, &AMyActor::OnTextureLoaded));void AMyActor::OnTextureLoaded(){ UTexture2D* Tex = TextureSoft.Get(); Mesh->SetMaterial(0, CreateMaterialWithTexture(Tex));}
Useful Utilities & Helpers
UGameplayStatics
#include "Kismet/GameplayStatics.h"// Get playerAPlayerController* PC = UGameplayStatics::GetPlayerController(this, 0);APawn* Player = UGameplayStatics::GetPlayerPawn(this, 0);ACharacter* Char = UGameplayStatics::GetPlayerCharacter(this, 0);// Load levelUGameplayStatics::OpenLevel(this, FName("Level_02"));UGameplayStatics::OpenLevelBySoftObjectPtr(this, LevelRef);// Apply damageUGameplayStatics::ApplyDamage(TargetActor, 25.f, Controller, this, DamageType);UGameplayStatics::ApplyRadialDamage(this, 100.f, Center, 500.f, DamageType, {}, this, Controller);// Slow motionUGameplayStatics::SetGlobalTimeDilation(this, 0.2f);// Get all actors of classTArray<AActor*> Enemies;UGameplayStatics::GetAllActorsOfClass(GetWorld(), AEnemy::StaticClass(), Enemies);