Appearance
MotionCameraComponent
MotionCameraComponent controls the first-person camera. It supports procedural curves, height transitions, static offsets, view angle limits, and native first-person body presentation.
Build with Motion 2.0
Review the Unreal Engine 5 first-person controller overview, or get Motion 2.0 on Fab.
Use native item config transforms to adjust the screen position of a first-person weapon or item. Stable camera body clearance applies to all presentations. It does not control item placement. See First-Person Item Configs.
Requirements
- Character with standard
UCapsuleComponent - Full-body skeletal mesh with the configured pivot socket for Socket mode
- Optional ASC access for camera-related GameplayTag checks
- Optional
Motion.Camera.DisableShaketag to gate motion-curve updates
The component automatically stores references to its character, capsule component, and player camera manager.
For setup steps, see How to add Motion to a character.
Behavior
During a component tick, the height interpolation updates first. Curve playback and the stored combined curve transforms then update when AreCameraEffectsEnabled() is true. Camera view generation starts from the Stable origin or the raw Socket origin. It then adds static offsets and motion-curve offsets. Next, it resolves Stable body clearance and world obstruction. The component then produces the final transform.
At BeginPlay, the component writes view pitch limits to the local PlayerCameraManager. It does not limit the pitch each frame.
Stable mode uses a height origin that is independent of animation. It moves the desired camera point forward if the point is inside the capsule body proxy. The clearance curve controls the amount of this movement. The solver uses the actual desired point. Thus, all camera heights and offsets use the same calculation. Animation pose and item state do not set the Stable camera position.
The Stable camera / Motion 1.6 camera samples the full-body MotionCamera socket as an evaluated animation reference. It aligns FirstPersonUpperBody and the attached item with the Stable camera anchor before clearance. It adds the shared profile pitch-vector curve in a yaw-only basis. It also limits the total correction on each axis.
Camera clearance continues to represent the distance between the camera and the body. FirstPersonLowerBody stays at its authored ground transform. The world and full-body representations do not move.
Motion.Camera.DisableShake makes AreCameraEffectsEnabled() false. It does not disable height interpolation, static offsets, Stable clearance, collision, or native first-person presentation. It also does not clear the last stored curve transform.
Movement components do not change camera transforms directly. They send curve and height requests to the MotionCameraComponent on the same actor.
API
Core camera functions
AreCameraEffectsEnabled() -> bool: returns false when the stored or late-resolved ASC hasMotion.Camera.DisableShake. It returns true when no ASC is available.GetOwningCharacter() -> ACharacter*: returns the cached owning character.GetOwningCapsuleComponent() -> UCapsuleComponent*: returns the cached capsule component.
Height management
SetTargetCameraHeight(float NewHeight, bool bInterpolate = true) -> void: sets target camera height.GetInterpolatedCameraHeight() -> float: returns current interpolated height.UpdateCameraHeight(float DeltaTime) -> void: updates height interpolation.SetCameraToStandingHeight(bool bInterpolate = true) -> void: moves camera to standing height.SetCameraToCrouchedHeight(bool bInterpolate = true) -> void: moves camera to crouched height.ConfigureCameraHeights(float NewStandingHeight, float NewCrouchedHeight) -> void: updates standing and crouched heights.GetBaseEyeHeight() -> float: returns base eye height offset.
Motion curves
AddMotionCurve(const FMotionCurve& MotionCurve) -> int32: adds a camera effect curve.RemoveMotionCurve(const FName& Identifier) -> void: removes every curve with the identifier.SetMotionCurvePaused(const FName& Identifier, bool bPaused) -> void: pauses or resumes a curve.ResetMotionCurve(const FName& Identifier) -> void: resets a curve to its start.GetActiveMotionCurves() -> const TArray<FMotionCurve>&: returns active curves.FindCurveIndexByIdentifier(const FName& Identifier) -> int32: finds a curve index by identifier.
Static offsets
AddStaticLocationOffset(const FName& Identifier, const FVector& Offset) -> void: adds persistent location offset.AddStaticRotationOffset(const FName& Identifier, const FRotator& Offset) -> void: adds persistent rotation offset.RemoveStaticLocationOffset(const FName& Identifier) -> void: removes a location offset.RemoveStaticRotationOffset(const FName& Identifier) -> void: removes a rotation offset.ClearAllStaticOffsets() -> void: clears all static offsets.
Internal processing
UpdateMotionCurves(float DeltaTime) -> void: updates all active curves.CalculateCurveTransforms() -> void: calculates combined curve transform.GetCombinedStaticLocationOffset() -> FVector: returns combined static location offset.GetCombinedStaticRotationOffset() -> FRotator: returns combined static rotation offset.PrintDebugInformation() -> void: prints debug output when enabled.
Overrides
GetCameraView(float DeltaTime, FMinimalViewInfo& DesiredView) -> void: applies Motion camera logic.GetEditorPreviewInfo(float DeltaTime, FMinimalViewInfo& ViewOut) -> bool: fills the preview through the superclass camera view when the component is active. It then returns true.
Native first-person rendering
ConfigureNativeFirstPersonPresentation() -> void: configures the local first-person body mesh roles.IsNativeFirstPersonPresentationEnabled() -> bool: returns whether native first-person body presentation is active locally.GetFirstPersonUpperBodyComponent() -> USkeletalMeshComponent*: returns the resolvedFirstPersonUpperBodymesh.GetFirstPersonLowerBodyComponent() -> USkeletalMeshComponent*: returns the resolvedFirstPersonLowerBodymesh.ApplyNativeFirstPersonRenderTuning(const FMotionNativeFirstPersonItemRenderTuning& RenderTuning) -> bool: applies supported item render settings to all first-person components.ClearNativeFirstPersonRenderTuning() -> void: restores native first-person camera defaults.GetCurrentNativeFirstPersonFieldOfView() -> float: returns the active native first-person FOV.GetCurrentNativeFirstPersonScale() -> float: returns the active native first-person scale.GetLastFinalCameraViewState() -> FMotionFinalCameraViewState: returns the last evaluated final camera view.GetFirstPersonPresentationState() -> FMotionFirstPersonPresentationState: returns presentation validity, camera mode, and obstruction state.GetStableCameraClearanceCurve() -> const FRuntimeFloatCurve&: returns the pitch-to-clearance-strength curve.GetStableCameraClearancePadding() -> float: returns the extra forward distance beyond the capsule surface at full clearance.GetMaxStableCameraClearanceCorrection() -> float: returns the maximum actor-forward Stable correction.GetStablePresentationAnchorOffset() -> FVector: returns the yaw-local neutral presentation-anchor offset.GetStablePresentationOffsetCurve() -> const FRuntimeVectorCurve&: returns the shared pitch-to-XYZ upper-body presentation curve.GetMaxStablePresentationCorrection() -> FVector: returns the per-axis Stable camera / Motion 1.6 camera correction budget.
Configuration
The assigned MotionCameraProfile contains settings for the Stable camera / Motion 1.6 camera. The Motion default is /MotionCore/Motion/Profiles/v2_0_0/DA_MotionCameraProfile_Default_v2_0_0.
The profile contains project-level camera and presentation defaults. It does not contain all internal solver constants.
Camera height
BaseEyeHeight: offset from the capsule-derived height. Default:-10.0f.HeightInterpolationSpeed: interpolation speed. Default:12.0f.
The component calculates standing and crouched camera targets from the capsule, crouch-height events, and BaseEyeHeight. These targets are runtime camera fields. They are not profile constants.
View Angle Constraints
ViewPitchMin: minimum pitch angle. Default:-89.0f.ViewPitchMax: maximum pitch angle. Default:89.0f.
Camera mode
CameraPivotSocketName: empty for Stable mode. Set it to a valid full-body mesh socket for Socket mode. Default: empty. Diagnostics such as debug display and detailed curve logging remain component-owned.
Native first-person body setup
bEnableNativeFirstPersonPresentation: enables local native first-person body setup.NativeFirstPersonFieldOfView: default camera first-person FOV.NativeFirstPersonScale: default camera first-person scale.FirstPersonLookDownScale: target first-person render scale during a steep downward view and camera obstruction. Set it to1.0to disable scale reduction.StableCameraClearanceCurve: maps final view pitch to Stable clearance strength.0disables correction.1requests full calculated clearance. The supplied curve is1at-89degrees. It becomes0at-60degrees.StableCameraClearancePadding: extra forward distance from the front surface of the capsule at full clearance. Default:15.0fcm.MaxStableCameraClearanceCorrection: maximum actor-forward Stable correction. Default:60.0fcm.StablePresentationAnchorOffset: yaw-local neutral offset from the pre-clearance Stable camera point to the desired presentation anchor. Default: zero.StablePresentationOffsetCurve: optional yaw-local XYZ correction that uses the final view pitch. The supplied shared curve adds+40cm on X at-89degrees. It becomes zero at-60degrees.MaxStablePresentationCorrection: maximum absolute Stable upper-body correction per yaw-local axis. Default:(100, 100, 100)cm.FirstPersonCameraObstructionPoseOffset: owner-view pose offset for the upper body during camera obstruction. UseFVector::ZeroVectorto disable this offset.
The character must provide a full-body mesh. It must also provide FirstPersonUpperBody and FirstPersonLowerBody skeletal mesh components. The native Stable camera / Motion 1.6 camera must have a MotionCamera socket on the full-body skeleton. This socket measures evaluated body motion. It does not set the Stable camera position.
On the local client, Motion marks the two first-person components as FirstPerson primitives. It marks the full-body mesh as the WorldSpaceRepresentation.
Motion uses Stable mode when CameraPivotSocketName is empty. It calculates the base camera from the capsule and ground height. Motion then adds the base height, static offsets, and active motion-curve location. It evaluates the desired point against the capsule at the actual local lateral and vertical position. At full curve strength, it moves the point forward to the capsule front plus StableCameraClearancePadding.
MaxStableCameraClearanceCorrection limits this movement. Partial curve values blend the uncorrected point with the fully cleared point.
A valid nonempty CameraPivotSocketName selects Socket mode. Motion uses the evaluated socket location as the raw camera origin. Stable clearance does not apply. Motion reports an invalid configuration if the requested socket does not exist. It does not select Stable mode.
The clearance solver uses the final desired point instead of a stance enum. One profile curve applies to all movement states, height changes, static offsets, and active camera effects. Equipped items are not an input.
After camera evaluation, the Stable camera / Motion 1.6 camera restores the authored upper-body transform. It samples the evaluated full-body MotionCamera socket. It then calculates the yaw-local correction that aligns the body with the Stable anchor before clearance. StablePresentationOffsetCurve adds the shared pitch-dependent composition. MaxStablePresentationCorrection then limits the total. The same settings apply to all item states, movement states, and project-defined camera heights.
The clearance curve is a dimensionless camera-safety control. The presentation curve controls XYZ upper-body and item composition. It does not move the camera. MotionNativeFirstPersonItemConfig controls item-specific grip and screen placement. Content authors control mesh cut placement and hidden interior geometry.
Motion resolves world obstruction after Stable clearance. The two camera modes apply the camera displacement directly to FirstPersonUpperBody. Stable mode adds the anchor correction. Socket mode does not add the anchor correction. The optional FirstPersonCameraObstructionPoseOffset applies only to the upper body. These operations do not move FirstPersonLowerBody.
Collision
bEnableCameraCollision: enables ceiling and obstruction checks.CameraObstructionProbeRadius: sphere radius used to keep the final camera view out of blocking geometry.CameraCollisionChannel: collision channel used by camera traces. Default:ECC_Camera.
The primary editable setting is the Profile reference. You can also edit the debug and log controls on the component. The component contains runtime state, stored references, collision clearances, and diagnostics.
Read-Only State
OwningCharacter: cached owning character.OwningCapsuleComponent: cached capsule component.OwningPlayerCameraManager: cached player camera manager.CachedAbilitySystemComponent: cached ability system component.DefaultCapsuleHalfHeight: cached default capsule half height.CurrentCameraHeight: current interpolated height.TargetCameraHeight: target interpolation height.bIsInterpolatingHeight: whether height interpolation is active.ActiveMotionCurves: active camera curves.StaticLocationOffsets: persistent location offsets.StaticRotationOffsets: persistent rotation offsets.CameraLocationFromCurves: combined location offset from curves.CameraRotationFromCurves: combined rotation offset from curves.LastFinalCameraViewState: last valid Motion camera view and its evaluated contributions.FirstPersonPresentationState: current mode, desired/evaluated Stable anchors, curve contribution, raw/applied correction, clamp state, and obstruction diagnostics.
Motion Curves
FMotionCurve defines procedural camera animation. The most important fields are:
Identifier:FNamefor lookup. The caller is responsible for uniqueness.CurveAsset:UCurveVectorasset for the effect.bShouldLoop: wraps playback from the end to the beginning when reverse playback is disabled.bShouldReverse: reverses playback at the end and then switches forward again at the beginning, producing ping-pong playback.Tickrate: playback speed multiplier.Multiplier: effect intensity.FalloutSmoothness: stored configuration value. Camera playback does not use it.bPauseAtNextZero: whether a pause request waits for a near-zero curve sample. Removal is immediate.bRemoveOnComplete: whether one-shot curves remove themselves.ActiveSeconds: current playback time, managed by the component.bIsPaused: current pause state.
Static Offset System
Static offsets are persistent additive camera adjustments. They stay active until you remove them. Use them for camera behavior such as ADS or lean. Use MotionNativeFirstPersonItemConfig transforms for item presentation, grip alignment, and local first-person item position.
Offsets are additive, persistent, and named. Location offsets and rotation offsets are separate.
Camera Height Management
The component tracks camera height independently of capsule height. It supports smooth interpolation, immediate changes, base eye height adjustment, and transition state.
Movement Component Integration
Motion movement components forward camera feedback to the MotionCameraComponent found on the same actor:
- Walk adds its walk bob curve one time. It then pauses or resumes the curve as necessary.
- Sprint adds and removes sprint camera shake.
- Jump adds jump and landing camera effects.
- Crouch updates the camera height target.
- Breathing adds the idle breathing curve one time. It then pauses or resumes the curve as necessary.
During a component tick, height interpolation occurs before curve playback and curve-transform calculation. Camera view generation then adds static offsets and curve offsets. It resolves Stable clearance and world obstruction. Finally, it builds the final view state and applies native first-person presentation.