繼承於APawn的控制器

新建一個基於C++的工程MyProject,默認會創建遊戲模式類AMyProjectGameModeBase,如果自己沒有創建Pawn,DefaultPawnClass就會默認爲ADefaultPawn類,打包後會出現一些問題。比如想按下鼠標左鍵沿X軸或者Y軸旋轉,代碼做了相應操作,結果卻會不按下鼠標左鍵就會旋轉,不是我們想要的。自己寫一個Pawn好控制些。這裏只做一些簡單的操控,鼠標左鍵按下可以左右、上下翻轉,鼠標滾輪滾動可以拉遠拉近。

AManipulator.h

#pragma once

#include "GameFramework/Pawn.h"
#include "Manipulator.generated.h"


UCLASS()
class MYPROJECT_API AManipulator : public APawn
{
	GENERATED_UCLASS_BODY()

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

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

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

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

	virtual void UpdateNavigationRelevance() override;

	virtual void MouseX(float Val);

	virtual void MouseY(float Val);

	virtual void MouseScrollUp();

	virtual void MouseScrollDown();

protected:
	float BaseTurnRate;
	float BaseSpeed;
	UPawnMovementComponent* MovementComponent;
	USphereComponent* CollisionComponent;
};

AManipulator.cpp

#include "MyProject.h"
#include "Manipulator.h"

void InitializeInputBindings()
{
	static bool bBindingsAdded = false;
	if (!bBindingsAdded)
	{
		bBindingsAdded = true;
	
		UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Manipulator_MouseX", EKeys::MouseX, 1.f));
		UPlayerInput::AddEngineDefinedAxisMapping(FInputAxisKeyMapping("Manipulator_MouseY", EKeys::MouseY, -1.f));
		UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("Manipulator_MouseScrollUp", EKeys::MouseScrollUp));
		UPlayerInput::AddEngineDefinedActionMapping(FInputActionKeyMapping("Manipulator_MouseScrollDown", EKeys::MouseScrollDown));
	}
}

AManipulator::AManipulator(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	PrimaryActorTick.bCanEverTick = true;
	BaseTurnRate = 45.f;
	CollisionComponent = CreateDefaultSubobject<USphereComponent>(FName(TEXT("CollisionComponent0")));
	CollisionComponent->InitSphereRadius(5.0f);
	CollisionComponent->SetCollisionProfileName(UCollisionProfile::Pawn_ProfileName);

	CollisionComponent->CanCharacterStepUpOn = ECB_No;
	CollisionComponent->bShouldUpdatePhysicsVolume = true;
	CollisionComponent->SetCanEverAffectNavigation(false);
	CollisionComponent->bDynamicObstacle = true;

	RootComponent = CollisionComponent;

	MovementComponent = CreateDefaultSubobject<UPawnMovementComponent, USpectatorPawnMovement>(FName(TEXT("MovementComponent0")));
	MovementComponent->UpdatedComponent = CollisionComponent;
	this->BaseEyeHeight = 2.0;
}

void AManipulator::BeginPlay()
{
	Super::BeginPlay();

}

void AManipulator::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void AManipulator::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	check(PlayerInputComponent);
	InitializeInputBindings();

	PlayerInputComponent->BindAxis("Manipulator_MouseX", this, &AManipulator::MouseX);
	PlayerInputComponent->BindAxis("Manipulator_MouseY", this, &AManipulator::MouseY);
	PlayerInputComponent->BindAction("Manipulator_MouseScrollUp", IE_Pressed, this, &AManipulator::MouseScrollUp);
	PlayerInputComponent->BindAction("Manipulator_MouseScrollDown", IE_Pressed, this, &AManipulator::MouseScrollDown);
}

UPawnMovementComponent* AManipulator::GetMovementComponent() const
{
	return MovementComponent;
}

void AManipulator::UpdateNavigationRelevance()
{
	if (CollisionComponent)
	{
		CollisionComponent->SetCanEverAffectNavigation(bCanAffectNavigationGeneration);
	}
}

void AManipulator::MouseScrollUp()
{
	APlayerController* PC = Cast<APlayerController>(GetController());
	if (PC)
	{
		FRotator const ControlSpaceRot = PC->GetControlRotation();
		AddMovementInput(FRotationMatrix(ControlSpaceRot).GetScaledAxis(EAxis::X), 10.0);
	}
}

void AManipulator::MouseScrollDown()
{
	APlayerController* PC = Cast<APlayerController>(GetController());
	if (PC)
	{
		FRotator const ControlSpaceRot = PC->GetControlRotation();
		AddMovementInput(FRotationMatrix(ControlSpaceRot).GetScaledAxis(EAxis::X), -10.0);
	}
}

void AManipulator::MouseX(float Val)
{
	if (Val != 0.0f && GetController())
	{
		APlayerController* PC = Cast<APlayerController>(GetController());
		if (PC)
		{
			if (PC->IsInputKeyDown(EKeys::LeftMouseButton))
			{
				PC->AddYawInput(Val);
			}
		}
	}
}

void AManipulator::MouseY(float Val)
{
	if (Val != 0.0f && GetController())
	{
		APlayerController* PC = Cast<APlayerController>(GetController());
		if (PC)
		{
			if (PC->IsInputKeyDown(EKeys::LeftMouseButton))
			{
				PC->AddPitchInput(Val);
			}
		}
	}
}

TIPS:


1void AManipulator::MouseX(float Val)和void AManipulator::MouseY(float Val)

if(PC->IsInputKeyDown(EKeys::LeftMouseButton))要想生效,項目設置中的輸入選項需要按照如下設置。


2、MyProjectGameModeBase中把DefaultPawnClass設爲自己寫的Pawn類AManipulator。

AMyProjectGameModeBase.cpp

#include "MyProject.h"
#include "MyProjectGameModeBase.h"
#include "MyHUD.h"
#include "Manipulator.h"

AMyProjectGameModeBase:: AMyProjectGameModeBase (const FObjectInitializer& ObjectInitializer)
{
	if ((GEngine != nullptr) && (GEngine->GameViewport != nullptr))
	{
		DefaultPawnClass = AManipulator::StaticClass();
		this->HUDClass = AMyHUD::StaticClass();
	}
}






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章