ue-character-movement

Use this skill when working with character movement, CharacterMovementComponent, CMC, movement modes, walking, falling, swimming, flying, custom movement, network prediction, FSavedMove, root motion, floor detection, step-up, or character physics. Also use for 'PhysWalking', 'PhysCustom', 'LaunchCha

By quodsoler · 837 installs

npx skills add quodsoler/unreal-engine-skills --skill ue-character-movement

Source repository · Upstream listing

UE Character Movement Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use". This skill covers UCharacterMovementComponent (CMC) and ACharacter : the movement mode pipeline, floor detection and step up, custom movement modes, client side prediction and correction, root motion, custom gravity, and the 5.8 movement base rework. Everything here ships in the Engine module — no plugin and no extra Build.cs entry beyond "Engine" . Public headers: GameFramework/CharacterMovementComponent.h (which already pulls in GameFramework/RootMotionSource.h , GameFramework/CharacterMovementReplication.h , CharacterMovementComponentAsync.h and Interfaces/MovementBaseInterface.h ), GameFramework/Character.h . Context Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, GAS/networking setup). Do not stop if it is missing. Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code. Request is about… Go to Choosing between CMC and the Mover plugin [CMC vs Mover]( cmc vs mover) Class hierarchy, movement modes, mode transitions [CMC Architecture]( cmc architecture) Standing on a lift, rotating platform, vehicle, physics body [Movement Base]( movement base) Where a tick goes, PhysWalking / PhysFalling , sweeps, sliding [Movement Pipeline]( movement pipeline) Falling through floors, step up, walkable angle, perching [Floor Detection]( floor detection) Wall run, climb, dash, grapple, any new movement type [Custom Movement Modes]( custom movement modes) Multiplayer desync, rubber banding, saved moves, compressed flags [Network Prediction]( network prediction) Knockback, dashes, animation driven motion [Root Motion]( root motion) Walking on walls/ceilings, planet gravity [Custom Gravity]( custom gravity) AI agents, navmesh driven walking, RVO avoidance [NavMesh Walking]( navmesh walking) Jump/crouch/launch from gameplay code [ACharacter API]( acharacter api) Speeds, friction, braking, rotation flags [Key Properties]( key properties) Deep templates live in [cmc extension patterns.md](references/cmc extension patterns.md); per mode internals and flow diagrams live in [movement pipeline.md](references/movement pipeline.md). CMC vs Mover Mover (Experimental in 5.8) is a separate plugin ( Mover , not enabled by default) built around UMoverComponent , UBaseMovementMode , FLayeredMoveBase and UCharacterMoverComponent . It is not a drop in CMC replacement. Situation Use Shipping title, any engine supported platform CMC Existing ACharacter hierarchy, animation and AI already wired to CMC CMC Networked gameplay that must be stable today CMC Non capsule, non humanoid movers (vehicles, drones) that still want rollback networking Mover Movement composed from data driven modes/modifiers instead of a Phys subclass Mover Movement simulated on the physics thread with Chaos Mover ( ChaosMover ) Prototype that can absorb Experimental API churn Mover Mover details belong to ue mover . Do not mix the two components on one pawn. CMC Architecture UNavMovementComponent also implements INavMovementInterface ; UCharacterMovementComponent additionally implements IRVOAvoidanceInterface and INetworkPredictionInterface , and is declared UCLASS(MinimalAPI) . CMC is a default subobject on ACharacter ( ACharacter::CharacterMovementComponentName ). ACharacter owns the capsule, mesh and high level verbs ( Jump , Crouch , LaunchCharacter ); CMC owns simulation, floor detection and prediction. Movement Modes EMovementMode ( Engine/EngineTypes.h ): Mode Meaning MOVE None No movement processing MOVE Walking Ground movement with floor detection and step up MOVE NavWalking Walking driven by navmesh projection MOVE Falling Airborne: gravity, air control, landing MOVE Swimming Fluid movement with buoyancy MOVE Flying Free 3D movement, no gravity MOVE Custom User defined; dispatches to PhysCustom with a uint8 sub mode ACharacter::OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode = 0) fires after the CMC hook and broadcasts MovementModeChangedDelegate ( FMovementModeChangedSignature ). Put enter/exit logic for custom modes in the CMC override; the current sub mode is the uint8 CustomMovementMode member. Movement Base The movement base is the object a character stands on and moves with. In 5.8 it is no longer a UPrimitiveComponent : it is FMovementBaseInterfaceData ( Interfaces/MovementBaseInterface.h ), which holds a TWeakObjectPtr<UObject PhysicsObjectOwner plus the IPhysicsBodyInstanceOwner that supplies the base behaviour. This lets non component physics objects act as bases. Reading the base APawn declares GetMovementBaseObject() , GetMovementBaseInterfaceData() and GetMovementBaseInterfaceData Mutable() ; ACharacter overrides all three as final . FMovementBaseInterfaceData itself exposes IsValid() , Clear() , Set() , GetBodyInstanceOwner() , GetMovementBaseObject() and GetMovementBaseObjectOwner() . Setting the base Build the struct from what you already have: MovementBaseUtility::GetMovementBaseDataFromPhysicsOwner(UObject ) does the same from a replicated PhysicsObjectOwner . Utility namespace Every MovementBaseUtility helper now takes FMovementBaseInterfaceData instead of UPrimitiveComponent : IsDynamicBase , IsSimulatedBase , UseRelativeLocation , AddTickDependency , RemoveTickDependency , GetMovementBaseVelocity , GetMovementBaseTangentialVelocity , GetMovementBaseTransform , TransformLocationToWorld , TransformLocationToLocal , TransformDirectionToWorld , TransformDirectionToLocal . New in 5.8: DoesMovementBaseDataMatch , IsMovementBaseDataValid , GetMovementBaseDataFromPhysicsOwner , GetMovementBaseDataFromHitResult . Stored and replicated base state Old member 5.8 member Holder MovementBase MovementBaseInterfaceData FBasedMovementInfo MovementBase PhysicsObjectOwner FRepRootMotionMontage MovementBase MovementBasePhysicsObjectOwner FCharacterNetworkMoveData StartBase / EndBase StartMovementBaseInterfaceData / EndMovementBaseInterfaceData FSavedMove Character LastServerMovementBase LastMovementBaseInterfaceData UCharacterMovementComponent Every server authority and correction virtual that used to take a UPrimitiveComponent ClientMovementBase now has an FMovementBaseInterfaceData overload: ServerMoveHandleClientError , ServerCheckClientError , ServerExceedsAllowablePositionError , ServerShouldUseAuthoritativePosition , ClientAdjustPosition Implementation , ClientVeryShortAdjustPosition Implementation , ClientAdjustRootMotionPosition Implementation , ClientAdjustRootMotionSourcePosition Implementation , OnClientCorrectionReceived (plus the non virtual RevertMove ). Override the new overload — overriding the deprecated one silently stops being called. ACharacter::BaseChange() and ACharacter::OnRep ReplicatedBasedMovement() are the notification hooks; ACharacter::GetBasedMovement() returns the FBasedMovementInfo . Movement Pipeline PerformMovement(float DeltaTime) (protected) is the autonomous path entry point; simulated proxies go through SimulatedTick , which calls PerformMovement only while root motion is active and otherwise SimulateMovement (a MoveSmooth extrapolation that skips the Phys functions). PerformMovement reaches StartNewPhysics(float deltaTime, int32 Iterations) , which dispatches on MovementMode . All Phys functions are virtual ; PhysFalling is public ( CharacterMovementComponent.h:1663 ), the other five are protected ( :1995 2007 ): Inside a Phys function: SafeMoveUpdatedComponent wraps MoveUpdatedComponent and calls ResolvePenetration on initial overlap — always prefer it inside custom Phys code. When overriding it, add using UMovementComponent::SafeMoveUpdatedComponent; next to the declaration or the FRotator overload is hidden. On a blocking hit, CMC's override of SlideAlongSurface(const FVector& Delta, float Time, const FVector& Normal, FHitResult& Hit, bool bHandleImpact) projects the remaining delta along the surface (and refuses to slide up unwalkable slopes while walking). Corner hits go through TwoWallAdjust(FVector& WorldSpaceDelta, const FHitResult& Hit, const FVector& OldHitNormal) const . During walking, ComputeGroundMovementDelta(const FVector& Delta, const FHitResult& RampHit, const bool bHitFromLineTrace) const reorients the delta along the ramp, and MaintainHorizontalGroundVelocity() flattens velocity afterwards (rescaling to preserve magnitude when bMaintainHorizontalGroundVelocity is false). SetUpdatedComponent(USceneComponent NewUpdatedComponent) is overridden on CMC; it is what binds the component being moved (the capsule) and re registers ticking. Sub stepping is bounded by MaxSimulationTimeStep and MaxSimulationIterations ; MIN TICK TIME is the floor below which a slice is discarded. CMC can also run the whole simulation on the physics thread behind the CVar p.AsyncCharacterMovement (default 0 ; the engine marks it not fully developed) through FCharacterMovementComponentAsyncInput / FCharacterMovementComponentAsyncOutput / FCharacterMovementComponentAsyncCallback — custom Phys state is not mirrored into that path automatically. Full per mode breakdowns and the async plumbing: [movement pipeline.md](references/movement pipeline.md). Floor Detection FFindFloorResult lives in CharacterMovementComponentAsync.h ( USTRUCT(BlueprintType) ), not in the CMC header: Member Meaning bBlockingHit Sweep hit something, not in initial penetration bWalkableFloor Hit surface passes the walkability test bLineTrace Result came from the line trace fallback FloorDist Distance from the swept capsule LineDist Distance from the line trace (valid only if bLineTrace ) HitResult Full FHitResult Helpers: IsWalkableFloor() ( bBlockingHit && bWalkableFloor ), GetDistanceToFloor() , Clear() , SetFromSweep() , SetFromLineTrace() . FindFloor delegates to ComputeFloorDist (downward capsule sweep, then a line trace to validate the contact point). The cached result is CurrentFloor . AdjustFloorHeight() snaps the capsule between MIN FLOOR DIST and MAX FLOOR DIST . Walkability: WalkableFloorAngle (degrees, clamped 0–90) and the derived WalkableFloorZ (default 0.71 , about 44.8 degrees). Set the angle through SetWalkableFloorAngle(float) — writing WalkableFloorZ directly desynchronises the pair. virtual bool IsWalkable(const FHitResult& Hit) const is the override point for per surface rules. Step up runs through virtual bool StepUp(const FVector& GravDir, const FVector& Delta, const FHitResult& Hit, FStepDownResult OutStepDownResult = NULL) , bounded by MaxStepHeight , with PerchRadiusThreshold and PerchAdditionalHeight controlling ledge perching. Custom Movement Modes MOVE Custom plus the uint8 CustomMovementMode gives 256 sub modes that reuse CMC's prediction pipeline. Call Super::PhysCustom(deltaTime, Iterations) first : the base implementation forwards to ACharacter::K2 UpdateCustomMovement(float DeltaTime) , so skipping it or calling it last breaks the Blueprint hook and any base bookkeeping added later. This skill is the authority on that ordering. Enter and leave a mode with SetMovementMode(MOVE Custom, static cast<uint8 (EMyMovementMode::Climbing)) and SetMovementMode(MOVE Falling) . Cap speed by overriding virtual float GetMaxSpeed() const override (the