Skip to content

MotionCameraComponent

The Camera Component provides first-person camera control with procedural animations. It handles height transitions, curve-based effects, and view angle constraints.

Requirements

  • Character with standard UCapsuleComponent
  • UMotionCameraEventBus component on the same character (for receiving effect events)
  • MotionPlayerState configured in GameMode (for GAS tag checks)
  • Gameplay Tags (optional):
    • Motion.Camera.DisableShake - Disables camera effects when present
  • Component Dependencies:
    • Automatically caches owning Character, CapsuleComponent, and PlayerCameraManager
    • Automatically subscribes to UMotionCameraEventBus for effect events
    • Works with any ACharacter subclass

Installation

  1. Add UMotionCameraEventBus to your Character Blueprint or C++ class
  2. Add UMotionCameraComponent to your Character Blueprint or C++ class
  3. Position the camera at eye level relative to the character mesh
  4. Configure standing and crouched camera heights
  5. Set view angle constraints for first-person gameplay
  6. Configure camera target offset curve for pitch-based adjustments
  7. The component will automatically detect and cache owner references
  8. The camera automatically subscribes to the Event Bus to receive effects from Motion components

Core Functionality

Functions

Core Camera Functions

FunctionParametersReturn TypeDescription
AreCameraEffectsEnabled()NoneboolCheck if camera effects are enabled (checks Motion.Camera.DisableShake tag)
GetOwningCharacter()NoneACharacter*Get the owning character (cached reference)
GetOwningCapsuleComponent()NoneUCapsuleComponent*Get the owning capsule component (cached reference)

Camera Height Management

FunctionParametersReturn TypeDescription
SetTargetCameraHeight()float NewHeight, bool bInterpolate = truevoidSet target camera height with optional interpolation
GetInterpolatedCameraHeight()NonefloatGet current interpolated camera height
UpdateCameraHeight()float DeltaTimevoidUpdate camera height interpolation (called each frame)
SetCameraToStandingHeight()bool bInterpolate = truevoidSet camera to standing height
SetCameraToCrouchedHeight()bool bInterpolate = truevoidSet camera to crouched height
ConfigureCameraHeights()float NewStandingHeight, float NewCrouchedHeightvoidConfigure camera heights for standing and crouched positions
GetBaseEyeHeight()NonefloatGet the base eye height offset

Curve Management System

FunctionParametersReturn TypeDescription
AddMotionCurve()const FMotionCurve& MotionCurveint32Add a motion curve for camera effects
RemoveMotionCurve()const FString& IdentifiervoidRemove a motion curve by identifier
SetMotionCurvePaused()const FString& Identifier, bool bPausedvoidPause or unpause a motion curve
ResetMotionCurve()const FString& IdentifiervoidReset a motion curve to its starting position
GetActiveMotionCurves()Noneconst TArray<FMotionCurve>&Get all active motion curves
FindCurveIndexByIdentifier()const FString& Identifierint32Find a curve by its identifier

Static Offset System

FunctionParametersReturn TypeDescription
AddStaticLocationOffset()const FString& Identifier, const FVector& OffsetvoidAdd a static location offset that persists until removed
AddStaticRotationOffset()const FString& Identifier, const FRotator& OffsetvoidAdd a static rotation offset that persists until removed
RemoveStaticLocationOffset()const FString& IdentifiervoidRemove a static location offset
RemoveStaticRotationOffset()const FString& IdentifiervoidRemove a static rotation offset
ClearAllStaticOffsets()NonevoidClear all static offsets
GetCameraTargetOffset()Noneconst FRuntimeVectorCurve&Get the camera target offset curve for external calculations

Internal Processing Functions

FunctionParametersReturn TypeDescription
UpdateMotionCurves()float DeltaTimevoidUpdate all active motion curves
CalculateCurveTransforms()NonevoidCalculate the combined transform from all active curves
GetCombinedStaticLocationOffset()NoneFVectorGet the combined location offset from all static offsets
GetCombinedStaticRotationOffset()NoneFRotatorGet the combined rotation offset from all static offsets
PrintDebugInformation()NonevoidPrint debug information if enabled

Event Bus Handlers

