【问题标题】:How to I use UPawnMovementComponent in Ue4 C++ instead of UFloatingPawnMovement to move a pawn?如何在 Ue4 C++ 中使用 UPawnMovementComponent 而不是 UFloatingPawnMovement 来移动棋子?
【发布时间】:2020-11-15 04:36:38
【问题描述】:

我无法弄清楚如何使用 UPawnMovementComponent 而不是 UFloatingPawnMovement 来移动棋子。每次我实现 UPawnMovementComponent 并点击播放时,编辑器都会崩溃。这是代码。

PlayerCharacter.h

    // Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "PlayerCharacter.generated.h"

UCLASS()
class LEARNING_API APlayerCharacter : public APawn
{
    GENERATED_BODY()

public:
    // Sets default values for this pawn's properties
    APlayerCharacter();

    UPROPERTY(EditAnywhere, Category = "Components")
    UStaticMeshComponent* PlayerMesh;

    UPROPERTY(EditAnywhere, Category = "Components")
    UCameraComponent* Camera;

    UPROPERTY(EditAnywhere, Category = "Components")
    USpringArmComponent* CameraArm;

    UPROPERTY(EditAnywhere, Category = "Components")
    UCapsuleComponent* CapsuleComponent;

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

    void MoveForward(float Amount);
    void MoveRight(float Amount);
    void Turn(float Amount);
    void LookUp(float Amount);

    PawnMovementComponent* PawnMovement;

public: 
    // Called every frame
    virtual void Tick(float DeltaTime) override;

    // Called to bind functionality to input
    virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

};

PlayerCharacter.cpp

    // Fill out your copyright notice in the Description page of Project Settings.


#include "PlayerCharacter.h"

// Sets default values
APlayerCharacter::APlayerCharacter()
{
    // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    // Default to Player 0
    AutoPossessPlayer = EAutoReceiveInput::Player0;

    // Player Mesh and make it a root component
    PlayerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Player Mesh"));
    RootComponent = PlayerMesh;

    // Capsule Component
    CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Component"));
    float capsule_radius = 40.f;
    float capsule_height = 80.f;
    CapsuleComponent->InitCapsuleSize(capsule_radius, capsule_height);
    CapsuleComponent->SetupAttachment(RootComponent);

    // Spring Arm Component
    CameraArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Camera Arm"));
    CameraArm->SetRelativeRotation(FRotator(0.f, 0.f, 0.f));
    CameraArm->TargetArmLength = 500.f;
    CameraArm->bEnableCameraLag = true;
    CameraArm->CameraLagSpeed = 3.f;
    CameraArm->SetupAttachment(RootComponent);

    // Camera
    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera Component"));
    Camera->SetupAttachment(CameraArm, USpringArmComponent::SocketName);

    // Player Movement Component
    PawnMovement= CreateDefaultSubobject<UPawnMovementComponent>(TEXT("Pawn Movement"));
}

// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
    Super::BeginPlay();
    
}

// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
    PlayerInputComponent->BindAxis("MoveForward", this, &APlayerCharacter::MoveForward);
    PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
    PlayerInputComponent->BindAxis("Turn", this, &APlayerCharacter::Turn);
    PlayerInputComponent->BindAxis("LookUp", this, &APlayerCharacter::LookUp);
}

void APlayerCharacter::MoveForward(float Amount)
{
    PawnMovement->AddInputVector(GetActorForwardVector() * Amount);
}

void APlayerCharacter::MoveRight(float Amount)
{
    PawnMovement->AddInputVector(GetActorRightVector() * Amount);
}

void APlayerCharacter::Turn(float Amount)
{
    AddControllerYawInput(Amount);
}

void APlayerCharacter::LookUp(float Amount)
{
    AddControllerPitchInput(Amount);
}

我想要实现 UPawnMovementComponent 而不是 UFloatingPawnMovement 的原因是因为我不想让一个浮动 pawn 在空中四处移动,我希望 pawn 只在地面上移动。我认为 UPawnMovementComponent 将允许我这样做。就像我说的,每次我实现、编译并运行它时,编辑器都会崩溃。那么有什么方法可以在编辑器不崩溃的情况下实现它。

【问题讨论】:

    标签: c++ game-engine unreal-engine4 game-development


    【解决方案1】:

    不确定你是否解决过这个问题(这个问题已经很老了),但我相信你不能直接初始化UPawnMovementComponent,你需要自己推导出来。如果您查看类声明,您可以看到UPawnMovementComponent 被标记为UCLASS(abstract)。见declaration here

    此外,如果您在调用之前尝试检查 PawnMovement 是否不是 nullptr,您将防止崩溃。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多