UI ナビゲーション コントローラー

このページでは、Windows.Gaming.Input.UINavigationController とユニバーサル Windows プラットフォーム (UWP) 用の関連 API を使った UI ナビゲーション デバイス向けプログラミングの基礎について説明します。

ここでは、次の項目について紹介します。

  • 接続されている UI ナビゲーション デバイスとそのユーザーの一覧を収集する方法
  • ナビゲーション デバイスが追加または削除されたことを検出する方法
  • 1 つ以上の UI ナビゲーション デバイスから入力を読み取る方法
  • ゲームパッドとアーケード スティックがナビゲーション デバイスとしてどのように動作するか

UI ナビゲーション コントローラーの概要

ほぼすべてのゲームには、ゲーム前のメニューやゲーム内のダイアログに過ぎない場合でも、ゲームプレイとは別のユーザー インターフェイスがあります。 プレイヤーは、選択した入力デバイスを使用してこの UI をナビゲートできる必要がありますが、開発者は各種類の入力デバイスに対して特定のサポートを追加する必要があり、プレイヤーを混乱させるゲームと入力デバイスの間に不整合が生じる可能性もあります。 このような理由から、 UINavigationController API が作成されました。

UI ナビゲーション コントローラーはさまざまな物理入力デバイスでサポートできる一般的な UI ナビゲーション コマンドのボキャブラリを提供するために存在する入力デバイスです。 UI ナビゲーション コントローラーは、物理入力デバイスを見る方法とは異なります。ナビゲーション コントローラーとして表示される物理入力デバイスを参照するにはナビゲーション デバイスを使用します。 開発者は、特定の入力デバイスではなくナビゲーション デバイスに対してプログラミングすることで、さまざまな入力デバイスをサポートする負担を回避し、既定で一貫性を実現します。

各種類の入力デバイスでサポートされるコントロールの数と種類は非常に異なる場合があるため、また、一部の入力デバイスでは、より豊富な一連のナビゲーション コマンドをサポートする必要があるため、ナビゲーション コントローラー インターフェイスは、コマンドのボキャブラリを 必要なセットに分割し 最も一般的で重要なコマンドを含み、 オプション セット 便利なコマンドを含みます。 すべてのナビゲーション デバイスは、必須セット内のすべてのコマンドをサポートしオプション セット内のすべてのコマンド、一部のコマンド、またはサポートしていないコマンド

必須セット

ナビゲーション デバイスは、 必要なセット内のすべてのナビゲーション コマンドをサポートする必要があります。これらは方向 (上、下、左、右)、表示、メニュー、受け入れ、取り消しコマンドです。

方向コマンドは、単一の UI 要素間のプライマリ XY フォーカス ナビゲーション を対象としています。 ビューコマンドとメニューコマンドは、ゲームプレイ情報(多くの場合、瞬間的、時にはモーダル)を表示し、ゲームプレイとメニューコンテキストをそれぞれ切り替えることを目的としています。 accept コマンドと cancel コマンドは、それぞれ肯定的 (はい) と否定 (いいえ) の応答を目的としています。

次の表は、これらのコマンドとその使用目的を例と共にまとめたものです。 | コマンド | 使用目的 | -------:| --------------- | Up | XY フォーカス ナビゲーションの上 | Down | XY フォーカス ナビゲーションの下 | Left | XY フォーカス ナビゲーションの左 | Right | XY フォーカス ナビゲーションの右 | View | ゲームプレイの情報を表示 (スコアボード、ゲーム統計、目標、世界やマップ領域) | Menu | プライマリ メニューまたは一時停止 (設定、状態、装備、道具、一時停止) | Accept | 肯定的な応答 (同意する、進む、確認する、開始する、はい) | Cancel | 否定的な応答 (拒否する、後退する、断る、停止する、いいえ)

省略可能なセット

また、ナビゲーション デバイスは、 オプション セット内のすべてのナビゲーション コマンド、一部、または何もサポートしていない場合もあります。これらはページング (上下左右)、スクロール (上、下、左、右)、コンテキスト (コンテキスト 1 から 4) のコマンドです。

コンテキスト コマンドは、アプリケーション固有のコマンドとナビゲーション ショートカットを明示的に目的としています。 ページングおよびスクロール コマンドは、UI 要素のページまたはグループ間の迅速なナビゲーションと、それぞれ UI 要素内のきめ細かいナビゲーションを目的としています。

