This topic shows how to use a reusable class named NuiBodyUserMapping to get the pairing between bodies and users by using an event driven approach.
In the Initialize function, add the following code to create a NuiBodyUserMapping object named pUserMapping.
C++
NuiBodyUserMapping* pUserMapping = new NuiBodyUserMapping();
pUserMapping->Initialize();
In the Update function, add the following code to keep track of the mapping with pUserMapping.
C++
NUI_FRAME frame;
User^ users[NUI_BODY_COUNT];
HRESULT hr = NuiStreamGetNextFrame( NUI_STREAM_TYPE_BODY, &frame );
if( SUCCEEDED(hr) )
{
const NUI_BODY_FRAME* pBodyFrame = static_cast<const NUI_BODY_FRAME*>( frame.pData );
for( UINT32 i = 0; i < NUI_BODY_COUNT; i++ )
{
if( NUI_BODY_TRACKED == (pBodyFrame->BodyData[i]).TrackingState )
{
users[i] = pUserMapping->GetUser( (pBodyFrame->BodyData[i]).TrackingID );
}
}
}
In the Shutdown function, add the following code to release pUserMapping.
C++
delete(pUserMapping);
C++
#pragma once
/************************************************************************
* *
* NuiBodyUserMapping.h -- *
* Implements the body to user mapping helper functions. *
* *
* *
* Copyright (c) Microsoft Corp. All rights reserved. *
* *
************************************************************************/
using namespace Windows::Xbox::Input::Nui;
using namespace Windows::Xbox::System;
using namespace Windows::Xbox::Input;
using namespace Windows::Foundation;
class NuiBodyUserMapping
{
private:
//
// Defines the structure that contains the body and user pair.
// On Xbox One, a body is considered as a controller.
//
struct NuiBodyUserPair
{
UINT64 controllerID; User^ user;
NuiBodyUserPair()
{
controllerID = NUI_BODY_INVALID_TRACKING_ID;
}
};
NuiBodyUserPair m_Pair[NUI_BODY_COUNT];
CRITICAL_SECTION m_Lock;
public:
NuiBodyUserMapping()
{
InitializeCriticalSection( &m_Lock );
}
~NuiBodyUserMapping()
{
DeleteCriticalSection( &m_Lock );
}
void OnPairingChanged(IController^ controller,
User^ user)
{
if( controller->Type != L"Windows.Xbox.Input.Nui.Body" )
{
return;
}
UINT64 controllerID = controller->ControllerId;
{
EnterCriticalSection( &m_Lock );
bool found = false;
for( UINT32 i = 0; i < NUI_BODY_COUNT; i++ )
{
if( m_Pair[i].controllerID == controllerID )
{
if( user != nullptr )
{
m_Pair[i].user = user;
}
else
{
m_Pair[i].controllerID = NUI_BODY_INVALID_TRACKING_ID;
}
found = true;
break;
}
}
if ( !found && user != nullptr )
{
for( UINT32 i = 0; i < NUI_BODY_COUNT; i++ )
{
if( m_Pair[i].controllerID == NUI_BODY_INVALID_TRACKING_ID )
{
m_Pair[i].controllerID = controllerID;
m_Pair[i].user = user;
break;
}
}
}
LeaveCriticalSection( &m_Lock );
}
}
Windows::Xbox::System::User^ GetUser( UINT64 TrackingID )
{
EnterCriticalSection( &m_Lock );
User^ user = nullptr;
for( INT32 i = 0; i < NUI_BODY_COUNT; i++ )
{
if( m_Pair[i].controllerID == TrackingID )
{
user = m_Pair[i].user;
break;
}
}
LeaveCriticalSection( &m_Lock );
return user;
}
void Initialize()
{
Controller::ControllerPairingChanged += ref new
EventHandler< ControllerPairingChangedEventArgs^
>( [=]( Platform::Object^ , ControllerPairingChangedEventArgs^ args )
{ OnPairingChanged(args->Controller, args->User); } );
Controller::ControllerRemoved += ref new
EventHandler< ControllerRemovedEventArgs^ >( [=]( Platform::Object^ ,
ControllerRemovedEventArgs^ args )
{ OnPairingChanged(args->Controller, nullptr); } );
auto controllers = Controller::GetControllers();
UINT size = controllers->Size;
for ( UINT i = 0; i < size; ++i )
{
auto controller = controllers->GetAt( i );
OnPairingChanged( controller, controller->User );
}
}
};
Getting Started with the Gamepad API
How to: Activate the Gamepad Impulse Triggers
How to: Detect Whether a Gamepad Button Is Pressed
How to: Activate Controller Vibration