Every frame, your player sees the output of one logical camera — a single pose (position, rotation, FOV, projection, physical-lens parameters) applied to the viewport. ComposableCameraSystem produces that pose by running a layered pipeline. This page walks the layers from outermost to innermost.
The layered picture¶
evaluated"] end subgraph DIR["Director — one per context · owns the running camera"] direction TB subgraph ET["Evaluation Tree — Tier 2 · per-context blending"] direction TB Inner(["Inner: Transition"]) Inner --> LeafA["Leaf: CamA
(source)"] Inner --> LeafB["Leaf: CamB
(target / running)"] end end CS -.->|"each entry owns"| DIR end classDef pcm fill:#eef3ff,stroke:#4a69bb,stroke-width:1.5px; classDef stack fill:#fff4e6,stroke:#d97706; classDef tree fill:#e8f7ee,stroke:#0e9f6e; class PCM pcm; class CS stack; class ET tree;
Read it top-down:
- Player Camera Manager (PCM) sits where Unreal's
APlayerCameraManagerwould — it's a subclass (AComposableCameraPlayerCameraManager) that every interested PlayerController points at viaPlayerCameraManagerClass(see Enabling the Plugin). It owns everything below it and drives the per-frame loop. - Context Stack is a LIFO stack of named contexts (
Gameplay,Cutscene,UI, …). Only the top context is evaluated each frame. Pushing a new context suspends everything below without tearing it down. Context names are registered inUComposableCameraProjectSettings::ContextNames; the first entry is the base context and is initialized before any actor'sBeginPlay. See Context Stack. - Director is per-context. It owns an Evaluation Tree, tracks the currently-running camera, and remembers the last two evaluated poses — which transitions use for velocity calculations. See Evaluation Tree.
- Evaluation Tree is a binary tree of leaves (wrapping a Camera) and inner nodes (wrapping a Transition). Leaves produce poses; inner nodes blend two poses into one. See Evaluation Tree.
- Camera is an
AComposableCameraCameraBaseactor that owns an ordered array of Camera Nodes. It's data-driven: the actor is a container, not a subclass hierarchy. See Authoring Camera Types. - Camera Node is a single-responsibility operator. It reads the input pose, applies its logic, and writes an output pose. Nodes also talk to each other through a typed pin system routed by a flat
RuntimeDataBlock. See Node Catalog. - Transition is a pose-only blender. Each frame it receives two input poses (source and target) and outputs one blended pose. It never references the source/target cameras directly. See Transitions.
- Modifier targets a specific node class and overrides its parameters at runtime. Highest priority wins; changes may trigger a seamless camera reactivation. See Modifiers.
- Action is a lightweight, fire-and-forget behavior that hooks into the camera's pre- or post-tick. Actions don't transform the pose through the node chain — they run alongside it, with built-in expiration (instant, duration, manual, or condition-based). Camera-scoped actions auto-expire on camera switch; persistent ones survive. See Camera Actions.
What happens on one frame¶
Once per frame, AComposableCameraPlayerCameraManager::DoUpdateCamera(DeltaTime) drives this sequence:
Camera.TickCamera() → pose"] Walk --> Ref["RefLeaf
OtherDirector.Evaluate() → pose"] Walk --> In["Inner
blend(left, right) → pose"] Leaf --> Col["CollapseFinishedTransitions"] Ref --> Col In --> Col Col --> Upd["Update Last / Previous EvaluatedPose"] Upd --> Post["Update actions, running camera, current context"] Post --> Final["Convert pose → FMinimalViewInfo → viewport"]
The recursive tree walk is the heart of the system. A leaf produces a pose by ticking its camera (which itself walks its ordered node list). An inner node produces a pose by blending its two children. A reference leaf produces a pose by evaluating a different Director entirely — that's how a gameplay camera keeps animating live while a cutscene is blending in on top.
After the pose comes out, CollapseFinishedTransitions walks the tree one more time and promotes any inner node whose transition is done, so the tree stays small.
Where each subsystem is explained¶
- The LIFO, push/pop semantics, auto-pop for transient cameras, and inter-context resume → Context Stack.
- Tree shape, activation rewrites, reference leaves, the collapse rule → Evaluation Tree.
- Lifecycle (
TransitionEnabled → OnBeginPlay → OnEvaluate → OnFinished), velocity-aware inertialization, the five-tier resolution chain → Transitions. - Priority-per-node-class, reactivation with transition, the difference from UE's built-in
UCameraModifier→ Modifiers. - Temporary per-frame behaviors with built-in expiration, camera-scoped vs. persistent → Actions.