12.

UE5 の Enhanced Input 実装手順|BPでキー入力

編集

この記事の要点

  • 作業は「Input Action を作る → Input Mapping Context に割り当てる → 適用する → イベントを受け取る」の4段階です。
  • アセットを作っただけでは反応しません。Subsystem に Mapping Context を追加する処理が必須です。
  • WASD の移動は4つに分けず、Axis2D の Input Action 1つに Negate と Swizzle でまとめるのが定石です。
  • 1回きりの処理を Triggered ピンだけで組むと連射されます。Pressed トリガーか Started ピンを使い分けます。
  • 動かないときは「Context の適用」「Possess されているか」「入力モードが UI に奪われていないか」の順で確認します。

Enhanced Input の作業手順はほぼ定型ですが、初回は「アセットは作ったのにイベントが呼ばれない」という壁にぶつかりがちです。しかもエラーもログも出ないため原因が見えません。この記事では Unreal Engine 5 (UE5) でキー入力を受け取るまでの手順を、詰まりやすい箇所の理由とセットで追いかけます。

1作業の全体像

やることは大きく4段階です。それぞれの段階で何を作り何とつながるのかを、先に図で確認しておきましょう。

STEP 1 Input Action を作る Value Type を決める STEP 2 Mapping Context に登録 キー・Modifier・Trigger STEP 3(忘れやすい) Add Mapping Context Subsystem 経由でプレイヤーに適用 STEP 4 イベントで受ける BP または C++
アセットを2つ作り、実行時に適用し、イベントで受け取る。STEP 3 を忘れると他がすべて正しくても無反応になります。

2下準備を確認する

UE5 のテンプレートから作ったプロジェクトであれば、Enhanced Input はすでに使える状態です。それでも次の2点は確認しておきましょう。

  1. プラグイン一覧で Enhanced Input が有効になっているか確認します。無効なら有効化してエディタを再起動します。
  2. Project Settings の Input カテゴリにある既定クラスの設定で、Player Input Class と Input Component Class が Enhanced Input 用のクラスになっているか確認します。古いプロジェクトを引き継いだ場合、ここが旧クラスのままになっていることがあります。

この既定クラスの設定は地味ですが重要です。Input Component Class が Enhanced Input 用になっていないと、イベントノード自体は置けるのに実行時にバインドされず、まったく反応しません。

3STEP 1:Input Action を作る

  1. コンテンツブラウザで、Input のような専用フォルダを作って開きます。
  2. 空きスペースで右クリックし、Input のカテゴリから Input Action を選びます。
  3. 名前を付けます。ここでは移動用に IA_Move、ジャンプ用に IA_Jump の2つを作ります。
  4. アセットを開き、Value Type を設定します。IA_MoveAxis2D (Vector2D)IA_JumpDigital (bool) にします。
  5. 保存します。

Value Type は後から変えられますが、変更すると受け取り側のピンの型も変わり、つないだノードが外れます。最初に決めておくのが安全です。

作るものValue Type理由
IA_MoveAxis2D (Vector2D)前後と左右をまとめて扱えるため。WASD もスティックも同じ Action に集約できる
IA_JumpDigital (bool)押されたかどうかだけが問題で、強弱の概念がないため

4STEP 2:Input Mapping Context にキーを割り当てる

  1. 同じフォルダで右クリックし、Input のカテゴリから Input Mapping Context を選びます。名前は IMC_Default などとします。
  2. アセットを開くと Mappings という配列があります。ここに項目を追加し、割り当てたい Input Action を指定します。
  3. 追加した Action の下にキーの欄が現れるので、物理キーを設定します。キー欄を選んで実際にそのキーを押すと入力できます。
  4. 必要に応じて、キーごとに Modifier と Trigger を追加します。
  5. 保存します。

ジャンプは単純で、IA_Jump にスペースキーを割り当てるだけです。問題は移動のほうで、ここが初回の最大の関門になります。

5WASD を1つの Axis2D にまとめる

キーが生む値は既定で X 成分に入ります。W・A・S・D をそのまま IA_Move に割り当てると4つとも「右方向に1」を意味してしまい、前後の区別も左右の符号もつきません。ここを Modifier で整えます。

キー付ける Modifier(上から順に)結果の値
WSwizzle Input Axis Values(YXZ)Y = 1(前方向)
SNegate → Swizzle Input Axis Values(YXZ)Y = -1(後ろ方向)
ANegateX = -1(左方向)
DなしX = 1(右方向)

Modifier は上から順に適用されるため、S の場合は「まず符号を反転し、それから X 成分を Y 成分へ移す」という順序になります。並び順を入れ替えると結果が変わるので必ず確認してください。

ゲームパッドの左スティックは元から2軸の値を出すため、Modifier なしでそのまま IA_Move に割り当てられます。同じ Input Action にキーボードとパッドの両方を割り当てておけば、受け取り側は一切変更せずに両対応になります。

6STEP 3:Mapping Context を適用する

ここが最も忘れられる工程です。アセットは作っただけでは使われません。プレイヤーに対して「このコンテキストを使え」と明示的に伝える必要があります。ブループリント (Blueprint) では、プレイヤーが操作する Pawn または Character のブループリントを開いて次のように組みます。

  1. イベントグラフに Event BeginPlay を置きます。
  2. Get Controller ノードを置き、Cast To PlayerController につなぎます。プレイヤーが操作していない場合はここで失敗するため、安全に処理を止められます。
  3. キャスト結果から Get Enhanced Input Local Player Subsystem を取得します。
  4. その戻り値から Add Mapping Context を呼びます。
  5. Mapping Context ピンに IMC_Default を、Priority ピンに 0 を指定します。

