ue4

UE4/C++ キーとGamePad入力を取得する

APlayerControllerクラスを使ってキーボードとGamePadからキーの入力を取得します。
入力を取得を取得するにはAPlayerControllerの以下のメソッドを使用します。

IsInputKeyDownはキーの押下状態、GetInputAnalogStickStateはアナログステックの入力を取得することが出来ます。  

IsInputKeyDownの使い方

    //"W"Keyが押されているかチェックする
    if (playerController->IsInputKeyDown(EKeys::W)) {
        // "W"Key押されています。
    }

GetInputAnalogStickStateの使い方

    float JoyR_X;
    float JoyR_Y;
    //ジョイスティックRの値を取得
    playerController->GetInputAnalogStickState(
                        EControllerAnalogStick::CAS_RightStick, 
                        JoyR_X, 
                        JoyR_Y);

上記を使用して入力取得するクラスを作成しました。

IvPadInput.h

#ifndef _IVPADINPUT_H_
#define _IVPADINPUT_H_

/**
 * @file IvPadInput.h
 * @brief ボタン入力を制御する
 * @author     inuvatico
 * @date        2020/10/17
 * @version     1.0
 * @copyright   2018 inuvatico
 * Released under the MIT license.
 *   see https://opensource.org/licenses/MIT
 * @par (new/Add/Change : 2020/10/17)
 *
*/
#include "GameFramework/PlayerController.h"

#ifndef nBit
#define nBit(n) (1<<n)
#endif

/**
 *  Keyのビット定義
*/
#define PAD_LeftThumbstick      nBit(0)
#define PAD_RightThumbstick     nBit(1)

#define PAD_Special_Left        nBit(2)
#define PAD_Special_Left_X      nBit(3)
#define PAD_Special_Left_Y      nBit(4)
#define PAD_Special_Right       nBit(5)

#define PAD_FaceButton_Bottom   nBit(6)
#define PAD_FaceButton_Right    nBit(7)
#define PAD_FaceButton_Left     nBit(8)
#define PAD_FaceButton_Top      nBit(9)
#define PAD_LeftShoulder        nBit(10)
#define PAD_RightShoulder       nBit(11)
#define PAD_LeftTrigger         nBit(12)
#define PAD_RightTrigger        nBit(13)
#define PAD_Up                  nBit(14)
#define PAD_Down                nBit(15)
#define PAD_Right               nBit(16)
#define PAD_Left                nBit(17)

#define  BTN_R_D    PAD_FaceButton_Bottom
#define  BTN_R_R    PAD_FaceButton_Right
#define  BTN_R_U    PAD_FaceButton_Top
#define  BTN_R_L    PAD_FaceButton_Left

#define  BTN_L_D    PAD_Down
#define  BTN_L_R    PAD_Right
#define  BTN_L_U    PAD_Up
#define  BTN_L_L    PAD_Left


//-----------------------------------------------------------------
/// IvPadInput ボタン入力を制御する
/// - APlayerControllerを使用します
//-----------------------------------------------------------------
class IvPadInput {

public:
    IvPadInput() {
        init();
    }

    ~IvPadInput() {}

    uint32 BtnOn;       // 現フレームでの入力
    uint32 BtnPressed;  // 入力状態
    uint32 BtnRelease;  // 現フレームで終了した入力

    // ジョイスティックR
    float JoyRdist;
    float JoyR_X;
    float JoyR_Y;

    // ジョイスティックL
    float JoyLdist;
    float JoyL_X;
    float JoyL_Y;

    void init() {
        BtnOn = 0;
        BtnPressed = 0;
        BtnRelease = 0;

        JoyRdist = 0;
        JoyR_X = 0;
        JoyR_Y = 0;

        JoyLdist = 0;
        JoyL_X = 0;
        JoyL_Y = 0;
    }

    /// Key情報
    struct SKeyInfo {
        FKey Key;   //!< Key
        uint32 Bit; //!< 対応ビット
    };
    #define KEYINFO(key,No) {key,No}

