CrimsonCamera · Lesson 3 of 6
Switch Camera Modes
Before you start
- Completed: Your First Camera
Chapters
Option A — push / pop on events (recommended)
Push an override when something starts (aim, mount, cutscene) and pop it when it ends. Each override is keyed by an owner tag: re-pushing with the same tag replaces it, popping with the same tag removes it, and the most-recently-pushed override wins. Identical in Blueprint and C++.
// Start aiming:Cam->PushCameraMode(UMyAimMode::StaticClass(), TAG_Camera_Mode_Aim);// Stop aiming:Cam->PopCameraMode(TAG_Camera_Mode_Aim);
Owner tags keep systems from clobbering each other
Because each override is keyed by its own tag, independent systems (aim, lock-on, a cutscene director) never overwrite one another — each pops only its own entry, restoring whatever was underneath.
Option B — select per frame from state
When no override is active, the component asks Determine Camera Mode every tick which mode to run. Override it to return a mode class computed from game state. Overrides (Option A) still take precedence when present.
// Bind the C++ delegate from any component (e.g. a hero component)...Cam->DetermineCameraModeDelegate.BindUObject(this, &AMyCharacter::PickMode);TSubclassOf<UCrimsonCameraMode> AMyCharacter::PickMode() const { return bIsAiming ? AimMode : DefaultMode; }// ...or override the BlueprintNativeEvent in a UCrimsonCameraComponent subclass:TSubclassOf<UCrimsonCameraMode> UMyCameraComponent::DetermineCameraMode_Implementation(){return bIsAiming ? AimMode : DefaultMode;}
Why selection is an event, not a multicast delegate
Determine Camera Mode returns the chosen mode, and Blueprint-assignable (dynamic multicast) delegates can't return a value — so per-tick selection is exposed to Blueprint as the overridable event (its default just runs the C++ DetermineCameraModeDelegate). Override it on a component subclass; if you can't swap the component, use Option A, which needs no subclass.