複雑な入力処理やランタイム制御の再マッピングなど、より高度な入力機能を必要とするプロジェクトの場合、実験的機能の Enhanced Input プラグイン により、開発者は簡単なアップグレードパスとエンジンのデフォルト入力システムとの下位互換性を利用できます。このプラグインには、ラジアル デッドゾーン、コード化されたアクション、コンテキスト入力と優先順位付け、アセットベースの環境での生の入力データの独自のフィルタリングと処理を拡張する機能などの機能が実装されています。
開始する
拡張入力を使用するようにプロジェクトを設定するには、Enhanced Input プラグインを有効にします。これには、エディタの [Edit (編集)] ドロップダウン メニューを開き、 [Plugins (プラグイン)] を選択します。[Plugin (プラグイン)] リストの [Input] セクションで [Enhanced Input] プラグインを見つけて有効にし、エディタを再起動します。
エディタが再起動したら、デフォルトの UE4 入力ハンドラの代わりに Enhanced Input プラグインのクラスを使用するようにプロジェクトを設定できます。[Edit (編集)] ドロップダウン メニューに移動して、[Project Settings (プロジェクト設定)] を選択します。[Project Settings (プロジェクト設定)] の [Input (インプット)] セクション ([Engine (エンジン)] という見出しの下にある) を特定して、[Default Classes (デフォルト クラス)] 設定を見つけます。これには、最初、標準の PlayerInput
クラスと InputComponent
クラスが指定されています。
拡張入力を使用するには、これらの設定をそれぞれ EnhancedPlayerInput
と EnhancedInputComponent
に変更します。
主要概念
拡張入力システムには、次の 4 つの主要な概念があります。
- 入力アクション は拡張入力システムとプロジェクトのコードの間の通信リンクです。入力アクションは、ジャンプしたりドアを開けたりするなど、インタラクティブなキャラクターが実行する可能性のあるあらゆるアクションに相当します。また、それだけでなく、歩行動作をランに変更するボタンの長押しなど、ユーザーの入力状態を示すためにも使用できます。入力アクションは raw 入力とは異なるものです。入力アクションはそのアクションをトリガーした特定の入力には認識しないものの、その入力の現在の状態は認識しており、最大 3 つの独立した浮動小数点軸で入力値を報告することができます。例えば、「アイテムを拾う」アクションでは、ユーザーが何かを拾おうとしているかどうかを示すオン/オフの状態のみが必要で、「歩行」アクションでは、ユーザーが歩いていこうとしている方向と速度を指定するために 2 つの軸が必要です。
- 入力マッピング コンテキスト は、ユーザー入力をアクションにマッピングします。また、入力マッピング コンテキストはユーザーごとに動的に追加、削除したり、優先順位を付けることができます。また、拡張入力ローカル プレイヤー サブシステム (Enhanced Input Local Player Subsystem) を使用してローカル プレイヤーに 1 つ以上のコンテキストを適用し、適用したコンテキストに優先順位を付けることで、同じ入力を消費しようとする複数のアクション間の競合を解決することができます。一般的な例としては、キャラクターがワールドを歩き回りながらドアを開けたり、キャラクターのバックパックを確認しながらアイテムを選択したりできる単一のボタンが挙げられます。キャラクターがバックパックを開くときは必ず、「ドアを開く」コンテキストを優先順位から除外し、キャラクターがバックパックを閉じると「アイテムを選択する」コンテキストを削除する「アイテムを選択する」入力マッピング コンテキストを追加することができます。入力マッピング コンテキストにより、ユーザーの入力がキャラクターの状況に基づいて正しく解釈されることが保証され、ドアとバックパックのシステムを意識して、入力処理レベルでコードをプログラミングする必要がなくなります。
- モディファイア は、ユーザーのデバイスから受け取る raw 入力の値を調整します。入力マッピング コンテキストは、入力アクションのそれぞれの raw 入力に関連付けられたモディファイアをいくつでも含むことができます。プラグインには、デッド ゾーン、複数フレームにわたる入力のスムージング、ローカル空間からワールド空間への入力ベクターの変換をはじめとする一般的なモディファイアが含まれています。また、デベロッパーが独自のモディファイアを作成することもできます。
- トリガー はポストモディファイア入力の値、または他の入力アクションの出力の大きさを使用して、入力アクションを有効にする必要があるかどうかを決定します。入力マッピング コンテキスト内の入力アクションは、入力ごとに 1 つ以上のトリガーを含むことができます。例としては、写真を撮るには、カメラの照準を合わせるための別の入力アクションが有効であるときに、ユーザーが左マウス ボタンを 1/4 秒押す必要がある場合などが挙げられます。
以上の概念を組み合わせることで、デベロッパーはシンプルな入力システムから複雑な入力システムまで素早くセットアップし、プロジェクト コードを変更することなく入力システムを調整することができます。
入力アクション
入力アクションは、システムとユーザーのプロジェクトのコードを関連付けます。入力アクションを作成するには、コンテキスト ブラウザ で右クリックして、 [Input (入力)] オプションを展開し、[Input Action (入力アクション)] を選択します。入力アクションをトリガーするには、その入力アクションを入力マッピング コンテキストに設定し、その入力マッピング コンテキストをローカル プレイヤーの Enhanced Input Local Player Subsystem (拡張入力ローカル プレイヤー サブシステム) に追加する必要があります。
トリガーされた入力アクションに Pawn クラスを応答させるには、SetupPlayerInputComponent
で適切なタイプの トリガー イベント にバインドする必要があります。次のサンプル コードでは、SetupPlayerInputComponent
をオーバーライドして、2 つの入力アクション MyInputAction
および MyOtherInputAction
をハンドラ関数にバインドしています。
// Make sure that we are using a UEnhancedInputComponent; if not, the project is not configured correctly.
if (UEnhancedInputComponent* PlayerEnhancedInputComponent = Cast<UEnhancedInputComponent>(PlayerInputComponent))
{
// There are ways to bind a UInputAction* to a handler function and multiple types of ETriggerEvent that may be of interest.
// This calls the handler function on the tick when MyInputAction starts, such as when pressing an action button.
if (MyInputAction)
{
PlayerEnhancedInputComponent->BindAction(MyInputAction, ETriggerEvent::Started, this, &AMyPawn::MyInputHandlerFunction);
}
// This calls the handler function (a UFUNCTION) by name on every tick while the input conditions are met, such as when holding a movement key down.
if (MyOtherInputAction)
{
PlayerEnhancedInputComponent->BindAction(MyOtherInputAction, ETriggerEvent::Triggered, this, TEXT("MyOtherInputHandlerFunction"));
}
}
入力アクションを Enhanced Input プラグインにバインドすると、ビルトインの入力システムのアクションおよび軸のバインディングが置き換えられます。Enhanced Input プラグインを使用する場合は、入力アクションのみをバインドする必要があります。
入力アクションをバインドする場合、以下の 4 種類のハンドラ関数シグネチャから選択できます。
戻り値の型 | パラメータ | 使用時の注記 |
---|---|---|
void |
() |
拡張入力システムからの追加情報を必要としないシンプルなケースに適しています |
void |
(const FInputActionValue& ActionValue) |
入力アクションの現在の値へのアクセスを提供します |
void |
(const FInputActionInstance& ActionInstance) |
名前で UFunction に動的にバインドする場合に使用されるシグネチャ。パラメータはオプションです。 このタイプのバインディングの主な目的は、入力アクションをブループリント スクリプティングに公開することです。Enhanced Input プラグインはこれを自動的に実行するため、デベロッパーはこのバインディング方法を使用する必要はほとんどありません。 |
void |
(FInputActionValue ActionValue, float ElapsedTime, float TriggeredTime) |
入力アクションにはブループリント スクリプティングに入力アクションを公開するビルトイン イベントが含まれているので、C++ のデベロッパーは、ブループリント スクリプティングのデベロッパーが入力アクションのイベントにアクセスできるように、パススルー関数を作成する必要はありません。
一般的なハンドラ関数は次の形式を取ります。
void AMyPawn::MyFirstAction(const FInputActionValue& Value)
{
// Debug log output to confirm that the handler function is running.
UE_LOG(LogTemp, Warning, TEXT("%s called with Input Action Value %s (magnitude %f)"), TEXT(__FUNCTION__), *Value.ToString(), Value.GetMagnitude());
// Use the GetType() function to determine Value's type, and the [] operator with an index between 0 and 2 to access its data.
}
ほとんどのユース ケースで、 void (const FInputActionValue&)
シグネチャを使用することが推奨されます。
入力アクションをハンドラ関数にバインディングすることで、ポーンは入力アクションがトリガーされた特定の方法に応じて、入力アクションに応答することができます。最も一般的なトリガー タイプは、ボタンを押した直後に 1 回実行されるアクションでは Started
で、入力を保持している間にフレームごとに実行される連続的なアクションでは Triggered
である可能性があります。ただし、完全なリストについては、ETriggerEvent の API リファレンス ページを参照してください。
(#入力マッピングコンテキスト)
入力マッピング コンテキスト
入力マッピング コンテキストは、1 つ以上の入力アクションをトリガーするためのルールを記述します。基本的な構造は、最上位レベルに入力アクションのリストを持つ階層になっています。入力アクション レベルの下には、キー、ボタン、および移動軸などの各入力アクションをトリガーできるユーザー入力のリストがあります。最下位レベルには、各ユーザー入力の入力トリガーと入力モディファイアのリストがあります。このリストを使用すると、入力の raw 値のフィルタリングまたは処理方法、および階層の最上位にある入力アクションを制御するために満たす必要のある制約事項を決定することができます。どの入力にも複数の入力モディファイアと入力トリガーを設定できます。このような入力モディファイアおよび入力トリガーは、ユーザーが作成するリストに表示される順に評価されます。これは、各ステップの出力を次のステップの入力として使用する入力モディファイアにとって特に重要です。
入力マッピング コンテキストを作成するには、コンテキスト ブラウザ を右クリックして、[入力 (Input)] オプションを展開し、[Input Mapping Context (入力マッピング コンテキスト)] を選択します。
入力マッピング コンテキストには関連するすべての入力アクションを設定します。シンプルなプロジェクトでは、すべての入力アクションを 1 つの入力マッピング コンテキストにまとめることができることがあります。複雑なプロジェクトでは、入力アクションを複数の入力マッピング コンテキストに設定すると適切に機能する可能性があります。これは、ローカル プレイヤーが一度に複数のアクティブな入力マッピング コンテキストを持つことができるためです。例えば、泳いだり、歩いたり、車両を運転したりできるキャラクターは、複数の入力マッピング コンテキストを持つ可能性があります。1 つの入力マッピング コンテキストは常に利用可能で、常に同じユーザー入力にマッピングされている一般的なアクション用で、その他の入力マッピング コンテキストは個々の移動モードごとに追加されます。デベロッパーは、車両関連の入力アクションを別の入力マッピング コンテキストに設定することができます。これにより、車両に乗車したときにローカル プレイヤーに車両関連の入力アクションを追加し、車両から出たときにローカル プレイヤーからこれらのアクションを削除することができます。こうすることで、不適切な入力アクションが実行されない (CPU サイクルを無駄にしない) ようにし、ユーザー入力が相互に排他的な入力マッピング コンテキストによって異なる入力アクションに使用された場合の入力の衝突を回避することで、バグを低減できます。詳細については、モディファイアおよびトリガーのセクションを参照してください。
このドロップダウン リストには多くの入力バインディングがあります。入力バインディングをより素早く選択するには、ドロップダウンの左にある小さなボタンを押してから、バインドしたいキーまたはボタンを押します。
入力マッピング コンテキストの設定が完了したら、それをポーンの プレイヤー コントローラー に関連付けられているローカル プレイヤーに追加できます。これを行うには、PawnClientRestart
関数をオーバーライドして以下のようなコード ブロックを追加します。
// Make sure that we have a valid PlayerController.
if (APlayerController* PC = Cast<APlayerController>(GetController()))
{
// Get the Enhanced Input Local Player Subsystem from the Local Player related to our Player Controller.
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
{
// PawnClientRestart can run more than once in an Actor's lifetime, so start by clearing out any leftover mappings.
Subsystem->ClearAllMappings();
// Add each mapping context, along with their priority values. Higher values outprioritize lower values.
Subsystem->AddMappingContext(MyInputMappingContext, MyInt32Priority);
}
}
入力マッピング コンテキストが追加されると、ポーンは SetupPlayerInputComponent
またはユーザーが設定したブループリント スクリプティングで、バインドした入力アクション イベントに応答できるようになります。使用可能な入力マッピング コンテキストのセットの変更を保証するイベントがゲームプレイ中に発生する場合、ClearAllMappings
、AddMappingContext
、および RemoveMappingContext
を使用して使用可能なコマンドのセットを動的に更新することができます。詳細については、IEnhancedInputSubsystemInterface API リファレンス ページを参照してください。
追加した各入力マッピング コンテキストにより、含まれる入力アクションをトリガーして、ポーンのブループリント グラフで適切なイベントを実行することができます。ゲームプレイ中はいつでも入力マッピング コンテキストのセットを変更できます。
入力モディファイア
入力モディファイアは、UE4 が受け取る raw 入力の値を、入力トリガーに送信する前に変更するプリプロセッサーです。Enhanced Input プラグインは、軸の順序を変更したり、「デッド ゾーン」を実装したり、軸入力をワールド空間に変換したり、その他のタスクを実行するための様々な入力モディファイアを備えてリリースされています。入力マッピング コンテキスト内の入力アクションに関連付けられた各入力は、その入力の 1 つまたは複数の入力トリガーに進む前に、ユーザー定義の一連の入力モディファイアによって調整されます。入力モディファイアはリストされている順に適用され、各入力モディファイアからの出力値が次の入力値になります。
Enhanced Input プラグインに装備されている入力モディファイアの完全なリストについては、UInputModifier API リファレンス ページを参照してください。自分のプロジェクトでまだ提供されていない入力モディファイアが必要な場合は、独自の UInputModifier
クラスを作成することができます。
方向入力
入力モディファイアの良い活用例は、1 つの入力アクションを使用した 2 方向入力です。マウスやゲームパッドのアナログ スティックでの 2 方向の動きの読み取りは、少なくとも 2 つの軸をサポートする入力アクションを作成し、適切な入力を入力マッピング コンテキストに追加するだけで済みます。ただし、キーボードの方向矢印や一般的な「WASD」構成のような 1 方向のソースからの入力もサポートしたい場合は、正しい入力モディファイアを適用することで、これらの入力もサポートすることができます。具体的には、一部のキーを負として登録するには [Negate (ネゲート)] を、一部のキーをデフォルトの X 軸ではなく Y 軸として登録するには [Swizzle Input Axis Values (入力軸値をスイズル)] を使用します。このためには、入力を次のように設定します。
文字キー | 矢印キー | 目的の入力の解釈 | 必要な入力モディファイア |
---|---|---|---|
W | 上 | 正の Y 軸 | Swizzle Input Axis Values (YXZ または ZXY) |
A | 左 | 負の X 軸 | Negate |
S | 下 | 負の Y 軸 | Negate Swizzle Input Axis Values (YXZ または ZXY) |
D | 右 | 正の X 軸 | (なし) |
各キーは正の 1 方向の値を報告するので、この値は常に X 軸を占有し、特定のティックで 0.0 または 1.0 の値を持ちます。左および下の入力に対して値をネゲートして、軸の順序を切り替え、上と下の入力に対して、入力の X 軸の値が Y 軸に移動するようにすることで、入力モディファイアを使用して 1 方向入力のセットを 1 つの 2 方向入力値として解釈することができます。
入力トリガー
入力トリガーは、ユーザー入力が入力モディファイアのオプション リストで調整された後、その入力マッピング コンテキスト内で対応する入力アクションをアクティブにするかどうかを決定します。ほとんどの入力トリガーは入力自体を分析します。つまり、最小有効化値を確認して、短いタップ、長押し、または通常の「押す」または「離す」イベントなどのパターンを検証します。このルールの 1 つの例外として、[Chorded Action (コード アクション)] 入力トリガーがあります。この入力トリガーは別の入力アクションをトリガーする必要があります。デフォルトでは、入力に対するユーザー アクティビティは、ティックごとにトリガーされます。
Enhanced Input プラグインに装備されている入力トリガーの完全なリストについては、UInputTrigger API リファレンス ページを参照してください。Enhanced Input プラグインで提供されていない入力トリガーが必要な場合は、独自の UInputTrigger
クラスを作成することができます。