Conditions:
Using multiple (in my case 4) Vive Trackers. Each one is mapped on a MotionControllerComponent as MotionSource Special_1-4.
Behavior:
If one of the trackers gets disconnected during gameplay and then reconnected, it is assigned as a different Special_N motion source, overwriting the original Special_N.
Relevant code and discussion:
The following code assigns input source number based on the number of already mapped trackers.
If I have four mapped devices, Special_1-4 and the first one gets disconnected, I am left with three mapped devices: Special_2-4. If the disconnected device (previously Special_1) gets reconnected, it is assigned as NumMappedDevices+1, i.e. Special_4, overwriting the previously assigned Special_4 in the process.
Console output:
LogSteamVRController: Tracker device 1 is being assigned unreal hand: Special 1, for player 0
LogSteamVRController: Tracker device 2 is being assigned unreal hand: Special 2, for player 0
LogSteamVRController: Tracker device 3 is being assigned unreal hand: Special 3, for player 0
LogSteamVRController: Tracker device 4 is being assigned unreal hand: Special 4, for player 0
LogSteamVRController: Tracker device 1 is being assigned unreal hand: Special 4, for player 0
Code: SteamVRController::RegisterTracker() SteamVRController.cpp, line 1017.
bool RegisterTracker(uint32 DeviceIndex)
{
// check to see if there are any Special designations left, skip mapping it if there are not
if (NumTrackersMapped >= MaxSpecialDesignations)
{
// go ahead and increment, so we can display a little more info in the log
++NumTrackersMapped;
UE_LOG(LogSteamVRController, Warning, TEXT("Unable to map VR tracker (#%i) to Special hand designation!"), NumTrackersMapped);
return false;
}
// add the tracker to player 0
DeviceToControllerMap[DeviceIndex] = GENERIC_TRACKER_PLAYER_NUM;
// select next special #
switch (NumTrackersMapped)
{
case 0:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_1;
break;
case 1:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_2;
break;
case 2:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_3;
break;
case 3:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_4;
break;
case 4:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_5;
break;
case 5:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_6;
break;
case 6:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_7;
break;
case 7:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_8;
break;
case 8:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_9;
break;
case 9:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_10;
break;
case 10:
ControllerStates[DeviceIndex].Hand = EControllerHand::Special_11;
break;
default:
// initial mapping verification above should catch any erroneous NumTrackersMapped
check(false);
break;
}
++NumTrackersMapped;
UE_LOG(LogSteamVRController, Log, TEXT("Tracker device %i is being assigned unreal hand: Special %i, for player %i"), DeviceIndex, NumTrackersMapped, GENERIC_TRACKER_PLAYER_NUM);
SetUnrealControllerIdToControllerIndex(DeviceToControllerMap[DeviceIndex], ControllerStates[DeviceIndex].Hand, DeviceIndex);
return true;
}