UE4 里面, 继承自Actor的这种实体, 并没有具体的功能, 它把内部的Component组合起来, 放在场景中表现.
UE4中Component作为具体功能的载体, 每个具体的功能, 都是一个Component类.
在Component中, Tick驱动该Component的工作.
CharacterMovementComponent的工作原则:
使用加速度驱动速度, 通过速度表现具体Actor的移动, 而我们能做的就是输入当前加速度的方向和最大加速度的百分比:
void APawn::AddMovementInput(FVector WorldDirection, float ScaleValue, bool bForce /*=false*/)
{
UPawnMovementComponent* MovementComponent = GetMovementComponent();
if (MovementComponent)
{
MovementComponent->AddInputVector(WorldDirection * ScaleValue, bForce);
}
else
{
Internal_AddMovementInput(WorldDirection * ScaleValue, bForce);
}
}
CharacterMovementComponent 通过TickComponent, 毎帧对输入进行消耗.
对于CharacterMovementComponent, TickComponent中关键代码:
void UCharacterMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
SCOPED_NAMED_EVENT(UCharacterMovementComponent_TickComponent, FColor::Yellow);
SCOPE_CYCLE_COUNTER(STAT_CharacterMovement);
SCOPE_CYCLE_COUNTER(STAT_CharacterMovementTick);
CSV_SCOPED_TIMING_STAT_EXCLUSIVE(CharacterMovement);
// 1189行: 毎帧消耗所有输入
const FVector InputVector = ConsumeInputVector();
if (!HasValidData() || ShouldSkipUpdate(DeltaTime))
{
return;
}
...
if( CharacterOwner->IsLocallyControlled() || (!CharacterOwner->Controller && bRunPhysicsWithNoController) || (!CharacterOwner->Controller && CharacterOwner->IsPlayingRootMotion()) )
{
{
SCOPE_CYCLE_COUNTER(STAT_CharUpdateAcceleration);
// We need to check the jump state before adjusting input acceleration, to minimize latency
// and to make sure acceleration respects our potentially new falling state.
CharacterOwner->CheckJumpInput(DeltaTime);
// apply input to acceleration 1251行:根据输入的值, 计算加速度.
// 从这里可以看出,加速度是毎帧清零的, 不输入, 就没有加速度
Acceleration = ScaleInputAcceleration(ConstrainInputAcceleration(InputVector));
AnalogInputModifier = ComputeAnalogInputModifier();
}
if (CharacterOwner->Role == ROLE_Authority)
{
// 1257行, 执行具体的客户端本地移动
PerformMovement(DeltaTime);
}
else if (bIsClient)
{
ReplicateMoveToServer(DeltaTime, Acceleration);
}
}
}
void UCharacterMovementComponent::PerformMovement(float DeltaSeconds)
{
.....
// 2162行, 如果通过LaunchCharacter 进行了速度设定, 直接替换成该速度,
// 并且不会进行最大速度限制的检测, 即你输入的是什么, 就设置为什么.
// Character::LaunchCharacter() has been deferred until now.
HandlePendingLaunch();
// change position 2302行, 这里进行位置的更新
StartNewPhysics(DeltaSeconds, 0);
// 2314行, 这里进行旋转的更新.
if ((bAllowPhysicsRotationDuringAnimRootMotion || !HasAnimRootMotion()) && !CharacterOwner->IsMatineeControlled())
{
PhysicsRotation(DeltaSeconds);
}
}
// 根据MovementMode类型的不同, 执行不同逻辑.
void UCharacterMovementComponent::StartNewPhysics(float deltaTime, int32 Iterations)
{
if ((deltaTime < MIN_TICK_TIME) || (Iterations >= MaxSimulationIterations) || !HasValidData())
{
return;
}
if (UpdatedComponent->IsSimulatingPhysics())
{
UE_LOG(LogCharacterMovement, Log, TEXT("UCharacterMovementComponent::StartNewPhysics: UpdateComponent (%s) is simulating physics - aborting."), *UpdatedComponent->GetPathName());
return;
}
const bool bSavedMovementInProgress = bMovementInProgress;
bMovementInProgress = true;
switch ( MovementMode )
{
case MOVE_None:
break;
case MOVE_Walking:
PhysWalking(deltaTime, Iterations);
break;
case MOVE_NavWalking:
PhysNavWalking(deltaTime, Iterations);
break;
case MOVE_Falling:
PhysFalling(deltaTime, Iterations);
break;
case MOVE_Flying:
PhysFlying(deltaTime, Iterations);
break;
case MOVE_Swimming:
PhysSwimming(deltaTime, Iterations);
break;
case MOVE_Custom:
PhysCustom(deltaTime, Iterations);
break;
default:
UE_LOG(LogCharacterMovement, Warning, TEXT("%s has unsupported movement mode %d"), *CharacterOwner->GetName(), int32(MovementMode));
SetMovementMode(MOVE_None);
break;
}
bMovementInProgress = bSavedMovementInProgress;
if ( bDeferUpdateMoveComponent )
{
SetUpdatedComponent(DeferredUpdatedMoveComponent);
}
}
void UCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iterations)
{
....................
// try to move forward 4722行, 进行位置更新
MoveAlongFloor(MoveVelocity, timeTick, &StepDownResult);
}
void UCharacterMovementComponent::MoveAlongFloor(const FVector& InVelocity, float DeltaSeconds, FStepDownResult* OutStepDownResult)
{
..............
// 4563行, 进行位置更新
SafeMoveUpdatedComponent(RampVector, UpdatedComponent->GetComponentQuat(), true, Hit);
}
网友评论