Appearance
Creating Camera Curves
This tutorial walks you through creating custom camera effects using Motion's curve system. You'll learn to create head bob, landing impact, and other procedural camera animations.
Overview
Motion's camera system uses UCurveVector assets to define procedural animations. Each curve has X, Y, Z channels that can represent either location or rotation offsets applied to the camera over time.
Prerequisites
- MotionCameraComponent added to your character
- MotionCameraEventBus component for receiving events
- Basic familiarity with Unreal's Curve Editor
Step 1: Create a Curve Asset
- In Content Browser, right-click and select Miscellaneous > Curve
- Choose CurveVector as the curve type
- Name it descriptively (e.g.,
Curve_HeadBoborCurve_LandingImpact)
Step 2: Design Your Curve
Open the curve asset in the Curve Editor. You have three channels:
| Channel | Location | Rotation |
|---|---|---|
| X (Red) | Right/Left | Roll (tilt) |
| Y (Green) | Forward/Back | Pitch (nod) |
| Z (Blue) | Up/Down | Yaw (turn) |
TIP
Each curve channel affects both location and rotation simultaneously. For location-only effects, keep values small (0.1-1.0). For rotation-only effects, design curves that return to zero position to minimize visual location offset.
Example: Head Bob Curve
A subtle walking head bob:
Time X Y Z
0.0 0 0 0
0.25 0.5 0 1.0
0.5 0 0 0
0.75 -0.5 0 1.0
1.0 0 0 0This creates a figure-8 motion: slight horizontal sway with vertical bounce.
Example: Landing Impact Curve
A sharp downward impact that recovers:
Time X Y Z
0.0 0 0 0
0.05 0 0 -5.0 (sharp drop)
0.15 0 0 -3.0 (partial recovery)
0.4 0 0 0 (full recovery)Curve Editor Tips
- Right-click on timeline to add keyframes
- Shift+click to add keyframe at current time
- Use Auto tangents for smooth interpolation
- Use Linear tangents for sharp, mechanical motion
- Ctrl+drag to scale sections
Step 3: Configure the Motion Curve Structure
In your component or Blueprint, create an FMotionCurve:
Blueprint Configuration
- Create a variable of type
Struct Motion Curve - Configure these properties:
| Property | Description | Example Value |
|---|---|---|
| Identifier | Unique FName identifier for this curve | "WalkHeadBob" |
| CurveAsset | Reference to your UCurveVector | Curve_HeadBob |
| bShouldLoop | Repeat when reaching end | true for head bob |
| bShouldReverse | Play backwards after forward | true for smooth loops |
| Tickrate | Playback speed multiplier | 1.0 (normal speed) |
| Multiplier | Scale the effect intensity | 0.5 (subtle), 2.0 (intense) |
| FalloutSmoothness | Blend out duration when removed | 0.0 default; use 0.2 for quick fade |
| bPauseAtNextZero | Pause curve at next zero crossing | true (safer transitions) |
| ZeroTolerance | Threshold for zero detection | 0.01 |
| bRemoveOnComplete | Auto-remove when curve completes | false (manually remove) |
C++ Configuration
cpp
FMotionCurve HeadBobCurve;
HeadBobCurve.Identifier = TEXT("WalkHeadBob");
HeadBobCurve.CurveAsset = LoadObject<UCurveVector>(nullptr, TEXT("/Game/Curves/CV_HeadBob"));
HeadBobCurve.bShouldLoop = true;
HeadBobCurve.bShouldReverse = true;
HeadBobCurve.Tickrate = 1.0f;
HeadBobCurve.Multiplier = 1.0f;
HeadBobCurve.FalloutSmoothness = 0.2f;Step 4: Apply the Curve
Method 1: Direct Camera Component Access
cpp
// Add the curve
int32 Index = CameraComponent->AddMotionCurve(HeadBobCurve);
// Remove when done
CameraComponent->RemoveMotionCurve(TEXT("WalkHeadBob"));Method 2: Event Bus (Recommended)
Motion components use the Event Bus to broadcast camera effects:
cpp
// From any Motion component
BroadcastCameraEffect(HeadBobCurve, EMotionCameraAction::Add);
// To remove
BroadcastCameraEffect(HeadBobCurve, EMotionCameraAction::Remove);Method 3: Blueprint Event Bus
- Get reference to
MotionCameraEventBuscomponent - Call
Broadcast Curve Eventwith your curve and action (Add/Remove/Pause/Resume)
Step 5: Test and Iterate
- Play in Editor
- Enable debug with
bShowDebugInformation = trueon the camera component - Watch the curve effect in action
- Adjust curve keyframes and multiplier as needed
Debug Commands
bash
# See camera state
log LogMotionCamera Verbose
# View active curves
# Check camera component's GetActiveMotionCurves()Common Curve Patterns
Walking Head Bob
- Loop: Yes
- Reverse: Yes
- Tickrate: Match walking animation cycle
- Multiplier: 0.3-0.5 (subtle)
Sprint Camera Shake
- Loop: Yes
- Reverse: Yes
- Tickrate: Faster than walk (1.5-2.0)
- Multiplier: 0.5-1.0 (more intense)
Landing Impact
- Loop: No
- Reverse: No
- Tickrate: 1.0
- Multiplier: Scale with fall distance
Jump Takeoff
- Loop: No
- Reverse: No
- Tickrate: 1.0
- Multiplier: 0.5-1.0
Weapon Recoil
- Loop: No
- Reverse: No
- Tickrate: Fast (2.0-3.0)
- Multiplier: Scale with weapon type
Curve Combinations
Multiple curves can be active simultaneously. Motion combines them additively:
cpp
// Add walking head bob
CameraComponent->AddMotionCurve(WalkHeadBob);
// Add breathing effect on top
CameraComponent->AddMotionCurve(BreathingCurve);
// Both effects combinePause and Resume
Control curves dynamically:
cpp
// Pause during cutscene
CameraComponent->SetMotionCurvePaused(TEXT("WalkHeadBob"), true);
// Resume after
CameraComponent->SetMotionCurvePaused(TEXT("WalkHeadBob"), false);
// Reset to start
CameraComponent->ResetMotionCurve(TEXT("WalkHeadBob"));Static Offsets
For permanent camera adjustments (not time-based):
cpp
// Add a lean offset
CameraComponent->AddStaticLocationOffset(TEXT("Lean"), FVector(0, 10, 0));
CameraComponent->AddStaticRotationOffset(TEXT("Lean"), FRotator(0, 0, 5));
// Remove when done
CameraComponent->RemoveStaticLocationOffset(TEXT("Lean"));
CameraComponent->RemoveStaticRotationOffset(TEXT("Lean"));Troubleshooting
| Issue | Solution |
|---|---|
| Curve not playing | Check AreCameraEffectsEnabled() - may be disabled by tag |
| Effect too subtle | Increase Multiplier value |
| Jerky animation | Use Auto or User tangents in curve editor |
| Curve not looping | Set bShouldLoop = true |
| Effect persists after removal | Increase FalloutSmoothness for smoother fade |
| Multiple curves conflicting | Use unique Identifier for each curve |
See Also
- MotionCameraComponent - Full component reference
- MotionBreathingComponent - Example curve usage
- Architecture - Camera Event Bus pattern