继承于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:


1、void 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();
    }
}

--------------------- 
作者:wenshuifuping  
来源:CSDN 
原文:https://blog.csdn.net/wenshuifuping/article/details/79197658 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值