Concept: Shared Camera State (Shoulder & Zoom)

Shoulder side and zoom distance are player framing preferences, not per-mode settings. So they live on UCrimsonCameraComponent as a single source of truth, and every third-person-derived mode reads the same value. Switch from third-person to aim to lock-on and your shoulder and zoom follow - with no carry-over code.

Why component-wide

The stack keeps one instance per mode class (see Concept: The Mode Stack). If shoulder/zoom were stored per instance, each mode would have its own - and switching modes would reset your framing. Hoisting them to the component means there is exactly one shoulder and one zoom, shared by all modes; the component advances their interpolation each frame before the modes evaluate.

Shoulder is a mirror, not an offset

The lateral (Y) framing magnitude comes from the active mode's offset curve. The shoulder applies a sign to it, interpolated smoothly through zero on a swap:

ShoulderLateral Y (curve Y = 45)Meaning
Right+45 (curve Y as authored)Default side
Left-45 (curve Y negated)Mirror of Right
Center0No lateral offset - camera directly behind
Author the magnitude in the curve
Set the lateral framing distance as the Y value of the mode's offset curve (e.g. 45). The shoulder only flips its sign, so Right/Left are always a clean mirror. ToggleShoulder flips Left/Right; from Center it moves to the default side (Right) rather than doing nothing.

Zoom is shared and clamped on the component

AddZoomDistance / SetZoomDistance change one shared target, clamped to the component's [MinZoomDistance, MaxZoomDistance] and interpolated by ZoomInterpSpeed. Every mode dollies its boom by the same GetCurrentZoomDistance(). The range is a single camera-wide setting - there is no per-mode zoom range; a mode either uses the shared zoom or opts out.

Per-mode opt-out

A specific mode can ignore the shared state and keep a fixed framing - useful for a cinematic or fixed-aim view.

Property (on the mode)DefaultWhen false
bUseShoulderOffsettrueThe mode ignores the shoulder sign and uses its offset-curve Y exactly as authored.
bUseZoomtrueThe mode ignores the shared zoom and keeps its fixed boom distance.
Opt-out, not scale
bUseShoulderOffset / bUseZoom are all-or-nothing per mode: a mode either uses the shared shoulder/zoom value or ignores it. There is no per-mode shoulder/zoom scale or range override.
Local-only
Like everything in CrimsonCamera, shoulder and zoom are a local presentation concern - they're not replicated. Each client owns its own framing. See Concept: Multiplayer & Authority.