次の表は、これらのコマンドとその使用目的をまとめたものです。 | コマンド | 使用目的 | -----------:| ------------ | PageUp | 上方向にジャンプ (上側または垂直方向の前のページやグループに対して) | PageDown | 下方向にジャンプ (下側または垂直方向の次のページやグループに対して) | PageLeft | 左方向にジャンプ (左側または水平方向の前のページやグループに対して) | PageRight | 右方向にジャンプ (右側または水平方向の次のページやグループに対して) | ScrollUp | 上方向にスクロール (フォーカスが置かれた UI 要素またはスクロール可能なグループ内) | ScrollDown | 下方向にスクロール (フォーカスが置かれた UI 要素またはスクロール可能なグループ内) | ScrollLeft | 左方向にスクロール (フォーカスが置かれた UI 要素またはスクロール可能なグループ内) | ScrollRight | 右方向にスクロール (フォーカスが置かれた UI 要素またはスクロール可能なグループ内) | Context1 | 最初のコンテキスト アクション | Context2 | 2 番目のコンテキスト アクション | Context3 | 3 番目のコンテキスト アクション | Context4 | 4 番目のコンテキスト アクション

ゲームは、実際の機能が使用目的と異なっているコマンドに対して自由に応答できますが、予期しない動作は避ける必要があります。 特に、使用目的が必要な場合は、コマンドの実際の関数を変更しないでください。最も意味のあるコマンドに新しい関数を割り当て、対応する関数を PageUp/PageDown などの対応するコマンドに割り当ててみてください。 最後に、各種類の入力デバイスでサポートされているコマンドと、それらがマップされるコントロールを検討し、すべてのデバイスから重要なコマンドにアクセスできるようにします。

ゲームパッド、アーケード スティック、レーシング ホイール ナビゲーション

Windows.Gaming.Input 名前空間でサポートされているすべての入力デバイスは、UI ナビゲーション デバイスです。

次の表は、ナビゲーション コマンドの 必要なセット がさまざまな入力デバイスにどのようにマップされるかをまとめたものです。

ナビゲーション コマンド ゲームパッドの入力 アーケード スティック入力 レーシング ホイールの入力
上へ 左サムスティックを上 / D パッドを上 スティックを上 方向パッド上
[下へ] 左サムスティックを下 / D パッドを下 スティックを下 方向パッド下
Left 左サムスティックを左 / D パッドを左 スティックを左 方向パッド左
Right 左サムスティックを右 / D パッドを右 スティックを右 方向パッド右
ビュー​​ View ボタン View ボタン View ボタン
メニュー Menu ボタン メニュー ボタン Menu ボタン
同意する A ボタン アクション 1 ボタン A ボタン
キャンセル​​ B ボタン アクション 2 ボタン B ボタン

次の表は、ナビゲーション コマンドの オプション セット がさまざまな入力デバイスにどのようにマップされるかをまとめたものです。

ナビゲーション コマンド ゲームパッドの入力 アーケード スティック入力 レーシング ホイールの入力
PageUp 左トリガー サポートされない 状況に応じて異なる
PageDown 右トリガー サポートされない 状況に応じて異なる
PageLeft 左バンパー サポートされない 状況に応じて異なる
PageRight 右バンパー サポートされない 状況に応じて異なる
ScrollUp 右サム スティック上 サポートされない 状況に応じて異なる
ScrollDown 右サム スティック下 サポートされない 状況に応じて異なる
ScrollLeft 右サム スティック左 サポートされない 状況に応じて異なる
ScrollRight 右サム スティック右 サポートされない 状況に応じて異なる
Context1 X ボタン サポートされない [X] ボタン (commonly)
Context2 Y ボタン サポートされない Y ボタン (commonly)
Context3 左サムスティック押下 サポートされない 状況に応じて異なる
Context4 右サムスティック押下 サポートされない 状況に応じて異なる

UI ナビゲーション コントローラーを検出して追跡する

UI ナビゲーション コントローラーは論理入力デバイスですが、物理デバイスの表現であり、同じ方法でシステムによって管理されます。 それらを作成または初期化する必要はありません。システムには、接続されている UI ナビゲーション コントローラーと、UI ナビゲーション コントローラーが追加または削除されたときに通知するイベントの一覧が表示されます。

UI ナビゲーション コントローラーの一覧

UINavigationController クラスは、現在接続されている UI ナビゲーション デバイスの読み取り専用リストである静的プロパティ UINavigationControllers を提供します。 接続されているナビゲーション デバイスの一部のみに関心がある場合があるため、 UINavigationControllers プロパティを使用してアクセスするのではなく、独自のコレクションを維持することをお勧めします。

次の例では、接続されているすべての UI ナビゲーション コントローラーを新しいコレクションにコピーします。

auto myNavigationControllers = ref new Vector<UINavigationController^>();

for (auto device : UINavigationController::UINavigationControllers)
{
    // This code assumes that you're interested in all navigation controllers.
    myNavigationControllers->Append(device);
}

UI ナビゲーション コントローラーの追加と削除

