DirectX でのキーボード、マウス、およびコントローラー入力Keyboard, mouse, and controller input in DirectX

Windows Mixed Reality デバイスでは、キーボード、マウス、およびゲームコントローラーはすべて、便利な入力形式です。Keyboards, mice, and game controllers can all be useful forms of input for Windows Mixed Reality devices. Bluetooth キーボードとマウスは両方とも HoloLens でサポートされており、アプリのデバッグや別の入力形式として使用できます。Bluetooth keyboards and mice are both supported on HoloLens, for use with debugging your app or as an alternate form of input. Windows Mixed Reality では、Pc に接続されているイマーシブヘッドセットもサポートされています。マウス、キーボード、およびゲームコントローラーは、従来は標準でした。Windows Mixed Reality also supports immersive headsets attached to PCs - where mice, keyboards, and game controllers have historically been the norm.

HoloLens でキーボード入力を使用するには、Bluetooth キーボードをデバイスにペアリングするか、Windows デバイスポータルを使用して仮想入力を使用します。To use keyboard input on HoloLens, pair a Bluetooth keyboard to your device or use virtual input via the Windows Device Portal. Windows Mixed Reality のイマーシブヘッドセットを装着しているときにキーボード入力を使用するには、をデバイスに配置するか、Windows キーと Y キーの組み合わせを使用して、混合現実に入力フォーカスを割り当てます。To use keyboard input while wearing a Windows Mixed Reality immersive headset, assign input focus to mixed reality by putting on the device or using the Windows Key + Y keyboard combination. HoloLens 用のアプリは、これらのデバイスが接続されていない機能を提供する必要があることに注意してください。Keep in mind that apps intended for HoloLens must provide functionality without these devices attached.

注意

この記事のコードスニペットでは、現在、 C++ C++ holographic プロジェクトテンプレートで使用されてC++いる C + c++ 17 準拠の/WinRT ではなく、/cx の使用方法を示しています。The code snippets in this article currently demonstrate use of C++/CX rather than C++17-compliant C++/WinRT as used in the C++ holographic project template. これらの概念は、プロジェクトC++の場合と同じですが、コードを変換する必要があります。The concepts are equivalent for a C++/WinRT project, though you will need to translate the code.

CoreWindow 入力イベントをサブスクライブしますSubscribe for CoreWindow input events

キーボード入力Keyboard input

Windows Holographic アプリテンプレートでは、他の UWP アプリと同じように、キーボード入力用のイベントハンドラーが追加されています。In the Windows Holographic app template, we include an event handler for keyboard input just like any other UWP app. アプリでは、Windows Mixed Reality と同じ方法でキーボード入力データを使用します。Your app consumes keyboard input data the same way in Windows Mixed Reality.

AppView .cpp から:From AppView.cpp:

// Register for keypress notifications.
   window->KeyDown +=
       ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &AppView::OnKeyPressed);

    …

   // Input event handlers

   void AppView::OnKeyPressed(CoreWindow^ sender, KeyEventArgs^ args)
   {
       //
       // TODO: Respond to keyboard input here.
       //
   }

仮想キーボード入力Virtual keyboard input

イマーシブデスクトップヘッドセットの場合は、Windows によってレンダリングされた仮想キーボードをイマーシブビューでサポートすることもできます。For immersive desktop headsets, you can also support virtual keyboards rendered by Windows over your immersive view. これをサポートするために、アプリはCoreTextEditContextを実装できます。To support this, your app can implement CoreTextEditContext. これにより、Windows はアプリでレンダリングされたテキストボックスの状態を把握できるようになり、仮想キーボードがそこにあるテキストに正しく参加できるようになります。This lets Windows understand the state of your own app-rendered text boxes, so the virtual keyboard can correctly contribute to the text there.

CoreTextEditContext サポートの実装の詳細については、 CoreTextEditContext サンプルを参照してください。For more information on implementing CoreTextEditContext support, see the CoreTextEditContext sample.

マウス入力Mouse Input

また、UWP CoreWindow 入力イベントハンドラーを使用して、マウス入力を再度使用することもできます。You can also use mouse input, again via the UWP CoreWindow input event handlers. ここでは、Windows Holographic アプリケーションテンプレートを変更して、マウスのクリック操作を、押したジェスチャと同じようにサポートする方法について説明します。Here's how to modify the Windows Holographic app template to support mouse clicks in the same way as pressed gestures. この変更を行った後、イマーシブヘッドセットデバイスの装着中にマウスをクリックすると、キューブが再配置されます。After making this modification, a mouse click while wearing an immersive headset device will reposition the cube.

UWP アプリでは、 Mousedevice API を使用してマウスの生の XY データを取得することもできます。Note that UWP apps can also get raw XY data for the mouse by using the MouseDevice API.

まず、AppView. h で新しい Onポインタ押されたハンドラーを宣言します。Start by declaring a new OnPointerPressed handler in AppView.h:

protected:
       void OnPointerPressed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::PointerEventArgs^ args);

