How can I determine if a XR controller is connected or not?
I have tried two methods so far, without success.
- I tried to get this information from a instance of “XRBaseController”, but I cant find a way to see if a controller is connected.
2.Made use of InputDevices.GetDevicesAtXRNode. With this I can see when a controller is connected, but it doesn’t seem to be able to tell me if a controller gets turned off.
void Update()
{
List<InputDevice> xrInputDevices = new List<InputDevice>();
InputDevices.GetDevicesAtXRNode(XRNode.RightHand, xrInputDevices);
bool isControllerConnected= false;
for (int i = 0; i < xrInputDevices.Count; ++i)
if (xrInputDevices[i].isValid)
isControllerConnected= true;
this.isControllerConnected = isControllerConnected;
}
I believe this is exactly what you are looking for::
XR Input under section Listening for device connections and disconnections:
(Unity - Manual: Unity XR Input)
“To avoid repeatedly checking if a device is connected to the platform, use InputDevices.deviceConnected and InputDevices.deviceDisconnected to notify your application when a device connects or disconnects.”
Then, all you should need is this:
/* If you want to set "isControllerConnected" if the first device matches the XRNode:: */
InputDevice xrInputDevice;
bool isControllerConnected;
IEnumerator Start()
{
// Get target devices
List<InputDevice>() xrInputDevices = new List<InputDevice>();
InputDevices.GetDevicesAtXRNode(XRNode.RightHand, xrInputDevices);
while (xrInputDevices.Count <= 0)
{
// wait for a device to be found.
yield return null;
InputDevices.GetDevicesAtXRNode(XRNode.RightHand, xrInputDevices);
}
xrInputDevice = xrInputDevices[0];
// Initialize if controller is connected
isControllerConnected = xrInputDevice.isValid;
// Add listeners for devices being connected/disconected
InputDevices.deviceConnected += (device) =>
{
if (xrInputDevice == device)
connectedDevices++;
}
InputDevices.deviceDisconnected += (device) =>
{
if (xrInputDevice == device)
connectedDevices--;
}
}
/* If you want to set "isControllerConnected" if ANY device matches the XRNode:: */
List<InputDevice> xrInputDevices;
int connectedDevices; // Keeps track of the current number
bool isControllerConnected { get => connectedDevices > 0; } // returns true if at least one device is active.
void Start()
{
// Get target devices
xrInputDevices = new List<InputDevice>();
InputDevices.GetDevicesAtXRNode(XRNode.RightHand, xrInputDevices);
// Initialize the number of connected devices
connectedDevices = 0;
foreach (InputDevice device in xrInputDevices)
if (device.isValid == true)
connectedDevices++;
// Add listeners for devices being connected/disconected
InputDevices.deviceConnected += (device) =>
{
// xrInputDevices is fixed at the time of starting this component. Consider adding devices to the list when they are connected and match the XRNode.
if (xrInputDevices.Contains(device))
connectedDevices++;
}
InputDevices.deviceDisconnected += (device) =>
{
if (xrInputDevices.Contains(device))
connectedDevices--;
}
}
2 Likes
This is exactly what I was looking for. Thank you!
1 Like