    //-------------------------------------------------------------
    /// ボタン情報の更新
    /// - Tickで呼び出します
    //-------------------------------------------------------------
    void update(
        const APlayerController *playerController //!< PlayerController
    ) {

        //-------------------------------------------------------------
        // ボタン情報の取得
        //-------------------------------------------------------------
        {
            static const SKeyInfo List[] = {
                KEYINFO(EKeys::Gamepad_LeftThumbstick   ,PAD_LeftThumbstick),
                KEYINFO(EKeys::Gamepad_RightThumbstick  ,PAD_RightThumbstick),
                KEYINFO(EKeys::Gamepad_Special_Left     ,PAD_Special_Left),
                KEYINFO(EKeys::Gamepad_Special_Left_X   ,PAD_Special_Left_X),
                KEYINFO(EKeys::Gamepad_Special_Left_Y   ,PAD_Special_Left_Y),
                KEYINFO(EKeys::Gamepad_Special_Right    ,PAD_Special_Right),
                KEYINFO(EKeys::Gamepad_LeftShoulder     ,PAD_LeftShoulder),
                KEYINFO(EKeys::Gamepad_RightShoulder    ,PAD_RightShoulder),
                KEYINFO(EKeys::Gamepad_LeftTrigger      ,PAD_LeftTrigger),
                KEYINFO(EKeys::Gamepad_RightTrigger     ,PAD_RightTrigger),
                KEYINFO(EKeys::Gamepad_FaceButton_Bottom,BTN_R_D),
                KEYINFO(EKeys::Gamepad_FaceButton_Right ,BTN_R_R),
                KEYINFO(EKeys::Gamepad_FaceButton_Left  ,BTN_R_L),
                KEYINFO(EKeys::Gamepad_FaceButton_Top   ,BTN_R_U),
                KEYINFO(EKeys::Gamepad_DPad_Up          ,BTN_L_U),
                KEYINFO(EKeys::Gamepad_DPad_Down        ,BTN_L_D),
                KEYINFO(EKeys::Gamepad_DPad_Right       ,BTN_L_R),
                KEYINFO(EKeys::Gamepad_DPad_Left        ,BTN_L_L),

                KEYINFO(EKeys::AnyKey                   ,0) //終端
            };

            uint32 btnOn = GetInputKeyDown(List, playerController);
            BtnOn = btnOn & (btnOn ^ BtnPressed);//今、押されたボタンを取得
            BtnRelease = (~btnOn) & BtnPressed; //今、離されたボタンを取得
            BtnPressed = btnOn; // 押されているボタンを取得
        }

        //-------------------------------------------------------------
        // ジョイステックの情報の取得
        //-------------------------------------------------------------
        {
            FVector vec;

            playerController->GetInputAnalogStickState(EControllerAnalogStick::CAS_LeftStick, JoyL_X, JoyL_Y);
            vec.Z = 0;
            vec.X = JoyL_X;
            vec.Y = JoyL_Y;
            JoyLdist = vec.Distance(vec, FVector::ZeroVector);
            if (JoyLdist == 0) {
                static const SKeyInfo List[] = {
                    //PC  ↓→←↑
                    KEYINFO(EKeys::W, 0x1),
                    KEYINFO(EKeys::S, 0x2),
                    KEYINFO(EKeys::D, 0x4),
                    KEYINFO(EKeys::A, 0x8),
                    KEYINFO(EKeys::AnyKey,0) //終端
                };
                uint32 btnOn = GetInputKeyDown(List, playerController);
                if (btnOn) {
                    JoyLdist = 1;
                    if (btnOn&0x1) JoyL_Y = 1;
                    if (btnOn&0x2) JoyL_Y = -1;
                    if (btnOn&0x4) JoyL_X = 1;
                    if (btnOn&0x8) JoyL_X = -1;
                }

            }

            playerController->GetInputAnalogStickState(EControllerAnalogStick::CAS_RightStick, JoyR_X, JoyR_Y);
            JoyR_Y *= -1;
            vec.X = JoyR_X;
            vec.Y = JoyR_Y;
            JoyRdist = vec.Distance(vec, FVector::ZeroVector);

            if (JoyRdist == 0) {
                static const SKeyInfo List[] = {
                    //PC  ↑↓→←
                    KEYINFO(EKeys::Up,   0x1),
                    KEYINFO(EKeys::Down, 0x2),
                    KEYINFO(EKeys::Right,0x4),
                    KEYINFO(EKeys::Left, 0x8),
                    KEYINFO(EKeys::AnyKey,0) //終端
                };
                uint32 btnOn = GetInputKeyDown(List, playerController);
                if (btnOn) {
                    JoyRdist = 1;
                    if (btnOn&0x1) JoyR_Y = 1;
                    if (btnOn&0x2) JoyR_Y = -1;
                    if (btnOn&0x4) JoyR_X = 1;
                    if (btnOn&0x8) JoyR_X = -1;
                }
            }
        }

        // Keyの状態を表示してみる
        if (GEngine) {
            GEngine->AddOnScreenDebugMessage(-1, 1.0f / 1200.f, FColor::Blue, FString::Printf(TEXT("PAD    : 0x%x,%f"), BtnPressed));
            if (BtnOn)
                GEngine->AddOnScreenDebugMessage(-1, 3, FColor::Black, FString::Printf(TEXT("PAD On : 0x%x,%f"), BtnOn));
            if (BtnRelease)
                GEngine->AddOnScreenDebugMessage(-1, 3, FColor::Green, FString::Printf(TEXT("PAD Off: 0x%x,%f"), BtnRelease));
            GEngine->AddOnScreenDebugMessage(-1, 1.0f / 1200.f, FColor::Blue, FString::Printf(TEXT("JoyLeft: D(%f)  (%f,%f)"), JoyLdist, JoyL_X, JoyL_Y));
            GEngine->AddOnScreenDebugMessage(-1, 1.0f / 1200.f, FColor::Blue, FString::Printf(TEXT("JoyRigh: D(%f)  (%f,%f)"), JoyRdist, JoyR_X, JoyR_Y));
        }
    }

    //-------------------------------------------------------------
    /// 押されているKeyを取得
    //-------------------------------------------------------------
    uint32 GetInputKeyDown(
        const SKeyInfo *list, //!< 取得したいKeyのリスト
        const APlayerController *playerController //!< PlayerController
    ) {
        uint32 btnOn = 0;
        for (int i = 0;; i++) {
            if (list[i].Bit == 0)
                break;
            if (playerController->IsInputKeyDown(list[i].Key)) {
                btnOn |= list[i].Bit;
            }
        }
        return  btnOn;
    }
};

#endif // _IVPADINPUT_H_


以上、PlayerControllerを使った入力処理でした。
※ ジョイスティックLRのY軸の値が逆なんだよなぁ...

prev/next







digitalize
  始めました。