Appearance
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 UMotionCameraEventBuscomponent 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
UMotionCameraEventBusfor effect events - Works with any ACharacter subclass
Installation
- Add
UMotionCameraEventBusto your Character Blueprint or C++ class - Add
UMotionCameraComponentto your Character Blueprint or C++ class - Position the camera at eye level relative to the character mesh
- Configure standing and crouched camera heights
- Set view angle constraints for first-person gameplay
- Configure camera target offset curve for pitch-based adjustments
- The component will automatically detect and cache owner references
- The camera automatically subscribes to the Event Bus to receive effects from Motion components


Core Functionality
Functions
Core Camera Functions
| Function | Parameters | Return Type | Description |
|---|---|---|---|
AreCameraEffectsEnabled() | None | bool | Check if camera effects are enabled (checks Motion.Camera.DisableShake tag) |
GetOwningCharacter() | None | ACharacter* | Get the owning character (cached reference) |
GetOwningCapsuleComponent() | None | UCapsuleComponent* | Get the owning capsule component (cached reference) |
Camera Height Management
| Function | Parameters | Return Type | Description |
|---|---|---|---|
SetTargetCameraHeight() | float NewHeight, bool bInterpolate = true | void | Set target camera height with optional interpolation |
GetInterpolatedCameraHeight() | None | float | Get current interpolated camera height |
UpdateCameraHeight() | float DeltaTime | void | Update camera height interpolation (called each frame) |
SetCameraToStandingHeight() | bool bInterpolate = true | void | Set camera to standing height |
SetCameraToCrouchedHeight() | bool bInterpolate = true | void | Set camera to crouched height |
ConfigureCameraHeights() | float NewStandingHeight, float NewCrouchedHeight | void | Configure camera heights for standing and crouched positions |
GetBaseEyeHeight() | None | float | Get the base eye height offset |
Curve Management System
| Function | Parameters | Return Type | Description |
|---|---|---|---|
AddMotionCurve() | const FMotionCurve& MotionCurve | int32 | Add a motion curve for camera effects |
RemoveMotionCurve() | const FString& Identifier | void | Remove a motion curve by identifier |
SetMotionCurvePaused() | const FString& Identifier, bool bPaused | void | Pause or unpause a motion curve |
ResetMotionCurve() | const FString& Identifier | void | Reset a motion curve to its starting position |
GetActiveMotionCurves() | None | const TArray<FMotionCurve>& | Get all active motion curves |
FindCurveIndexByIdentifier() | const FString& Identifier | int32 | Find a curve by its identifier |
Static Offset System
| Function | Parameters | Return Type | Description |
|---|---|---|---|
AddStaticLocationOffset() | const FString& Identifier, const FVector& Offset | void | Add a static location offset that persists until removed |
AddStaticRotationOffset() | const FString& Identifier, const FRotator& Offset | void | Add a static rotation offset that persists until removed |
RemoveStaticLocationOffset() | const FString& Identifier | void | Remove a static location offset |
RemoveStaticRotationOffset() | const FString& Identifier | void | Remove a static rotation offset |
ClearAllStaticOffsets() | None | void | Clear all static offsets |
GetCameraTargetOffset() | None | const FRuntimeVectorCurve& | Get the camera target offset curve for external calculations |
Internal Processing Functions
| Function | Parameters | Return Type | Description |
|---|---|---|---|
UpdateMotionCurves() | float DeltaTime | void | Update all active motion curves |
CalculateCurveTransforms() | None | void | Calculate the combined transform from all active curves |
GetCombinedStaticLocationOffset() | None | FVector | Get the combined location offset from all static offsets |
GetCombinedStaticRotationOffset() | None | FRotator | Get the combined rotation offset from all static offsets |
PrintDebugInformation() | None | void | Print debug information if enabled |
Event Bus Handlers
| Function | Parameters | Return Type | Description |
|---|---|---|---|
HandleCurveEvent() | const FMotionCurve& Curve, EMotionCameraAction Action | void | Handle curve events from the event bus (Add, Remove, Pause, Resume) |
HandleHeightEvent() | float Height, bool bInterpolate | void | Handle height events from the event bus (crouch transitions) |
SubscribeToEventBus() | None | void | Subscribe to the camera event bus (called automatically in BeginPlay) |
Overridden Camera Functions
| Function | Parameters | Return Type | Description |
|---|---|---|---|
GetCameraView() | float DeltaTime, FMinimalViewInfo& DesiredView | void | Override camera view calculation with Motion enhancements |
GetEditorPreviewInfo() | float DeltaTime, FMinimalViewInfo& ViewOut | bool | Editor preview information with debug visualization |
Configuration Properties
Camera Height Configuration
| Property | Type | Default | Range | Description |
|---|---|---|---|---|
| StandingCameraHeight | float | 160.0f | - | Camera height when character is standing |
| CrouchedCameraHeight | float | 80.0f | - | Camera height when character is crouched |
| BaseEyeHeight | float | -10.0f | - | Base eye height offset from capsule top |
| HeightInterpolationSpeed | float | 12.0f | 0.1 - 50.0 | Speed of camera height interpolation |
View Angle Constraints
| Property | Type | Default | Description |
|---|---|---|---|
| ViewPitchMin | float | -89.0f | Minimum pitch angle (looking down) |
| ViewPitchMax | float | 89.0f | Maximum pitch angle (looking up) |
| ViewYawMin | float | -359.99f | Minimum yaw angle |
| ViewYawMax | float | 359.99f | Maximum yaw angle |
| ViewRollMin | float | -359.99f | Minimum roll angle |
| ViewRollMax | float | 359.99f | Maximum roll angle |
Camera Target Configuration
| Property | Type | Description |
|---|---|---|
| CameraTargetOffset | FRuntimeVectorCurve | Camera target offset based on pitch angle |
Debug Configuration
| Property | Type | Default | Description |
|---|---|---|---|
| bShowDebugInformation | bool | true | Whether to display debug information on screen and in logs |
| bLogCurveDetails | bool | false | Whether to log detailed curve information (performance intensive) |
Read-Only State Properties
Cached References
| Property | Type | Description |
|---|---|---|
| OwningCharacter | ACharacter* | Owning character (cached for performance) |
| OwningCapsuleComponent | UCapsuleComponent* | Owning capsule component (cached for performance) |
| OwningPlayerCameraManager | APlayerCameraManager* | Owning player camera manager (cached for performance) |
| CachedEventBus | UMotionCameraEventBus* | Cached reference to the camera event bus |
| CachedAbilitySystemComponent | UAbilitySystemComponent* | Cached reference to the ability system component |
| DefaultCapsuleHalfHeight | float | Default capsule half height (cached for performance) |
Camera Height State
| Property | Type | Description |
|---|---|---|
| CurrentCameraHeight | float | Current interpolated camera height (independent of capsule) |
| TargetCameraHeight | float | Target camera height for interpolation |
| bIsInterpolatingHeight | bool | Whether camera height is currently interpolating |
Curve and Offset State
| Property | Type | Description |
|---|---|---|
| ActiveMotionCurves | TArray<FMotionCurve> | All active motion curves affecting the camera |
| StaticLocationOffsets | TMap<FString, FVector> | Static location offsets that persist until manually removed |
| StaticRotationOffsets | TMap<FString, FRotator> | Static rotation offsets that persist until manually removed |
| CameraLocationFromCurves | FVector | Combined location offset from all active curves |
| CameraRotationFromCurves | FRotator | Combined 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 rollCamera 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 upOr 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:
| Event | Source Components | Effect |
|---|---|---|
OnMotionCurveEvent | Walk, Sprint, Jump, Breathing | Camera shake, bob, breathing effects |
OnCameraHeightEvent | Crouch | Camera 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:
- Motion Curves: All curves contribute additively
- Static Offsets: Applied after curve processing
- Height Interpolation: Applied to final position
- 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
| Action | Description |
|---|---|
EMotionCameraAction::Add | Start playing a new curve effect |
EMotionCameraAction::Remove | Stop and remove a curve by its identifier |
EMotionCameraAction::Pause | Pause a curve (keeps its position) |
EMotionCameraAction::Resume | Resume a paused curve |
FMotionCurve Properties
When handling curve events, you'll receive an FMotionCurve with these key properties:
| Property | Type | Description |
|---|---|---|
Identifier | FString | Unique identifier for the curve |
CurveVector | FRuntimeVectorCurve | The actual curve data (XYZ = rotation, or translation) |
Tickrate | float | Playback speed multiplier |
Multiplier | float | Amplitude multiplier |
bShouldLoop | bool | Whether the curve should loop |
bShouldReverse | bool | Whether to reverse at the end |
ActiveSeconds | float | Current playback time |
bIsPaused | bool | Current pause state |
This decoupled architecture allows you to use any camera system while still benefiting from the movement effects provided by Motion components.