UI ナビゲーション コントローラーが追加または削除されると、 UINavigationControllerAdded および UINavigationControllerRemoved イベントが発生します。 これらのイベントのイベント ハンドラーを登録して、現在接続されているナビゲーション デバイスを追跡できます。

次の例では、追加された UI ナビゲーション デバイスの追跡を開始します。

UINavigationController::UINavigationControllerAdded += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
    // This code assumes that you're interested in all new navigation controllers.
    myNavigationControllers->Append(args);
}

次の例では、削除されたアーケード スティックの追跡を停止します。

UINavigationController::UINavigationControllerRemoved += ref new EventHandler<UINavigationController^>(Platform::Object^, UINavigationController^ args)
{
    unsigned int indexRemoved;

    if(myNavigationControllers->IndexOf(args, &indexRemoved))
	{
        myNavigationControllers->RemoveAt(indexRemoved);
    }
}

ユーザーとヘッドセット

各ナビゲーション デバイスをユーザー アカウントに関連付けて ID を入力にリンクしたり、ボイス チャットやナビゲーション機能を容易にするためにヘッドセットを接続したりできます。 ユーザーとヘッドセットの操作の詳細については、「ユーザーとそのデバイスの追跡」と「ヘッドセット」を参照してください。

UI ナビゲーション コントローラーの読み取り

関心のある UI ナビゲーション デバイスを特定したら、そこから入力を収集する準備が整います。 ただし、他の種類の入力とは異なり、ナビゲーション デバイスはイベントを発生させて状態変化を伝えません。 代わりに、イベントをポーリングすることで現在の状態を定期的に読み取ります。

UI ナビゲーション コントローラーのポーリング

ポーリングによって、ナビゲーション デバイスの正確な時点のスナップショットがキャプチャされます。 入力収集に対するこのアプローチは、ほとんどのゲームに適しています。そのロジックは通常、イベントドリブンではなく確定的なループで実行されるためです。また、一般に、一度に収集された入力からゲーム コマンドを解釈する方が、時間の経過に伴って収集された多数の単一の入力からのコマンドよりも簡単です。

ナビゲーション デバイスをポーリングするには、 UINavigationController.GetCurrentReading; を呼び出します。この関数は、ナビゲーション デバイスの状態を含む UINavigationReading を返します。

auto navigationController = myNavigationControllers[0];

UINavigationReading reading = navigationController->GetCurrentReading();

ボタンの読み取り

各 UI ナビゲーション ボタンは、押された (下向き)、または離された (上) かどうかに対応するブール値の読み取り値を提供します。 効率を高める目的で、ボタンの読み取り値は個々のブール値として表されません。代わりに、これらはすべて、 RequiredUINavigationButtons および OptionalUINavigationButtons 列挙型によって表される 2 つのビットフィールドのいずれかにパックされます。

必須セットに属するボタンはUINavigationReading 構造体のRequiredButtonsプロパティから読み取られます。オプション セットに属するボタンは、OptionalButtons プロパティから読み取られます。 これらのプロパティはビットフィールドであるため、関心のあるボタンの値を分離するためにビットごとのマスクが使用されます。 対応するビットが設定されている場合、ボタンは押されます(下)。それ以外の場合はリリース (アップ)。

次の例では、 要求セットの [承諾] ボタン 押されているかどうかを確認します。

if (RequiredUINavigationButtons::Accept == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
    // Accept is pressed
}

次の例では、 要求セットの [承諾] ボタン を離すかどうかを決定します。

if (RequiredUINavigationButtons::None == (reading.RequiredButtons & RequiredUINavigationButtons::Accept))
{
    // Accept is released (not pressed)
}

オプション セット内のボタンを読み取る場合は、必ず OptionalButtons プロパティとOptionalUINavigationButtons列挙体を使用してください

次の例では、 オプション セットの [コンテキスト 1] ボタン が押されているかどうかを確認します。

if (OptionalUINavigationButtons::Context1 == (reading.OptionalButtons & OptionalUINavigationButtons::Context1))
{
    // Context 1 is pressed
}

場合によっては、ボタンが押された状態から離されたボタンまたは離されたボタンに切り替えるタイミング、複数のボタンが押されているか離されているか、または一連のボタンが特定の方法で配置されているか、一部のボタンが押されていないかを判断する必要がある場合があります。 これらの状態を検出する方法の詳細については、「ボタン移行の検出」および「複雑なボタン配置の検出」を参照してください。

UI ナビゲーション コントローラーのサンプルを実行する

InputInterfacingUWP サンプル (github)は、さまざまな入力デバイスが UI ナビゲーション コントローラーとしてどのように動作するかを示しています。

関連項目

Windows.Gaming.Input.GamepadWindows.Gaming.Input.ArcadeStickWindows.Gaming.Input.RacingWheelWindows.Gaming.Input.IGameController