美文网首页
UE4 CharacterMovementComponent w

UE4 CharacterMovementComponent w

作者: 我真的不知道该起什么名字了 | 来源:发表于2019-06-14 17:53 被阅读0次

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);
}

相关文章

网友评论

      本文标题:UE4 CharacterMovementComponent w

      本文链接:https://www.haomeiwen.com/subject/ebppfctx.html