FunctionParametersReturn TypeDescription
HandleCurveEvent()const FMotionCurve& Curve, EMotionCameraAction ActionvoidHandle curve events from the event bus (Add, Remove, Pause, Resume)
HandleHeightEvent()float Height, bool bInterpolatevoidHandle height events from the event bus (crouch transitions)
SubscribeToEventBus()NonevoidSubscribe to the camera event bus (called automatically in BeginPlay)

Overridden Camera Functions

FunctionParametersReturn TypeDescription
GetCameraView()float DeltaTime, FMinimalViewInfo& DesiredViewvoidOverride camera view calculation with Motion enhancements
GetEditorPreviewInfo()float DeltaTime, FMinimalViewInfo& ViewOutboolEditor preview information with debug visualization

Configuration Properties

Camera Height Configuration

PropertyTypeDefaultRangeDescription
StandingCameraHeightfloat160.0f-Camera height when character is standing
CrouchedCameraHeightfloat80.0f-Camera height when character is crouched
BaseEyeHeightfloat-10.0f-Base eye height offset from capsule top
HeightInterpolationSpeedfloat12.0f0.1 - 50.0Speed of camera height interpolation

View Angle Constraints

PropertyTypeDefaultDescription
ViewPitchMinfloat-89.0fMinimum pitch angle (looking down)
ViewPitchMaxfloat89.0fMaximum pitch angle (looking up)
ViewYawMinfloat-359.99fMinimum yaw angle
ViewYawMaxfloat359.99fMaximum yaw angle
ViewRollMinfloat-359.99fMinimum roll angle
ViewRollMaxfloat359.99fMaximum roll angle

Camera Target Configuration

PropertyTypeDescription
CameraTargetOffsetFRuntimeVectorCurveCamera target offset based on pitch angle

Debug Configuration

PropertyTypeDefaultDescription
bShowDebugInformationbooltrueWhether to display debug information on screen and in logs
bLogCurveDetailsboolfalseWhether to log detailed curve information (performance intensive)

Read-Only State Properties

Cached References

PropertyTypeDescription
OwningCharacterACharacter*Owning character (cached for performance)
OwningCapsuleComponentUCapsuleComponent*Owning capsule component (cached for performance)
OwningPlayerCameraManagerAPlayerCameraManager*Owning player camera manager (cached for performance)
CachedEventBusUMotionCameraEventBus*Cached reference to the camera event bus
CachedAbilitySystemComponentUAbilitySystemComponent*Cached reference to the ability system component
DefaultCapsuleHalfHeightfloatDefault capsule half height (cached for performance)

Camera Height State

PropertyTypeDescription
CurrentCameraHeightfloatCurrent interpolated camera height (independent of capsule)
TargetCameraHeightfloatTarget camera height for interpolation
bIsInterpolatingHeightboolWhether camera height is currently interpolating

Curve and Offset State

PropertyTypeDescription
ActiveMotionCurvesTArray<FMotionCurve>All active motion curves affecting the camera
StaticLocationOffsetsTMap<FString, FVector>Static location offsets that persist until manually removed
StaticRotationOffsetsTMap<FString, FRotator>Static rotation offsets that persist until manually removed
CameraLocationFromCurvesFVectorCombined location offset from all active curves
CameraRotationFromCurvesFRotatorCombined rotation offset from all active curves

Motion Curves

Motion curves define procedural camera animations with full control over translation and rotation:

cpp
FMotionCurve CurveData;
CurveData.Identifier = "WalkBob";
CurveData.TranslationCurve = LoadObject<UCurveVector>(...);
CurveData.RotationCurve = LoadObject<UCurveVector>(...);
CurveData.Duration = 1.0f;
CurveData.PlayRate = 1.0f;
CurveData.bLoop = true;
CurveData.bStartPaused = false;

int32 CurveIndex = CameraComponent->AddMotionCurve(CurveData);

// Runtime control
CameraComponent->SetMotionCurvePaused("WalkBob", true);
CameraComponent->ResetMotionCurve("WalkBob");
CameraComponent->RemoveMotionCurve("WalkBob");

