Entrada de teclado, mouse e controlador no DirectXKeyboard, mouse, and controller input in DirectX

Teclados, mouses e controladores de jogos podem ser formas úteis de entrada para dispositivos Windows Mixed Reality.Keyboards, mice, and game controllers can all be useful forms of input for Windows Mixed Reality devices. Os teclados e os mouses Bluetooth têm suporte no HoloLens, para uso com a depuração do aplicativo ou como uma forma alternativa de entrada.Bluetooth keyboards and mice are both supported on HoloLens, for use with debugging your app or as an alternate form of input. A realidade mista do Windows também dá suporte a headsets de imersão conectadas a PCs – onde os mouses, teclados e controladores de jogos têm sido historicamente a norma.Windows Mixed Reality also supports immersive headsets attached to PCs - where mice, keyboards, and game controllers have historically been the norm.

Para usar a entrada de teclado no HoloLens, Emparelhe um teclado Bluetooth para seu dispositivo ou use a entrada virtual por meio do portal de dispositivo do Windows.To use keyboard input on HoloLens, pair a Bluetooth keyboard to your device or use virtual input via the Windows Device Portal. Para usar a entrada de teclado ao utilizar um headset de imersão de realidade mista do Windows, atribua o foco de entrada à realidade mista, colocando no dispositivo ou usando a combinação de teclas do 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. Tenha em mente que os aplicativos destinados ao HoloLens devem fornecer funcionalidade sem esses dispositivos conectados.Keep in mind that apps intended for HoloLens must provide functionality without these devices attached.

Observação

Os trechos de código neste artigo demonstram atualmente o C++uso de/CX em vez de/WinRT em C++conformidade com C + +17, conforme usado no C++ modelo de projeto Holographic.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. Os conceitos são equivalentes a C++um projeto/WinRT, embora você precise converter o código.The concepts are equivalent for a C++/WinRT project, though you will need to translate the code.

Assinar eventos de entrada do CoreWindowSubscribe for CoreWindow input events

Entrada por tecladoKeyboard input

No modelo de aplicativo Holographic do Windows, incluímos um manipulador de eventos para entrada de teclado, assim como qualquer outro aplicativo UWP.In the Windows Holographic app template, we include an event handler for keyboard input just like any other UWP app. Seu aplicativo consome dados de entrada de teclado da mesma maneira no Windows Mixed Reality.Your app consumes keyboard input data the same way in Windows Mixed Reality.

De 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.
       //
   }

Entrada de teclado virtualVirtual keyboard input

Para headsets de área de trabalho de imersão, você também pode dar suporte a teclados virtuais renderizados pelo Windows sobre sua exibição de imersão.For immersive desktop headsets, you can also support virtual keyboards rendered by Windows over your immersive view. Para dar suporte a isso, seu aplicativo pode implementar o CoreTextEditContext.To support this, your app can implement CoreTextEditContext. Isso permite que o Windows entenda o estado de suas próprias caixas de texto renderizadas pelo aplicativo, de modo que o teclado virtual possa contribuir corretamente para o texto lá.This lets Windows understand the state of your own app-rendered text boxes, so the virtual keyboard can correctly contribute to the text there.

Para obter mais informações sobre como implementar o suporte a CoreTextEditContext, consulte o exemplo CoreTextEditContext.For more information on implementing CoreTextEditContext support, see the CoreTextEditContext sample.

Entrada do mouseMouse Input

Você também pode usar a entrada do mouse, novamente por meio dos manipuladores de eventos de entrada UWP CoreWindow.You can also use mouse input, again via the UWP CoreWindow input event handlers. Aqui está como modificar o modelo de aplicativo Holographic do Windows para dar suporte a cliques do mouse da mesma maneira que os gestos pressionados.Here's how to modify the Windows Holographic app template to support mouse clicks in the same way as pressed gestures. Depois de fazer essa modificação, um clique do mouse ao usar um dispositivo de headset de imersão reposicionará o cubo.After making this modification, a mouse click while wearing an immersive headset device will reposition the cube.

Observe que os aplicativos UWP também podem obter dados XY brutos para o mouse usando a API MouseDevice .Note that UWP apps can also get raw XY data for the mouse by using the MouseDevice API.

Comece declarando um novo manipulador OnPointerPressed em AppView. h:Start by declaring a new OnPointerPressed handler in AppView.h:

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

Em AppView. cpp, adicione este código a SetWindow:In AppView.cpp, add this code to SetWindow:

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

Em seguida, coloque essa definição para OnPointerPressed na parte inferior do arquivo: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();
       }
   }

O manipulador de eventos que acabamos de adicionar é uma passagem para a classe principal do modelo.The event handler we just added is a pass-through to the template main class. Vamos modificar a classe principal para dar suporte a essa passagem.Let's modify the main class to support this pass-through. Adicione essa declaração de método público ao arquivo de cabeçalho:Add this public method declaration to the header file:

