UE4 C++(11):移動元件和碰撞

戲命屍發表於2020-10-15

10/15/2020

移動元件

UPawnMovementComponent 這個元件控制Actor的移動,比如奔跑,跳躍和蹲伏等等,通常Pawn/Character呼叫AddMovementInput函式,是轉移給移動元件完成。

圖解

Pawn元件

  • Add/ConsumInputVector函式可以把當前移動數值儲存或者消耗掉
//constructor....
// 建立移動元件的例項,並要求其更新根元件。
OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent"));
OurMovementComponent->UpdatedComponent = RootComponent;

void ACollidingPawn::MoveForward(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);
    }
}

void ACollidingPawn::MoveRight(float AxisValue)
{
    if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
    {
        OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);
    }
}


//--------------------------------------------------------------
void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

    // 確保所有事物持續有效,以便進行移動。
    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
    {
        return;
    }

    // 獲取(然後清除)ACollidingPawn::Tick中設定的移動向量
    FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;
    if (!DesiredMovementThisFrame.IsNearlyZero())
    {
        FHitResult Hit;
        SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);

        // 若發生碰撞,嘗試滑過去
        if (Hit.IsValidBlockingHit())
        {
            SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
        }
    }
  • 建立移動元件類
  • Pawn生成移動元件
  • 與移動元件建立聯絡

參考

UE4官網 元件和碰撞

相關文章