ue-character-movement
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseUE Character Movement
UE 角色移动
You are an expert in Unreal Engine's (CMC), the core system that drives character locomotion, floor detection, network prediction, and root motion integration. You understand the full Phys* pipeline, custom movement mode implementation, and the prediction architecture.
UCharacterMovementComponentFSavedMove_Character你是Unreal Engine中(CMC)的专家,CMC是驱动角色移动、地面检测、网络预测和根运动集成的核心系统。你熟悉完整的Phys*管线、自定义移动模式实现以及预测架构。
UCharacterMovementComponentFSavedMove_CharacterContext Check
上下文检查
Read to determine:
.agents/ue-project-context.md- Whether the project uses or a custom pawn with its own movement
ACharacter - The UE version (UE 5.4+ adds support, UE 5.5 changes
GravityDirectionsignature)DoJump - Whether multiplayer is involved (affects prediction pipeline complexity)
- Any existing CMC subclass or custom movement modes already in use
阅读以确定:
.agents/ue-project-context.md- 项目是否使用或带有自定义移动逻辑的自定义Pawn
ACharacter - UE版本(UE 5.4+新增支持,UE 5.5修改了
GravityDirection的签名)DoJump - 是否涉及多人游戏(会影响预测管线的复杂度)
- 是否已存在CMC子类或自定义移动模式
Information Gathering
信息收集
Ask the developer:
- Are you extending or configuring the default one?
UCharacterMovementComponent - Do you need custom movement modes (wall-running, climbing, dashing)?
- Is this multiplayer? If so, do custom abilities need network prediction?
- Are you integrating root motion from animations or gameplay code?
- Do you need custom gravity directions (UE 5.4+)?
询问开发者:
- 你是要扩展还是配置默认的组件?
UCharacterMovementComponent - 是否需要自定义移动模式(跑墙、攀爬、冲刺)?
- 这是多人游戏项目吗?如果是,自定义能力是否需要网络预测?
- 你是否要从动画或游戏玩法代码中集成根运动?
- 是否需要自定义重力方向(UE 5.4+)?
CMC Architecture
CMC架构
UCharacterMovementComponentUMovementComponent
-> UNavMovementComponent
-> UPawnMovementComponent
-> UCharacterMovementComponentCMC also implements and . It is declared .
IRVOAvoidanceInterfaceINetworkPredictionInterfaceUCLASS(MinimalAPI)CMC lives as a default subobject on , created in the constructor. provides the capsule, skeletal mesh, and high-level actions (, , ), while CMC handles the actual physics simulation, floor detection, and network prediction.
ACharacterACharacterJumpCrouchLaunchCharacterUCharacterMovementComponentUMovementComponent
-> UNavMovementComponent
-> UPawnMovementComponent
-> UCharacterMovementComponentCMC还实现了和,它被声明为。
IRVOAvoidanceInterfaceINetworkPredictionInterfaceUCLASS(MinimalAPI)CMC作为默认子对象存在于中,在构造函数中创建。提供碰撞胶囊、骨骼网格体和高层动作(、、),而CMC负责实际的物理模拟、地面检测和网络预测。
ACharacterACharacterJumpCrouchLaunchCharacterMovement Modes
移动模式
CMC dispatches movement logic through :
EMovementMode| Mode | Value | Description |
|---|---|---|
| 0 | No movement processing |
| 1 | Ground movement with floor detection and step-up |
| 2 | Walking driven by navmesh projection |
| 3 | Airborne — gravity, air control, landing detection |
| 4 | Fluid movement with buoyancy |
| 5 | Free 3D movement, no gravity |
| 6 | User-defined; dispatches to |
| 7 | Sentinel value |
Change modes with . The CMC calls after every transition, which is the correct place to handle enter/exit logic for custom modes.
SetMovementMode(EMovementMode, uint8 CustomMode = 0)OnMovementModeChanged(PreviousMode, PreviousCustomMode)CMC通过分发移动逻辑:
EMovementMode| 模式 | 数值 | 描述 |
|---|---|---|
| 0 | 无移动处理 |
| 1 | 带地面检测和台阶攀爬的地面移动 |
| 2 | 由导航网格投影驱动的行走 |
| 3 | 空中状态——重力、空中控制、落地检测 |
| 4 | 带浮力的流体移动 |
| 5 | 自由3D移动,无重力 |
| 6 | 用户自定义;通过 |
| 7 | 哨兵值 |
使用切换模式。每次模式切换后,CMC会调用,这是处理自定义模式进入/退出逻辑的正确位置。
SetMovementMode(EMovementMode, uint8 CustomMode = 0)OnMovementModeChanged(PreviousMode, PreviousCustomMode)Phys* Movement Pipeline
Phys*移动管线
Every tick, CMC processes movement through a strict pipeline. Understanding this flow is essential for writing correct custom movement or debugging unexpected behavior.
PerformMovement(float DeltaTime)StartNewPhysics()Phys*EMovementModePhys*protected virtual- — ground movement
PhysWalking(float deltaTime, int32 Iterations) - — navmesh-projected walking
PhysNavWalking(float deltaTime, int32 Iterations) - — airborne/gravity
PhysFalling(float deltaTime, int32 Iterations) - — fluid movement
PhysSwimming(float deltaTime, int32 Iterations) - — free flight
PhysFlying(float deltaTime, int32 Iterations) - — your code here
PhysCustom(float deltaTime, int32 Iterations)
Inside each function, two core methods do the heavy lifting:
Phys*CalcVelocitycpp
// BlueprintCallable
void CalcVelocity(float DeltaTime, float Friction, bool bFluid, float BrakingDeceleration);SafeMoveUpdatedComponentcpp
virtual bool SafeMoveUpdatedComponent(
const FVector& Delta,
const FQuat& NewRotation,
bool bSweep,
FHitResult& OutHit,
ETeleportType Teleport = ETeleportType::None
);It wraps and automatically handles depenetration if the move results in an overlap. Always prefer over in custom Phys* functions.
MoveUpdatedComponentSafeMoveUpdatedComponentMoveUpdatedComponentWhen a sweep hits a surface, projects movement along it. When hits occur in a corner (two blocking surfaces), CMC calls (virtual on ) to compute a safe movement direction that avoids both walls. During , (virtual) adjusts the velocity delta to follow the floor slope — it projects horizontal input onto the floor plane so the character walks along inclines rather than into them.
SlideAlongSurfaceTwoWallAdjustUMovementComponentPhysWalkingComputeGroundMovementDeltaSee for the full flow diagram and per-mode breakdown.
references/movement-pipeline.md每帧,CMC都会通过严格的管线处理移动。理解这一流程对于编写正确的自定义移动逻辑或调试异常行为至关重要。
PerformMovement(float DeltaTime)StartNewPhysics()EMovementModePhys*Phys*protected virtual- —— 地面移动
PhysWalking(float deltaTime, int32 Iterations) - —— 导航网格投影行走
PhysNavWalking(float deltaTime, int32 Iterations) - —— 空中/重力移动
PhysFalling(float deltaTime, int32 Iterations) - —— 流体移动
PhysSwimming(float deltaTime, int32 Iterations) - —— 自由飞行
PhysFlying(float deltaTime, int32 Iterations) - —— 自定义代码实现处
PhysCustom(float deltaTime, int32 Iterations)
每个函数内部,有两个核心方法负责主要工作:
Phys*CalcVelocitycpp
// BlueprintCallable
void CalcVelocity(float DeltaTime, float Friction, bool bFluid, float BrakingDeceleration);SafeMoveUpdatedComponentcpp
virtual bool SafeMoveUpdatedComponent(
const FVector& Delta,
const FQuat& NewRotation,
bool bSweep,
FHitResult& OutHit,
ETeleportType Teleport = ETeleportType::None
);它封装了,如果移动导致重叠,会自动处理解穿透。在自定义Phys*函数中,始终优先使用而非。
MoveUpdatedComponentSafeMoveUpdatedComponentMoveUpdatedComponent当扫查命中表面时,会将移动沿表面投影。当在角落命中两个阻挡表面时,CMC会调用(的虚函数)来计算一个安全的移动方向以避开两面墙。在中,(虚函数)会调整速度增量以适应地面坡度——它将水平输入投影到地面平面,使角色沿斜坡行走而非撞向斜坡。
SlideAlongSurfaceTwoWallAdjustUMovementComponentPhysWalkingComputeGroundMovementDelta完整的流程图和各模式的详细分解可查看。
references/movement-pipeline.mdFloor Detection
地面检测
CMC's walking mode relies on continuous floor detection to determine whether the character is grounded.
CMC的行走模式依赖持续的地面检测来判断角色是否处于地面。
FFindFloorResult
FFindFloorResult
cpp
struct FFindFloorResult
{
uint32 bBlockingHit : 1; // Sweep hit something
uint32 bWalkableFloor : 1; // Hit surface passes walkability test
uint32 bLineTrace : 1; // Result came from line trace (not sweep)
float FloorDist; // Distance from capsule bottom to floor
float LineDist; // Distance from line trace
FHitResult HitResult; // Full hit result data
bool IsWalkableFloor() const { return bBlockingHit && bWalkableFloor; }
};cpp
struct FFindFloorResult
{
uint32 bBlockingHit : 1; // 扫查命中物体
uint32 bWalkableFloor : 1; // 命中表面通过可行走测试
uint32 bLineTrace : 1; // 结果来自线迹检测(而非扫查)
float FloorDist; // 胶囊底部到地面的距离
float LineDist; // 线迹检测的距离
FHitResult HitResult; // 完整的命中结果数据
bool IsWalkableFloor() const { return bBlockingHit && bWalkableFloor; }
};Floor Detection Methods
地面检测方法
FindFloorcpp
void FindFloor(
const FVector& CapsuleLocation,
FFindFloorResult& OutFloorResult,
bool bCanUseCachedLocation,
const FHitResult* DownwardSweepResult = nullptr
);It delegates to , which performs a downward capsule sweep followed by a line trace. The sweep finds the floor surface, and the line trace validates walkability at the exact contact point.
ComputeFloorDist()FindFloorcpp
void FindFloor(
const FVector& CapsuleLocation,
FFindFloorResult& OutFloorResult,
bool bCanUseCachedLocation,
const FHitResult* DownwardSweepResult = nullptr
);它委托给,后者先执行向下的胶囊扫查,再执行线迹检测。扫查用于找到地面表面,线迹检测用于验证接触点的可行走性。
ComputeFloorDist()Walkable Floor Angle
可行走地面角度
Two linked properties control what counts as "walkable":
- (default 44.765 degrees) — the maximum surface angle in degrees
WalkableFloorAngle - — the corresponding Z component of the surface normal (auto-calculated from the angle)
WalkableFloorZ
Set the angle, not the Z value directly. updates both.
SetWalkableFloorAngle()有两个关联属性控制“可行走”的判定:
- (默认44.765度)—— 最大表面角度(以度为单位)
WalkableFloorAngle - —— 对应表面法线的Z分量(由角度自动计算)
WalkableFloorZ
请设置角度,而非直接设置Z值。会同时更新这两个属性。
SetWalkableFloorAngle()Custom Movement Modes
自定义移动模式
MOVE_Customuint8带有子模式的是添加新移动类型的标准方式。这允许你在复用CMC完整网络预测管线的同时,最多添加256种自定义模式。
uint8MOVE_CustomImplementation Steps
实现步骤
- Define custom mode constants:
cpp
UENUM(BlueprintType)
enum class ECustomMovementMode : uint8
{
WallRun = 0,
Climb = 1,
Dash = 2
};- Override in your CMC subclass:
PhysCustom
cpp
virtual void PhysCustom(float deltaTime, int32 Iterations) override;- Enter the mode using :
SetMovementMode
cpp
SetMovementMode(MOVE_Custom, static_cast<uint8>(ECustomMovementMode::WallRun));- Handle transitions in :
OnMovementModeChanged
cpp
virtual void OnMovementModeChanged(EMovementMode PrevMode, uint8 PrevCustomMode) override;Inside , dispatch on and implement your simulation. Call for acceleration, for capsule movement, and when transitioning out.
PhysCustomCustomMovementModeCalcVelocitySafeMoveUpdatedComponentSetMovementModeSee for a complete wall-run implementation.
references/cmc-extension-patterns.md- 定义自定义模式常量:
cpp
UENUM(BlueprintType)
enum class ECustomMovementMode : uint8
{
WallRun = 0,
Climb = 1,
Dash = 2
};- 在你的CMC子类中重写:
PhysCustom
cpp
virtual void PhysCustom(float deltaTime, int32 Iterations) override;- 使用进入模式:
SetMovementMode
cpp
SetMovementMode(MOVE_Custom, static_cast<uint8>(ECustomMovementMode::WallRun));- 在中处理模式切换:
OnMovementModeChanged
cpp
virtual void OnMovementModeChanged(EMovementMode PrevMode, uint8 PrevCustomMode) override;在内部,根据分发逻辑并实现你的模拟。调用处理加速度,处理胶囊移动,在切换模式时调用。
PhysCustomCustomMovementModeCalcVelocitySafeMoveUpdatedComponentSetMovementMode完整的跑墙实现可查看。
references/cmc-extension-patterns.mdNetwork Prediction
网络预测
CMC uses a client-side prediction and server reconciliation model. The client runs movement locally, saves inputs, sends them to the server, and corrects if the server disagrees. This is why custom movement must integrate with the prediction pipeline to work in multiplayer.
CMC使用客户端预测和服务器校正模型。客户端本地运行移动逻辑,保存输入,发送到服务器,并在服务器结果不一致时进行修正。这就是为什么自定义移动必须集成到预测管线中才能在多人游戏中正常工作。
FSavedMove_Character
FSavedMove_Character
Each client tick generates a saved move that records the input state:
Key fields: , , , , , , .
bPressedJumpbWantsToCrouchStartLocationStartVelocitySavedLocationAccelerationMaxSpeedKey virtuals to override for custom data:
- — reset your custom fields
Clear() - — capture your custom state from the CMC before the move executes
SetMoveFor(ACharacter*, float, FVector const&, FNetworkPredictionData_Client_Character&) - — restore your custom state before replaying a move
PrepMoveFor(ACharacter*) - — pack custom booleans into the
GetCompressedFlags() constflagsuint8 - — return
CanCombineWith(const FSavedMovePtr&, ACharacter*, float)only if two moves are identical (enables bandwidth optimization)true - — called after the move executes
PostUpdate(ACharacter*, EPostUpdateMode) - — prevent combining if this move carries significant state
IsImportantMove(const FSavedMovePtr&)
客户端每帧都会生成一个保存的移动记录,用于记录输入状态:
关键字段:、、、、、、。
bPressedJumpbWantsToCrouchStartLocationStartVelocitySavedLocationAccelerationMaxSpeed用于自定义数据的关键虚函数:
- —— 重置自定义字段
Clear() - —— 在移动执行前从CMC捕获自定义状态
SetMoveFor(ACharacter*, float, FVector const&, FNetworkPredictionData_Client_Character&) - —— 在重放移动前恢复自定义状态
PrepMoveFor(ACharacter*) - —— 将自定义布尔值打包到
GetCompressedFlags() const标志中uint8 - —— 仅当两个移动完全相同时返回
CanCombineWith(const FSavedMovePtr&, ACharacter*, float)(优化带宽)true - —— 移动执行后调用
PostUpdate(ACharacter*, EPostUpdateMode) - —— 如果移动携带重要状态,禁止合并
IsImportantMove(const FSavedMovePtr&)
CompressedFlags
压缩标志
The returned by has a fixed layout:
uint8GetCompressedFlags| Flag | Value | Purpose |
|---|---|---|
| | Jump input |
| | Crouch input |
| | Engine reserved |
| | Engine reserved |
| | Your custom flag |
| | Your custom flag |
| | Your custom flag |
| | Your custom flag |
You get four custom bits. For more complex state, use .
FCharacterNetworkMoveDataGetCompressedFlagsuint8| 标志 | 数值 | 用途 |
|---|---|---|
| | 跳跃输入 |
| | 蹲伏输入 |
| | 引擎保留 |
| | 引擎保留 |
| | 自定义标志 |
| | 自定义标志 |
| | 自定义标志 |
| | 自定义标志 |
你有4个自定义位。对于更复杂的状态,使用。
FCharacterNetworkMoveDataFNetworkPredictionData_Client_Character
FNetworkPredictionData_Client_Character
Override to return your custom subclass:
AllocateNewMove()FSavedMovecpp
class FMyNetworkPredictionData : public FNetworkPredictionData_Client_Character
{
public:
FMyNetworkPredictionData(const UCharacterMovementComponent& ClientMovement)
: FNetworkPredictionData_Client_Character(ClientMovement) {}
virtual FSavedMovePtr AllocateNewMove() override;
};The CMC exposes this via , which you override to lazy-init your custom prediction data class.
GetPredictionData_Client()重写以返回自定义的子类:
AllocateNewMove()FSavedMovecpp
class FMyNetworkPredictionData : public FNetworkPredictionData_Client_Character
{
public:
FMyNetworkPredictionData(const UCharacterMovementComponent& ClientMovement)
: FNetworkPredictionData_Client_Character(ClientMovement) {}
virtual FSavedMovePtr AllocateNewMove() override;
};CMC通过暴露此接口,你需要重写该函数以延迟初始化自定义预测数据类。
GetPredictionData_Client()Modern Packed RPCs
现代打包RPC
UE5 uses packed move RPCs on :
ACharacter- — client to server
ServerMovePacked(FCharacterServerMovePackedBits) - — server to client
ClientMoveResponsePacked(FCharacterMoveResponsePackedBits)
The old RPCs (, , ) are . For custom network data beyond CompressedFlags, derive (override , ), derive , and call in your CMC constructor.
ServerMoveServerMoveDualClientAdjustPositionDEPRECATED_CHARACTER_MOVEMENT_RPCFCharacterNetworkMoveDataClientFillNetworkMoveDataSerializeFCharacterNetworkMoveDataContainerSetNetworkMoveDataContainer()See for full FSavedMove and network data implementation templates.
references/cmc-extension-patterns.mdUE5在上使用打包移动RPC:
ACharacter- —— 客户端到服务器
ServerMovePacked(FCharacterServerMovePackedBits) - —— 服务器到客户端
ClientMoveResponsePacked(FCharacterMoveResponsePackedBits)
旧版RPC(、、)已标记为。对于超出压缩标志的自定义网络数据,继承(重写、),继承,并在CMC构造函数中调用。
ServerMoveServerMoveDualClientAdjustPositionDEPRECATED_CHARACTER_MOVEMENT_RPCFCharacterNetworkMoveDataClientFillNetworkMoveDataSerializeFCharacterNetworkMoveDataContainerSetNetworkMoveDataContainer()完整的FSavedMove和网络数据实现模板可查看。
references/cmc-extension-patterns.mdRoot Motion
根运动
Root motion allows animations or gameplay code to drive character movement directly. CMC integrates root motion through and its subclasses.
FRootMotionSource根运动允许动画或游戏玩法代码直接驱动角色移动。CMC通过及其子类集成根运动。
FRootMotionSourceFRootMotionSource
FRootMotionSource
Base class fields:
- — higher priority sources override lower
Priority - — unique ID returned by
LocalIDApplyRootMotionSource - —
InstanceNamefor retrieval and removalFName - — total time in seconds; negative Duration means infinite (runs until explicitly removed)
Duration - —
AccumulateMode(replaces other sources) orOverride(stacks)Additive
基类字段:
- —— 优先级高的源会覆盖优先级低的源
Priority - ——
LocalID返回的唯一IDApplyRootMotionSource - —— 用于检索和移除的
InstanceNameFName - —— 总时长(秒);负值表示无限时长(需显式移除才会停止)
Duration - ——
AccumulateMode(替换其他源)或Override(叠加)Additive
Subclasses
子类
| Class | Key Parameters | Use Case |
|---|---|---|
| | Knockback, wind |
| | Explosions, vortex |
| | Dash to fixed point |
| | Homing dash |
| | Targeted jump arc |
| 类 | 关键参数 | 使用场景 |
|---|---|---|
| | 击退、风力 |
| | 爆炸、漩涡 |
| | 冲刺到固定点 |
| | 追踪冲刺 |
| | 目标跳跃弧线 |
CMC Methods
CMC方法
cpp
// Returns uint16 LocalID for tracking
uint16 ApplyRootMotionSource(TSharedPtr<FRootMotionSource> Source);
// Retrieve by InstanceName
TSharedPtr<FRootMotionSource> GetRootMotionSource(FName InstanceName);
// Remove by InstanceName
void RemoveRootMotionSource(FName InstanceName);Apply a constant knockback:
cpp
auto Knockback = MakeShared<FRootMotionSource_ConstantForce>();
Knockback->InstanceName = TEXT("Knockback");
Knockback->Duration = 0.3f;
Knockback->Force = KnockbackDirection * KnockbackStrength;
Knockback->AccumulateMode = ERootMotionAccumulateMode::Override;
CMC->ApplyRootMotionSource(Knockback);cpp
// 返回用于追踪的uint16 LocalID
uint16 ApplyRootMotionSource(TSharedPtr<FRootMotionSource> Source);
// 通过InstanceName检索
TSharedPtr<FRootMotionSource> GetRootMotionSource(FName InstanceName);
// 通过InstanceName移除
void RemoveRootMotionSource(FName InstanceName);应用持续击退效果:
cpp
auto Knockback = MakeShared<FRootMotionSource_ConstantForce>();
Knockback->InstanceName = TEXT("Knockback");
Knockback->Duration = 0.3f;
Knockback->Force = KnockbackDirection * KnockbackStrength;
Knockback->AccumulateMode = ERootMotionAccumulateMode::Override;
CMC->ApplyRootMotionSource(Knockback);Key Properties
关键属性
| Property | Default | Description |
|---|---|---|
| 600 | Maximum ground speed |
| — | Rate of speed change |
| 1.0 | Multiplier on world gravity |
| — | Initial vertical velocity on jump |
| — | Lateral control while falling (0-1) |
| — | Friction on ground surfaces |
| — | Deceleration when no input on ground |
| — | Maximum height of obstacles to step over |
| 44.765 | Max walkable surface angle in degrees |
| — | Speed while crouching |
| — | Maximum speed in water |
| — | Maximum speed when flying |
| — | Speed cap for custom modes |
| — | Rotate character toward movement direction |
| — | Smoothly rotate toward controller rotation |
| — | Simulated proxy interpolation mode |
| — | Cap on sub-step delta for stability |
| — | Max physics iterations per frame |
| false | Enable RVO (reciprocal velocity obstacle) avoidance |
| — | |
| — | float — higher weight yields right-of-way to other agents |
| 属性 | 默认值 | 描述 |
|---|---|---|
| 600 | 最大地面移动速度 |
| — | 速度变化率 |
| 1.0 | 世界重力的乘数 |
| — | 跳跃时的初始垂直速度 |
| — | 下落时的横向控制(0-1) |
| — | 地面表面的摩擦力 |
| — | 地面无输入时的减速度 |
| — | 可攀爬的障碍物最大高度 |
| 44.765 | 最大可行走表面角度(度) |
| — | 蹲伏时的速度 |
| — | 水中最大速度 |
| — | 飞行时的最大速度 |
| — | 自定义模式的速度上限 |
| — | 使角色朝向移动方向旋转 |
| — | 平滑地朝向控制器旋转方向 |
| — | 模拟代理的插值模式 |
| — | 子步delta的上限,保证稳定性 |
| — | 每帧最大物理迭代次数 |
| false | 启用RVO(相对速度障碍物)避让 |
| — | |
| — | float —— 权重越高,越优先获得通行权 |
Rotation
旋转
bOrientRotationToMovementbUseControllerDesiredRotationbOrientRotationToMovementbUseControllerDesiredRotationGravity Direction (UE 5.4+)
重力方向(UE 5.4+)
cpp
virtual void SetGravityDirection(const FVector& GravityDir);
FVector GetGravityDirection() const;
bool HasCustomGravity() const;
// Transform helpers (fields are protected — access via accessors)
FQuat GetWorldToGravityTransform() const;
FQuat GetGravityToWorldTransform() const;Custom gravity reorients the entire movement simulation. Walking, falling, and floor detection all respect the gravity direction when returns .
HasCustomGravity()truecpp
virtual void SetGravityDirection(const FVector& GravityDir);
FVector GetGravityDirection() const;
bool HasCustomGravity() const;
// 变换助手(字段受保护——通过访问器访问)
FQuat GetWorldToGravityTransform() const;
FQuat GetGravityToWorldTransform() const;自定义重力会重新调整整个移动模拟。当返回时,行走、下落和地面检测都会遵循重力方向。
HasCustomGravity()trueACharacter API
ACharacter API
ACharacterACharacterJump
跳跃
cpp
void Jump(); // Sets bPressedJump, CMC handles velocity
void StopJumping(); // Clears jump input
bool CanJump() const; // Checks CanJumpInternalProperties: , , , .
bPressedJumpJumpMaxHoldTimeJumpMaxCountJumpCurrentCountDoJump(bool bReplayingMoves, float DeltaTime)DoJump(bool)cpp
void Jump(); // 设置bPressedJump,CMC处理速度
void StopJumping(); // 清除跳跃输入
bool CanJump() const; // 检查CanJumpInternal属性:、、、。
bPressedJumpJumpMaxHoldTimeJumpMaxCountJumpCurrentCountDoJump(bool bReplayingMoves, float DeltaTime)DoJump(bool)Crouch
蹲伏
cpp
void Crouch(bool bClientSimulation = false);
void UnCrouch(bool bClientSimulation = false);bIsCrouchedCrouchedHalfHeightSetCrouchedHalfHeight()GetCrouchedHalfHeight()cpp
void Crouch(bool bClientSimulation = false);
void UnCrouch(bool bClientSimulation = false);bIsCrouchedCrouchedHalfHeightSetCrouchedHalfHeight()GetCrouchedHalfHeight()LaunchCharacter
角色发射
cpp
void LaunchCharacter(FVector LaunchVelocity, bool bXYOverride, bool bZOverride);When is , replaces XY velocity entirely. When , adds to existing velocity. Same logic for on the Z axis. Automatically transitions to .
bXYOverridetruefalsebZOverrideMOVE_Fallingcpp
void LaunchCharacter(FVector LaunchVelocity, bool bXYOverride, bool bZOverride);当为时,完全替换XY速度;为时,叠加到现有速度上。Z轴的逻辑相同。会自动切换到模式。
bXYOverridetruefalseMOVE_FallingLanded
落地
cpp
virtual void Landed(const FHitResult& Hit);Called when the character lands after falling. Override this for landing effects, damage, or animation triggers.
cpp
virtual void Landed(const FHitResult& Hit);角色从空中落地时调用。可重写此函数以实现落地效果、伤害或动画触发。
Accessors
访问器
cpp
UCharacterMovementComponent* GetCharacterMovement() const;
UCapsuleComponent* GetCapsuleComponent() const;
USkeletalMeshComponent* GetMesh() const;cpp
UCharacterMovementComponent* GetCharacterMovement() const;
UCapsuleComponent* GetCapsuleComponent() const;
USkeletalMeshComponent* GetMesh() const;Common Mistakes
常见错误
Modifying velocity directly instead of using CalcVelocity:
cpp
// WRONG: Bypasses friction, braking, and acceleration curves
Velocity = GetLastInputVector() * MaxWalkSpeed;
// RIGHT: Let CMC handle physics
CalcVelocity(DeltaTime, GroundFriction, false, BrakingDecelerationWalking);Forgetting to call Super in PhysCustom:
cpp
// WRONG: Skips base class bookkeeping
void UMyCMC::PhysCustom(float DT, int32 Iter)
{
MyCustomLogic(DT, Iter);
}
// RIGHT: Call Super first (base PhysCustom is empty but future-proofs)
void UMyCMC::PhysCustom(float DT, int32 Iter)
{
Super::PhysCustom(DT, Iter);
MyCustomLogic(DT, Iter);
}Not saving custom state in FSavedMove:
Custom movement flags that are not captured in and restored in will be lost during server correction replays, causing desyncs.
SetMoveForPrepMoveForUsing MoveUpdatedComponent instead of SafeMoveUpdatedComponent:
does not resolve penetration. In custom Phys* functions, always use to prevent the character from getting stuck inside geometry.
MoveUpdatedComponentSafeMoveUpdatedComponentSetting both rotation flags:
and conflict. The character oscillates between two desired rotations each frame. Pick one based on your camera style.
bOrientRotationToMovementbUseControllerDesiredRotationUsing deprecated old-style RPCs:
, , are . Use the packed RPC pipeline and for custom data.
ServerMoveServerMoveDualClientAdjustPositionDEPRECATED_CHARACTER_MOVEMENT_RPCFCharacterNetworkMoveData直接修改速度而非使用CalcVelocity:
cpp
// 错误:绕过了摩擦力、制动和加速度曲线
Velocity = GetLastInputVector() * MaxWalkSpeed;
// 正确:让CMC处理物理逻辑
CalcVelocity(DeltaTime, GroundFriction, false, BrakingDecelerationWalking);在PhysCustom中忘记调用Super:
cpp
// 错误:跳过了基类的簿记工作
void UMyCMC::PhysCustom(float DT, int32 Iter)
{
MyCustomLogic(DT, Iter);
}
// 正确:先调用Super(基类PhysCustom为空,但这样做可兼容未来版本)
void UMyCMC::PhysCustom(float DT, int32 Iter)
{
Super::PhysCustom(DT, Iter);
MyCustomLogic(DT, Iter);
}未在FSavedMove中保存自定义状态:
未在中捕获并在中恢复的自定义移动标志,会在服务器校正重放时丢失,导致不同步。
SetMoveForPrepMoveFor使用MoveUpdatedComponent而非SafeMoveUpdatedComponent:
不会解决穿透问题。在自定义Phys*函数中,始终使用以防止角色卡在几何体内部。
MoveUpdatedComponentSafeMoveUpdatedComponent同时设置两个旋转标志:
和会冲突。角色每帧会在两个期望旋转之间振荡。请根据你的相机风格选择其中一个。
bOrientRotationToMovementbUseControllerDesiredRotation使用已弃用的旧版RPC:
、、已标记为。对于自定义数据,请使用打包RPC管线和。
ServerMoveServerMoveDualClientAdjustPositionDEPRECATED_CHARACTER_MOVEMENT_RPCFCharacterNetworkMoveDataReference Files
参考文件
- — Complete CMC subclass templates: custom FSavedMove, prediction data, GetPredictionData_Client, wall-run PhysCustom, and custom network move data
references/cmc-extension-patterns.md - — Phys* flow diagrams, floor detection chain, step-up logic, PhysWalking/PhysFalling breakdowns, and root motion replication flow
references/movement-pipeline.md
- —— 完整的CMC子类模板:自定义FSavedMove、预测数据、GetPredictionData_Client、跑墙PhysCustom和自定义网络移动数据
references/cmc-extension-patterns.md - —— Phys*流程图、地面检测链、台阶攀爬逻辑、PhysWalking/PhysFalling分解以及根运动复制流程
references/movement-pipeline.md
Related Skills
相关技能
- — Replication fundamentals, RPCs, net roles; CMC prediction builds on this
ue-networking-replication - — Root motion from AnimMontage, animation-driven movement
ue-animation-system - — Sweep queries, collision channels used by CMC floor detection
ue-physics-collision - — GAS abilities that trigger movement modes or root motion
ue-gameplay-abilities - — NavMesh integration, MOVE_NavWalking, RVO avoidance
ue-ai-navigation - — Enhanced Input feeding movement input to CMC
ue-input-system - — Component subobject patterns for CMC subclasses
ue-actor-component-architecture
- —— 复制基础、RPC、网络角色;CMC预测基于此构建
ue-networking-replication - —— 来自AnimMontage的根运动、动画驱动的移动
ue-animation-system - —— 扫查查询、CMC地面检测使用的碰撞通道
ue-physics-collision - —— 触发移动模式或根运动的GAS能力
ue-gameplay-abilities - —— NavMesh集成、MOVE_NavWalking、RVO避让
ue-ai-navigation - —— 增强输入系统向CMC提供移动输入
ue-input-system - —— CMC子类的组件子对象模式
ue-actor-component-architecture