AppView .cpp で、次のコードを SetWindow に追加します。In AppView.cpp, add this code to SetWindow:

// Register for pointer pressed notifications.
   window->PointerPressed +=
       ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &AppView::OnPointerPressed);

次に、この定義を、ファイルの末尾で押された Onポインタに配置します。Then put this definition for OnPointerPressed at the bottom of the file:

void AppView::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
   {
       // Allow the user to interact with the holographic world using the mouse.
       if (m_main != nullptr)
       {
           m_main->OnPointerPressed();
       }
   }

追加したイベントハンドラーは、テンプレートのメインクラスへのパススルーです。The event handler we just added is a pass-through to the template main class. このパススルーをサポートするようにメインクラスを変更してみましょう。Let's modify the main class to support this pass-through. 次のパブリックメソッド宣言をヘッダーファイルに追加します。Add this public method declaration to the header file:

// Handle mouse input.
       void OnPointerPressed();

このプライベートメンバー変数も必要になります。You'll need this private member variable, as well:

// Keep track of mouse input.
       bool m_pointerPressed = false;

最後に、メインクラスを新しいロジックで更新して、マウスのクリックをサポートします。Finally, we will update the main class with new logic to support mouse clicks. まず、このイベントハンドラーを追加します。Start by adding this event handler. クラス名を必ず更新してください。Make sure to update the class name:

void MyHolographicAppMain::OnPointerPressed()
   {
       m_pointerPressed = true;
   }

次に、Update メソッドで、ポインターを取得するための既存のロジックを次のように置き換えます。Now, in the Update method, replace the existing logic for getting a pointer pose with this:

SpatialInteractionSourceState^ pointerState = m_spatialInputHandler->CheckForInput();
   SpatialPointerPose^ pose = nullptr;
   if (pointerState != nullptr)
   {
       pose = pointerState->TryGetPointerPose(currentCoordinateSystem);
   }
   else if (m_pointerPressed)
   {
       pose = SpatialPointerPose::TryGetAtTimestamp(currentCoordinateSystem, prediction->Timestamp);
   }
   m_pointerPressed = false;

再コンパイルして再デプロイします。Recompile and redeploy. マウスをクリックすると、bluetooth マウスが接続されているイマーシブヘッドセットまたは HoloLens のキューブが再配置されることがわかります。You should notice that the mouse click will now reposition the cube in your immersive headset - or HoloLens with bluetooth mouse attached.

ゲームコントローラーのサポートGame controller support

ゲームコントローラーは、ユーザーがイマーシブ Windows Mixed Reality エクスペリエンスを制御できる楽しい便利な方法です。Game controllers can be a fun and convenient way of allowing the user to control an immersive Windows Mixed Reality experience.

Windows Holographic アプリテンプレートにゲームコントローラーのサポートを追加するには、まず、次のプライベートメンバー宣言をメインファイルの header クラスに追加します。The first step in adding support for game controllers to the Windows Holographic app template, is to add the following private member declarations to the header class for your main file:

// Recognize gamepads that are plugged in after the app starts.
       void OnGamepadAdded(Platform::Object^, Windows::Gaming::Input::Gamepad^ args);
// Stop looking for gamepads that are unplugged.
       void OnGamepadRemoved(Platform::Object^, Windows::Gaming::Input::Gamepad^ args);
Windows::Foundation::EventRegistrationToken                     m_gamepadAddedEventToken;
       Windows::Foundation::EventRegistrationToken                     m_gamepadRemovedEventToken;
// Keeps track of a gamepad and the state of its A button.
       struct GamepadWithButtonState
       {
           Windows::Gaming::Input::Gamepad^ gamepad;
           bool buttonAWasPressedLastFrame = false;
       };
       std::vector<GamepadWithButtonState>                             m_gamepads;

メインクラスのコンストラクターで、ゲームパッドイベントと、現在アタッチされているすべてのゲームパッドを初期化します。Initialize gamepad events, and any gamepads that are currently attached, in the constructor for your main class:

// If connected, a game controller can also be used for input.
   m_gamepadAddedEventToken = Gamepad::GamepadAdded +=
       ref new EventHandler<Gamepad^>(
           bind(&$safeprojectname$Main::OnGamepadAdded, this, _1, _2)
           );
m_gamepadRemovedEventToken = Gamepad::GamepadRemoved +=
       ref new EventHandler<Gamepad^>(
           bind(&$safeprojectname$Main::OnGamepadRemoved, this, _1, _2)
           );
for (auto const& gamepad : Gamepad::Gamepads)
   {
       OnGamepadAdded(nullptr, gamepad);
   }

これらのイベントハンドラーを main クラスに追加します。Add these event handlers to your main class. クラス名を必ず更新してください。Make sure to update the class name:

void MyHolographicAppMain::OnGamepadAdded(Object^, Gamepad^ args)
   {
       for (auto const& gamepadWithButtonState : m_gamepads)
       {
           if (args == gamepadWithButtonState.gamepad)
           {
               // This gamepad is already in the list.
               return;
           }
       }
       m_gamepads.push_back({ args, false });
   }
