|
執筆バージョン: Unreal Engine 5.7
|
はじめに
皆さんこんにちは!EnhancedInput使っていますか?
今回はEnhancedInputの入力値に変化をもたらす「InputModifier」について紹介していきます。
実際にInputModifierを使って2通りの「キーの同時押し」を実装していこうとおもいます。
なお本ブログにおいてはEnhancedInputに関するInputActionやInputMappingContextについては知っている前提で話を進めていきます。
InputModifierとは?
InputModifierとは、EnhancedInputにおいて入力された値を補正や加工するものです。
自分で作らなくてもUEにはデフォルトでいくつかの機能が用意されています。
例えば一定の値以下の入力を0として扱う「DeadZone」や入力の特定成分を反転させる「Negate」などがあります。
InputModifierクラスを継承すればC++やBPで自作することができます。
今回はC++を使って実装例を紹介していきたいと思います。
同時入力を作ろう パターンA
じつはInputModifierを使わなくてもEnhancedInputであれば「ChordedAction」というものを使えば同時押しが実装できますが、
あえてそちらを使わずに同時入力を実装していこうと思います。
主な手順としては下記のものになります。
1.押下情報をVector型のX,Y,Z成分に置換するModifierを作る。
2.同時押し用のアクションを用意する
3.「ボタン1をX成分の入力」「ボタン2をY成分の入力」として扱うようにInputMappingContextを設定する。
4.X成分とY成分が両方入力がある場合にアクションを発火する。
それでは早速手順1のModifierを作っていきます。
USynchronousInputというUInputModifierを継承したクラスを作成し、
ModifyRaw_Implementationをオーバーライドして処理を書いていきます。
処理としてはfloatで来た入力値をConversionRatioの成分に掛け算することで、
ConversionRatioで設定した成分だけがVector出力に渡されるようにしています。
|
|
UCLASS() class USynchronousInput : public UInputModifier { GENERATED_BODY() public: //どの成分に変換するか指定する変数 UPROPERTY(EditInstanceOnly, BlueprintReadWrite) FVector ConversionRatio = FVector(0.0f); protected: //Modifierの実装部 virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override; }; |
|
|
FInputActionValue USynchronousInput::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) { float CurrentFloat = CurrentValue.Get(); FVector NewValue = ConversionRatio * CurrentFloat; return FInputActionValue(NewValue); } |
次に同時押し用のアクションを用意します
今回はIA_SyncronousActionという名前にして、ValueTypeをAxis3D(Vector)にします。

続いて手順3の各ボタンにそれぞれ成分を割り振る方法です。
作成したSyncronousInputをキーのModifierに設定します。
この時それぞれのキーのConversionRatioのXYZを違う成分として登録します。

これだけだと毎フレームイベントが発火しちゃうので、各キーのTrigigersにPressedを指定します。
これでボタンを押下した瞬間だけイベントが発火するようになります。

ここまで出来たら後は発火されるイベント側の処理になります。
まずはCharacterのBeginPlayでIMCを登録しておきます。
そしたらイベントグラフからIA_SyncronousActionを配置して、XとYの値が両方とも1以上だったときに処理を行うようにします。

これで同時押しが実装できます。
メリットとしてはInputActionが1つで済むのできれいになります。
同時入力を作ろう パターンB
先ほどは1つのInputActionに2つのキーを割り当てて実装しましたが、
今度は2つのInputActionを使ってModifier内で他のInputActionの入力値を参照して実装する方法を紹介します。
主な手順としては以下のものとなります。
1.別のInputActionの入力を参照するModifierを作る。
2.同時押し用のアクションをキー別で用意する
3.ボタン2がModifierをつかうようにInputMappingContextを設定する
4.Characterでアクションを発火する
それではまずはModifierを作っていきます。
|
|
UCLASS() class USynchronousInputB : public UInputModifier { GENERATED_BODY() public: //参照する他のInputAction UPROPERTY(EditInstanceOnly, BlueprintReadWrite) class UInputAction* PairInputAction; protected: //Modifierの実装部 virtual FInputActionValue ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) override; }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
FInputActionValue USynchronousInputB::ModifyRaw_Implementation(const UEnhancedPlayerInput* PlayerInput, FInputActionValue CurrentValue, float DeltaTime) { //別のInputActionの入力されている値を取得 FInputActionValue PairValue = PlayerInput->GetActionValue(PairInputAction); bool PairBoolValue = PairValue.Get(); if(PairBoolValue) { //別のInputActionの入力があるので、この入力はそのままの値を返す return CurrentValue; } else { //別のInputActionの入力がないので、この入力は0として扱う return FInputActionValue(false); } } |
次にInputActionを作成します。
先ほどと異なり今度はボタン別にInputActionを用意するので、「IA_SyncronousActionB1」と「IA_SyncronousActionB2」を作成します。
InputActionを用意したらInputMappingContextを設定していきます。
下記の画像のように、IA_SyncronousActionB2にだけSynchronousInputBを設定して、
PairInputActionにIA_SyncronousActionB1を指定します。

InputMappingContextが設定できたら、CharacterのイベントグラフからIA_SyncronousActionB2を配置して、値がtrueだったときに処理を行うようにします。

これで別パターンの同時押しが実装できます。
同時押しでこのやり方をすることは無いと思いますが、ModifierからほかのInputActionの値を取得することができると、
「前後移動と左右移動のActionが分かれていても入力を正規化する」など応用方法がいくつかあるので、この手法を覚えておくと役立つことがあるかもしれません。
さいごに
今回はInputModifierについて、2通りの同時押しの実装を通して紹介をしました。
改めて、InputModifierは生の入力からキャラでの入力までの間に値に変化を加えることができる機能です。
EnhancedInputを使ってアクションを作る場合、キーボード入力とゲームパッド入力を同じアクションに設定すると思いますが、
キーボード&マウスとゲームパッドでカメラ感度のオプションを分けたい場合などそれぞれのキーに対して操作を反映させたい場合等に使えるので、使いこなせるようになってもらえたら嬉しいです。