源碼摘自官網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;便可