void MyHolographicAppMain::OnGamepadRemoved(Object^, Gamepad^ args)
   {
       m_gamepads.erase(
           std::remove_if(m_gamepads.begin(), m_gamepads.end(), [&](GamepadWithButtonState& gamepadWithState)
               {
                   return gamepadWithState.gamepad == args;
               }),
           m_gamepads.end());
   }

最後に、コントローラーの状態の変更を認識するように入力ロジックを更新します。Finally, update the input logic to recognize changes in controller state. ここでは、前のセクションで説明したのと同じ m_pointerPressed 変数を使用して、マウスイベントを追加します。Here, we use the same m_pointerPressed variable discussed in the section above for adding mouse events. SpatialPointerPose をチェックする直前に、Update メソッドに次を追加します。Add this to the Update method, just before where it checks for the SpatialPointerPose:

// Check for new input state since the last frame.
   for (auto& gamepadWithButtonState : m_gamepads)
   {
       bool buttonDownThisUpdate = ((gamepadWithButtonState.gamepad->GetCurrentReading().Buttons & GamepadButtons::A) == GamepadButtons::A);
       if (buttonDownThisUpdate && !gamepadWithButtonState.buttonAWasPressedLastFrame)
       {
           m_pointerPressed = true;
       }
       gamepadWithButtonState.buttonAWasPressedLastFrame = buttonDownThisUpdate;
   }
// For context.
   SpatialInteractionSourceState^ pointerState = m_spatialInputHandler->CheckForInput();
   SpatialPointerPose^ pose = nullptr;
   if (pointerState != nullptr)
   {
       pose = pointerState->TryGetPointerPose(currentCoordinateSystem);
   }
   else if (m_pointerPressed)
   {
       pose = SpatialPointerPose::TryGetAtTimestamp(currentCoordinateSystem, prediction->Timestamp);
   }
   m_pointerPressed = false;

メインクラスをクリーンアップするときは、必ずイベントの登録を解除してください。Don't forget to unregister the events when cleaning up the main class:

if (m_gamepadAddedEventToken.Value != 0)
   {
       Gamepad::GamepadAdded -= m_gamepadAddedEventToken;
   }
   if (m_gamepadRemovedEventToken.Value != 0)
   {
       Gamepad::GamepadRemoved -= m_gamepadRemovedEventToken;
   }

再コンパイルし、再デプロイします。Recompile, and redeploy. これで、ゲームコントローラーをアタッチまたはペアリングし、回転するキューブの位置を変更することができます。You can now attach, or pair, a game controller and use it to reposition the spinning cube.

キーボードとマウスの入力に関する重要なガイドラインImportant guidelines for keyboard and mouse input

Microsoft HoloLens でこのコードを使用する方法には、主な違いがいくつかあります。これは、主に自然なユーザー入力に依存するデバイスであり、Windows Mixed Reality 対応 PC で使用できるものと同じです。There are some key differences in how this code can be used on Microsoft HoloLens – which is a device that relies primarily on natural user input – versus what is available on a Windows Mixed Reality-enabled PC.

  • キーボードやマウスの入力に依存することはできません。You can’t rely on keyboard or mouse input to be present. アプリのすべての機能は、宝石、ジェスチャ、音声入力で動作する必要があります。All of your app's functionality must work with gaze, gesture, and speech input.
  • Bluetooth キーボードが接続されている場合は、アプリが要求するテキストに対してキーボード入力を有効にすると便利です。When a Bluetooth keyboard is attached, it can be helpful to enable keyboard input for any text that your app might ask for. これは、たとえば、ディクテーションの優れた補完です。This can be a great supplement for dictation, for example.
  • アプリを設計する際には、ゲームのために (たとえば) WASD やマウスのコントロールを使用しないようにしてください。When it comes to designing your app, don’t rely on (for example) WASD and mouse look controls for your game. HoloLens は、ユーザーが部屋を移動するように設計されています。HoloLens is designed for the user to walk around the room. この場合、ユーザーはカメラを直接制御します。In this case, the user controls the camera directly. 移動/表示コントロールを使用して、部屋の周りにカメラを運転するためのインターフェイスは、同じエクスペリエンスを提供しません。An interface for driving the camera around the room with move/look controls won't provide the same experience.
  • キーボード入力は、特にユーザーがキーボードを使用する必要がないため、アプリまたはゲームエンジンのデバッグ側面を制御するのに優れた方法です。Keyboard input can be an excellent way to control the debugging aspects of your app or game engine, especially since the user will not be required to use the keyboard. この配線は、CoreWindow イベント Api を使用した場合と同じです。Wiring it up is the same as you're used to, with CoreWindow event APIs. このシナリオでは、デバッグセッション中にキーボードイベントを "デバッグ入力のみ" モードにルーティングするようにアプリを構成する方法を実装することを選択できます。In this scenario, you might choose to implement a way to configure your app to route keyboard events to a "debug input only" mode during your debug sessions.
  • Bluetooth コントローラーも同様に機能します。Bluetooth controllers work as well.

参照See also