// Handle mouse input.
       void OnPointerPressed();

Você também precisará dessa variável de membro privado:You'll need this private member variable, as well:

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

Por fim, atualizaremos a classe principal com nova lógica para dar suporte a cliques do mouse.Finally, we will update the main class with new logic to support mouse clicks. Comece adicionando este manipulador de eventos.Start by adding this event handler. Certifique-se de atualizar o nome da classe:Make sure to update the class name:

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

Agora, no método Update, substitua a lógica existente para obter uma pose de ponteiro com esta: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 e reimplante.Recompile and redeploy. Você deve observar que o clique do mouse agora reposicionará o cubo no headset de imersão ou no HoloLens com o mouse Bluetooth anexado.You should notice that the mouse click will now reposition the cube in your immersive headset - or HoloLens with bluetooth mouse attached.

Suporte ao controlador de jogosGame controller support

Os controladores de jogo podem ser uma maneira divertida e conveniente de permitir que o usuário controle uma experiência de realidade do Windows Mixed realm.Game controllers can be a fun and convenient way of allowing the user to control an immersive Windows Mixed Reality experience.

A primeira etapa para adicionar suporte a controladores de jogos ao modelo de aplicativo Holographic do Windows é adicionar as seguintes declarações de membro privado à classe de cabeçalho para o arquivo principal: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;

Inicializar eventos do gamepad e todos os gamepads que estão anexados no momento, no construtor para sua classe principal: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);
   }

Adicione esses manipuladores de eventos à classe principal.Add these event handlers to your main class. Certifique-se de atualizar o nome da classe: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());
   }

Por fim, atualize a lógica de entrada para reconhecer as alterações no estado do controlador.Finally, update the input logic to recognize changes in controller state. Aqui, usamos a mesma variável m_pointerPressed discutida na seção acima para adicionar eventos de mouse.Here, we use the same m_pointerPressed variable discussed in the section above for adding mouse events. Adicione isso ao método Update, pouco antes de onde ele verifica o SpatialPointerPose: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;

Não se esqueça de cancelar o registro dos eventos ao limpar a classe principal: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 e reimplante.Recompile, and redeploy. Agora você pode anexar ou emparelhar um controlador de jogo e usá-lo para reposicionar o cubo de rotação.You can now attach, or pair, a game controller and use it to reposition the spinning cube.

Diretrizes importantes para entrada de teclado e mouseImportant guidelines for keyboard and mouse input

Há algumas diferenças importantes em como esse código pode ser usado no Microsoft HoloLens – que é um dispositivo que depende principalmente da entrada natural do usuário – em comparação com o que está disponível em um PC com o Windows Mixed Reality habilitado.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.

  • Você não pode contar com o teclado ou a entrada do mouse para estar presente.You can’t rely on keyboard or mouse input to be present. Toda a funcionalidade do seu aplicativo deve funcionar com olhar, gesto e entrada de fala.All of your app's functionality must work with gaze, gesture, and speech input.
  • Quando um teclado Bluetooth é anexado, pode ser útil habilitar a entrada de teclado para qualquer texto que seu aplicativo possa solicitar.When a Bluetooth keyboard is attached, it can be helpful to enable keyboard input for any text that your app might ask for. Isso pode ser um excelente suplemento para ditado, por exemplo.This can be a great supplement for dictation, for example.
  • Quando se trata de criar seu aplicativo, não confie (por exemplo) WASD e controles de aparência do mouse para seu jogo.When it comes to designing your app, don’t rely on (for example) WASD and mouse look controls for your game. O HoloLens foi projetado para que o usuário percorra a sala.HoloLens is designed for the user to walk around the room. Nesse caso, o usuário controla a câmera diretamente.In this case, the user controls the camera directly. Uma interface para orientar a câmera em todo o espaço com os controles mover/procurar não fornecerá a mesma experiência.An interface for driving the camera around the room with move/look controls won't provide the same experience.
  • A entrada de teclado pode ser uma maneira excelente de controlar os aspectos de depuração do seu aplicativo ou do seu mecanismo de jogo, especialmente, uma vez que o usuário não será solicitado a usar o teclado.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. Conectar-se a ele é o mesmo que você está acostumado a, com APIs de evento CoreWindow.Wiring it up is the same as you're used to, with CoreWindow event APIs. Nesse cenário, você pode optar por implementar uma maneira de configurar seu aplicativo para rotear eventos de teclado para um modo de "somente entrada de depuração" durante as sessões de depuração.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.
  • Controladores Bluetooth também funcionam.Bluetooth controllers work as well.

Consulte tambémSee also