Curve Properties

  • Identifier - Unique string ID for the curve
  • TranslationCurve - XYZ position offsets over time
  • RotationCurve - Pitch/Yaw/Roll offsets over time
  • Duration - Total curve duration in seconds
  • PlayRate - Playback speed multiplier
  • bLoop - Whether curve repeats
  • bStartPaused - Start in paused state
  • CurrentTime - Current playback time (automatically managed)
  • bIsPaused - Current pause state

Static Offset System

Static offsets provide persistent camera adjustments that remain until explicitly removed:

cpp
// Add weapon ADS offset
CameraComponent->AddStaticLocationOffset("ADS", FVector(10, 5, -2));
CameraComponent->AddStaticRotationOffset("ADS", FRotator(-2, 0, 0));

// Multiple offsets can be active simultaneously
CameraComponent->AddStaticLocationOffset("Lean", FVector(0, 15, 0));
CameraComponent->AddStaticLocationOffset("Breathing", FVector(0, 0, 1));

// Remove specific offsets
CameraComponent->RemoveStaticLocationOffset("ADS");
CameraComponent->RemoveStaticRotationOffset("ADS");

// Clear all offsets at once
CameraComponent->ClearAllStaticOffsets();

// Query combined offsets
FVector CombinedLocation = CameraComponent->GetCombinedStaticLocationOffset();
FRotator CombinedRotation = CameraComponent->GetCombinedStaticRotationOffset();

Offset Processing

  • Additive: All static offsets are added together
  • Persistent: Remain active until explicitly removed
  • Named: Each offset identified by unique string
  • Independent: Location and rotation offsets managed separately

Camera Height Management

The component provides independent camera height tracking with smooth interpolation:

cpp
// Standard height transitions
CameraComponent->SetCameraToStandingHeight(true);  // Interpolated
CameraComponent->SetCameraToCrouchedHeight(true);   // Interpolated

// Custom height with interpolation control
CameraComponent->SetTargetCameraHeight(50.0f, true);   // Smooth transition
CameraComponent->SetTargetCameraHeight(120.0f, false); // Instant change

// Configure base heights
CameraComponent->ConfigureCameraHeights(180.0f, 90.0f); // Standing, Crouched

// Query current state
float CurrentHeight = CameraComponent->GetInterpolatedCameraHeight();
float BaseEyeHeight = CameraComponent->GetBaseEyeHeight();
bool IsInterpolating = CameraComponent->bIsInterpolatingHeight;

Height System Features

  • Independent Tracking: Camera height separate from capsule height
  • Smooth Interpolation: Configurable interpolation speed
  • State Awareness: Tracks interpolation progress
  • Base Eye Height: Offset from capsule top for fine-tuning

Advanced Features

View Angle Constraints

Comprehensive view angle clamping system:

cpp
// Configure view limits
CameraComponent->ViewPitchMin = -80.0f;   // Limit looking down
CameraComponent->ViewPitchMax = 80.0f;    // Limit looking up
CameraComponent->ViewYawMin = -180.0f;    // Limit left turn
CameraComponent->ViewYawMax = 180.0f;     // Limit right turn
CameraComponent->ViewRollMin = -45.0f;    // Limit left roll
CameraComponent->ViewRollMax = 45.0f;     // Limit right roll

Camera Target Offset Curve

Pitch-based camera targeting adjustments:

cpp
// Configure pitch-based offset curve
FRuntimeVectorCurve& TargetOffset = CameraComponent->CameraTargetOffset;
TargetOffset.GetRichCurveConst(0)->AddKey(-90.0f, 10.0f);  // Looking down
TargetOffset.GetRichCurveConst(0)->AddKey(0.0f, 0.0f);     // Level
TargetOffset.GetRichCurveConst(0)->AddKey(90.0f, -10.0f);  // Looking up

Or define as a curve asset in the editor.

Integration with Motion Components

Motion components communicate with the camera through the Camera Event Bus pattern:

Event Types:

EventSource ComponentsEffect
OnMotionCurveEventWalk, Sprint, Jump, BreathingCamera shake, bob, breathing effects
OnCameraHeightEventCrouchCamera height transitions

