UnrealEngine4入門(二) 實現一個可用按鍵控制的球體

源碼摘自官網guide,加上部分本身的理解和註釋app

接上篇博客 本文實現一個可用WASD控制滾動的球體編輯器

先建立一個可見的球體:ide

在CollidingPawn.cpp的構造函數ACollidingPawn::ACollidingPawn()中添加一個球體,一個網格組件(mesh),一個彈簧臂和相機,代碼以下:函數

    //建立一個球體
    USphereComponent* SphereComponent = CreateDefaultSubobject<USphereComponent>(TEXT("RootComponent"));
    //設置爲根組件
    RootComponent = SphereComponent;
    //設置半徑
    SphereComponent->InitSphereRadius(40.0f);
    SphereComponent->SetCollisionProfileName(TEXT("Pawn"));

    // 建立並放置網格物體組件,這樣咱們能看到球體的位置
    UStaticMeshComponent* SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("VisualRepresentation"));
    //若是不把網格附加到SphereComponent 就看不到球體
    SphereVisual->AttachTo(RootComponent);
    static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
    if (SphereVisualAsset.Succeeded()){
        SphereVisual->SetStaticMesh(SphereVisualAsset.Object);
        SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
        SphereVisual->SetWorldScale3D(FVector(0.8f));
    }

    //  使用彈簧臂來讓相機得到一種平滑、天然的運動。
    //  彈簧臂的目的是讓視角跟SphereComponent保持必定距離,若是不加,效果像fps遊戲的第一視角同樣
    USpringArmComponent* SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraAttachmentArm"));
    SpringArm->AttachTo(RootComponent);
    SpringArm->RelativeRotation = FRotator(-45.f, 0.f, 0.f); //45度角
    SpringArm->TargetArmLength = 400.0f; //彈簧臂長度
    SpringArm->bEnableCameraLag = true;
    SpringArm->CameraLagSpeed = 3.f;

    // 建立相機並附加到彈簧臂
    // 若是沒有相機 什麼都看不到
    UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera"));
    Camera->AttachTo(SpringArm, USpringArmComponent::SocketName);

 

而後配置按鍵: 打開ue編輯器, 選擇編輯->項目設置-> 輸入, 而後在右邊的axis mappings加入以下設置:ui

MoveForWard,MoveRight,Turn,Turn_Y 可自定義,表示跟各個按鍵的綁定關係。this

而後建立一個類CollidingPawnMovementComponent繼承自PawnMovementComponent(控制pawn移動的組件),咱們能夠把WASD綁定的行爲綁定到這個component上,而後把該component綁定到咱們剛纔建立的球體上:spa

CollidingPawnMovementComponent.cppcode

#include "Demo.h"
#include "CollidingPawnMovementComponent.h"

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

    // Make sure that everything is still valid, and that we are allowed to move.
    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
    {
        return;
    }

    // Get (and then clear) the movement vector that we set in ACollidingPawn::Tick
    FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;
    if (!DesiredMovementThisFrame.IsNearlyZero())
    {
        FHitResult Hit;
        SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);

        // If we bumped into something, try to slide along it
        if (Hit.IsValidBlockingHit())
        {
            SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
        }
    }
};

而後在CollidingPawn.h中加入以下代碼:component

class UCollidingPawnMovementComponent* OurMovementComponent;

先將movementComponent綁定到剛纔加的球體上,在CollidingPawn構造函數底部加入以下代碼:orm

    // Create an instance of our movement component, and tell it to update the root.
    OurMovementComponent = CreateDefaultSubobject<UCollidingPawnMovementComponent>(TEXT("CustomMovementComponent"));
    OurMovementComponent->UpdatedComponent = RootComponent;

爲了讓遊戲中的其餘類知道CollidingPawn目前正在使用CollidingPawnMovementComponent做爲移動控制組件,須要在CollidingPawn.h中加入如下代碼:

virtual UPawnMovementComponent* GetMovementComponent() const override;

而後在CollidingPawn.cpp中加入:

UPawnMovementComponent* ACollidingPawn::GetMovementComponent() const
{
    return OurMovementComponent;
}

 剛纔咱們已經將新建立的移動控制組件綁定到了球體上,如今須要把WASD觸發的函數綁定到移動組件上,在CollidingPawn中實現往前移動,往左移動,轉動視角的三個方法:

// 往前(後)移動
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 ACollidingPawn::Turn(float AxisValue)
{
    FRotator NewRotation = GetActorRotation();
    NewRotation.Yaw += AxisValue;
    SetActorRotation(NewRotation);
}

而後將這三個方法在ACollidingPawn::SetupPlayerInputComponent中註冊:

void ACollidingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
    Super::SetupPlayerInputComponent(InputComponent);

    InputComponent->BindAxis("MoveForward", this, &ACollidingPawn::MoveForward);
    InputComponent->BindAxis("MoveRight", this, &ACollidingPawn::MoveRight);
    InputComponent->BindAxis("Turn", this, &ACollidingPawn::Turn);
}

以上就完成了一個可用WASD移動和鼠標控制左右視角的球體

若是上下移動視角,可仿照以上的ACollidingPawn::Turn方法,將NewRotation.Yaw += AxisValue; 改成NewRotation.Pitch += AxisValue;便可

相關文章
相關標籤/搜索