C++で入力を検知する2つの方法

はじめに

今回は、C++でキー入力を検知してログを表示するプログラムを2つご紹介します。
どちらが良いというわけではなく、時と場合によって使いわけるようにしましょう。

1つめの方法

1つめはSetupPlayerInputComponentにて入力されたキーと関数を紐付けて取得する方法です。
APlayerController::ClientRestartに引数として渡したポーンまたはGameModeのコンストラクタでDefaultPawnClassに設定したポーンだけSetupPlayerInputComponentでバインドしたキー入力が受け取ることができます。
入力を受け取るポーンを切り替えたい時にこれを使うと良いです。

MyPawn.h

#pragma once

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

UCLASS()
class MYPROJECT2_API AMyPawn : public APawn
{
    GENERATED_BODY()

public:
    AMyPawn();
    virtual void BeginPlay() override;
    virtual void Tick( float DeltaSeconds ) override;
    virtual void SetupPlayerInputComponent( class UInputComponent* InputComponent ) override;

private:
    void PressedAButton();
    void ReleasedAButton();

private:
    bool bAButtonPressed;
};

MyPawn.cpp

#include "MyProject2.h"
#include "MyPawn.h"

AMyPawn::AMyPawn()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AMyPawn::BeginPlay()
{
    Super::BeginPlay();
}

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

    if ( bAButtonPressed )
    {
        UE_LOG( LogTemp, Display, TEXT( "output1: %s" ), L"Aキーが押されている" );
    }
}

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

    // 入力と関数を紐付ける
    // "AButton"は設定→プロジェクト設定→インプットで設定することができます
    InputComponent->BindAction( "AButton", IE_Pressed, this, &AMyPawn::PressedAButton );
    InputComponent->BindAction( "AButton", IE_Released, this, &AMyPawn::ReleasedAButton );
}

void AMyPawn::PressedAButton()
{
    bAButtonPressed = true;
    UE_LOG( LogTemp, Display, TEXT( "output1: %s" ), L"Aキーが押された" );
}

void AMyPawn::ReleasedAButton()
{
    bAButtonPressed = false;
    UE_LOG( LogTemp, Display, TEXT( "output1: %s" ), L"Aキーが離された" );
}

2つめの方法

2つめはAPlayerControllerから入力を取得する方法です。
こちらは1つめで設定されたInputComponentを取得してきて入力を受け取ります。
UGameplayStatics::GetPlayerControllerでPlayerControllerを取得してくることでポーンに限らずどこでも入力を受け取ることができます。

MyPawn2.h

#pragma once

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

UCLASS()
class MYPROJECT2_API AMyPawn2 : public APawn
{
    GENERATED_BODY()

public:
    AMyPawn2();
    virtual void BeginPlay() override;
    virtual void Tick( float DeltaSeconds ) override;
    virtual void SetupPlayerInputComponent( class UInputComponent* InputComponent ) override;
};

MyPawn2.cpp

#include "MyProject2.h"
#include "MyPawn2.h"

AMyPawn2::AMyPawn2()
{
    PrimaryActorTick.bCanEverTick = true;
}

void AMyPawn2::BeginPlay()
{
    Super::BeginPlay();
}

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

    APlayerController* PlayerController = Cast<APlayerController>( Controller );
    if ( PlayerController != nullptr )
    {
        FKey Key = EKeys::A;
        if ( PlayerController->WasInputKeyJustPressed( Key ) )
        {
            // Aキーが押された時true
            UE_LOG( LogTemp, Display, TEXT( "output2: %s" ), L"Aキーが押された" );
        }
        if ( PlayerController->IsInputKeyDown( Key ) )
        {
            // Aキーが押されている間true
            UE_LOG( LogTemp, Display, TEXT( "output2: %s" ), L"Aキーが押されている" );
        }
        if ( PlayerController->WasInputKeyJustReleased( Key ) )
        {
            // Aキーを離した時true
            UE_LOG( LogTemp, Display, TEXT( "output2: %s" ), L"Aキーが離された" );
        }
    }
}

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