Priority は数値が大きいほど優先されます。基本操作を 0 にしておき、特定の状況だけ有効にしたいコンテキストを 1 以上で重ねる使い分けが分かりやすいでしょう。

なお Pawn の BeginPlay に置くと、Possess のタイミングによっては Controller が未設定でキャストに失敗することがあります。その場合は PlayerController 側に書くか、Possess のイベントに移すと安定します。

7STEP 4:ブループリントでイベントを受け取る

  1. Pawn または Character のブループリントで、イベントグラフの空きスペースを右クリックします。
  2. 検索欄に Input Action の名前(例:IA_Move)を入力すると Enhanced Input のイベントノードが候補に出ます。これを配置します。
  3. ノードには Started / Ongoing / Triggered / Completed / Canceled の実行ピンと、値の出力ピンが並びます。
  4. 移動処理は Triggered ピンにつなぎます。押している間ずっと呼ばれるため、毎フレームの移動処理に適しています。
  5. 値の出力ピンから X 成分と Y 成分を取り出し、それぞれ左右移動と前後移動に使います。

ジャンプは事情が違います。Trigger を指定していない場合、Triggered ピンは押しっぱなしの間ずっと呼ばれ続けます。1回だけ実行したいときは次のどちらかで対処します。

○ こうする
該当キーに Pressed トリガーを追加します。押した瞬間の1回だけ Triggered が発火するようになり、受け取り側は単純なままで済みます。
○ これでもよい
トリガーを付けずに Started ピンにつなぎます。評価開始時に1回だけ呼ばれるため、押した瞬間の処理に使えます。離したときの処理は Completed ピンで受けます。

8C++ で受け取る場合

C++ の場合は、モジュールの依存に EnhancedInput を追加したうえで、Mapping Context の適用と Action のバインドを書きます。まず適用です。

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

    if (APlayerController* PC = Cast<APlayerController>(GetController()))
    {
        if (UEnhancedInputLocalPlayerSubsystem* Subsystem =
                ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
        {
            // DefaultMappingContext は UInputMappingContext* 型の UPROPERTY
            Subsystem->AddMappingContext(DefaultMappingContext, 0);
        }
    }
}

次にバインドです。SetupPlayerInputComponent で受け取った Input Component を Enhanced Input 用のクラスにキャストしてから BindAction を呼びます。第2引数には、ブループリントの実行ピンとして並んでいたイベント種別を指定します。

void AMyCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

    if (UEnhancedInputComponent* EIC = Cast<UEnhancedInputComponent>(PlayerInputComponent))
    {
        EIC->BindAction(MoveAction, ETriggerEvent::Triggered, this, &AMyCharacter::Move);
        EIC->BindAction(JumpAction, ETriggerEvent::Started,   this, &AMyCharacter::StartJump);
    }
}

void AMyCharacter::Move(const FInputActionValue& Value)
{
    const FVector2D Axis = Value.Get<FVector2D>();
    // Axis.X が左右、Axis.Y が前後
}

値は FInputActionValue 型で渡され、Input Action の Value Type に合わせて取り出します。Digital なら bool、Axis1D なら float、Axis2D なら FVector2D です。型が食い違うと期待した値になりません。

9反応しないときのチェックリスト

Enhanced Input のトラブルはエラーを出さず「ただ無反応」になるのが厄介です。上から順に確認していけば、たいていの原因は見つかります。

確認すること症状対処
Add Mapping Context を呼んでいるかすべての入力が無反応BeginPlay などで Subsystem 経由の適用処理を追加する。最も多い原因
イベントを置いたアクタが操作対象か特定のブループリントだけ反応しないそのアクタが実際に Possess されているか確認する
Input Component Class の設定ノードは置けるのに一切呼ばれないProject Settings の既定クラスが Enhanced Input 用か確認する
Value Type と受け取り方イベントは呼ばれるが値がゼロValue Type と取り出している型を一致させる
Modifier の並び順移動方向が逆、前後左右が入れ替わるNegate と Swizzle の順序を見直す
入力モードが UI 側にあるUI を出した後だけ効かない入力モードの設定を確認する
他コンテキストの横取り一部のキーだけ効かない同じキーを使う優先度の高いコンテキストが残っていないか確認する

最後の「UI に入力を奪われている」パターンは、Enhanced Input を疑っていると解決しません。ウィジェット (Widget) を表示する処理の前後で症状が変わる場合は、「Set Input Mode」の種類と使い方SetInputMode_UIOnlyを取り消す方法 を確認してください。ここまでできれば、あとは Input Action を増やしていくだけです。Tips の他の記事も併せて活用してください。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. ブループリントで途中から親クラスを指定する方法
  2. C++で編集となっているコンポーネントをブループリントで編集する方法
  3. Boolean変数の初期値を変更する方法
  4. ブループリントで特定のキーが押された時にイベントを発火させる方法
  5. ブループリントで配列からインデックスを指定して取得する方法
  6. Blueprintで「Esc」キーを使ってイベントを発生させる方法
  7. Blueprintで「Cast To」を使い、複数のクラスに対応する方法
  8. Blueprintで指定した確率で処理を分岐させる方法
  9. FrameGrabberをBlueprintで使用する方法
  10. ブループリントで現在日時を取得する方法
  11. Enhanced Input とは?Input Action と Input Mapping Context の基本
  12. Enhanced Input でキー入力を受け取る手順
  13. 旧 Input Mappings から Enhanced Input へ移行する方法