Component Effects:

  • Walk Component - Broadcasts subtle walking bob curves
  • Sprint Component - Broadcasts sprint shake curve with speed modulation
  • Jump Component - Broadcasts jump takeoff and landing camera effects
  • Crouch Component - Broadcasts height transition events
  • Breathing Component - Broadcasts idle breathing camera motion

Processing Priority System

When multiple effects are active:

  1. Motion Curves: All curves contribute additively
  2. Static Offsets: Applied after curve processing
  3. Height Interpolation: Applied to final position
  4. View Angle Clamping: Final transform validation

Camera Effects Control

Camera effects can be controlled via multiple methods:

cpp
// Gameplay tag control (automatic)
bool EffectsEnabled = CameraComponent->AreCameraEffectsEnabled();
// Checks for Motion.Camera.DisableShake tag on ASC

// Individual curve control
CameraComponent->SetMotionCurvePaused("WalkBob", true);
CameraComponent->RemoveMotionCurve("SprintShake");

// Global debug toggle
CameraComponent->bShowDebugInformation = false;

Custom Camera Integration

If you prefer to use your own camera system instead of UMotionCameraComponent, you can subscribe to the Camera Event Bus to receive effect events from Motion components.

Subscribing to the Event Bus

cpp
// In your custom camera component's BeginPlay:
void UMyCustomCamera::BeginPlay()
{
    Super::BeginPlay();

    // Find the event bus on the owning character
    if (AActor* Owner = GetOwner())
    {
        UMotionCameraEventBus* EventBus = Owner->FindComponentByClass<UMotionCameraEventBus>();
        if (EventBus)
        {
            // Subscribe to curve events (camera shake, bob, breathing)
            EventBus->OnMotionCurveEvent.AddDynamic(this, &UMyCustomCamera::HandleCurveEvent);

            // Subscribe to height events (crouch transitions)
            EventBus->OnCameraHeightEvent.AddDynamic(this, &UMyCustomCamera::HandleHeightEvent);
        }
    }
}

Implementing Event Handlers

cpp
UFUNCTION()
void UMyCustomCamera::HandleCurveEvent(const FMotionCurve& Curve, EMotionCameraAction Action)
{
    // Only process for locally controlled characters
    if (ACharacter* Character = Cast<ACharacter>(GetOwner()))
    {
        if (!Character->IsLocallyControlled())
            return;
    }

    switch (Action)
    {
        case EMotionCameraAction::Add:
            // Start playing the curve effect
            AddMyCurveEffect(Curve);
            break;

        case EMotionCameraAction::Remove:
            // Stop and remove the curve by identifier
            RemoveMyCurveEffect(Curve.Identifier);
            break;

        case EMotionCameraAction::Pause:
            // Pause the curve
            PauseMyCurveEffect(Curve.Identifier);
            break;

        case EMotionCameraAction::Resume:
            // Resume the curve
            ResumeMyCurveEffect(Curve.Identifier);
            break;
    }
}

UFUNCTION()
void UMyCustomCamera::HandleHeightEvent(float TargetHeight, bool bInterpolate)
{
    // Only process for locally controlled characters
    if (ACharacter* Character = Cast<ACharacter>(GetOwner()))
    {
        if (!Character->IsLocallyControlled())
            return;
    }

    // Apply your own height transition logic
    SetMyCameraHeight(TargetHeight, bInterpolate);
}

Event Actions

ActionDescription
EMotionCameraAction::AddStart playing a new curve effect
EMotionCameraAction::RemoveStop and remove a curve by its identifier
EMotionCameraAction::PausePause a curve (keeps its position)
EMotionCameraAction::ResumeResume a paused curve

FMotionCurve Properties

When handling curve events, you'll receive an FMotionCurve with these key properties:

PropertyTypeDescription
IdentifierFStringUnique identifier for the curve
CurveVectorFRuntimeVectorCurveThe actual curve data (XYZ = rotation, or translation)
TickratefloatPlayback speed multiplier
MultiplierfloatAmplitude multiplier
bShouldLoopboolWhether the curve should loop
bShouldReverseboolWhether to reverse at the end
ActiveSecondsfloatCurrent playback time
bIsPausedboolCurrent pause state

This decoupled architecture allows you to use any camera system while still benefiting from the movement effects provided by Motion components.

Motion - Advanced First Person Character Controller