Jump to content

Issue with Detecting Controller Connection/Disconnection onVive XR Elite in Unity (using UnityEngine.XR).


Linkone

Recommended Posts

I am developing an application targeting the Vive XR Elite 3 with Unity 2021.3.30 LTS. My application needs to detect when a motion controller is connected or disconnected. I've implemented this functionality using Unity's InputDevices.deviceConnected and InputDevices.deviceDisconnected events.

The code works as expected when running on my PC using a Vive Pro headset + controllers, but it fails to detect controller connections and disconnections when running on the Vive XR Elite build. I am logging any errors and there any. It seems to me that the events are never fired.

Here's a simplified version of my code:

Can someone help me to understand if I can use something else to achieve this?

 

public event Action<ControllerName> OnControllerConnected;
    public event Action<ControllerName> OnControllerDisconnected;

    public enum ControllerName
    {
        Left,
        Right
    }

    private void OnEnable()
    {
        InputDevices.deviceConnected += OnDeviceConnected;
        InputDevices.deviceDisconnected += OnDeviceDisconnected;
    }

    private void OnDisable()
    {
        InputDevices.deviceConnected -= OnDeviceConnected;
        InputDevices.deviceDisconnected -= OnDeviceDisconnected;
    }

  private void OnDeviceConnected(UnityEngine.XR.InputDevice device)
  {
  	Debug.Log("Device connected: " + device.name);
  	if ((device.characteristics & InputDeviceCharacteristics.Left) != 0)
  	{
  		Debug.Log("Left Controller Connected");
  		OnControllerConnected?.Invoke(ControllerName.Left);
  	}
  	else if ((device.characteristics & InputDeviceCharacteristics.Right) != 0)
  	{
  		Debug.Log("Right Controller Connected");
  		OnControllerConnected?.Invoke(ControllerName.Right);
  	}
  }

  private void OnDeviceDisconnected(UnityEngine.XR.InputDevice device)
  {
  	Debug.Log("Device connected: " + device.name);
  	if ((device.characteristics & InputDeviceCharacteristics.Left) != 0)
  	{
  		Debug.Log("Left Controller Disconnected");
  		OnControllerDisconnected?.Invoke(ControllerName.Left);
  	}
  	else if ((device.characteristics & InputDeviceCharacteristics.Right) != 0)
  	{
  		Debug.Log("Right Controller Disconnected");
  		OnControllerDisconnected?.Invoke(ControllerName.Right);
  	}
  }

 

Link to comment
Share on other sites

Hi @Linkone

Just for a sanity check:

  1. Are the controllers otherwise accessible otherwise, do rendermodels show up and/or other visualiztions on the relevant tracked pose driver/controller?
  2. is this openxr or wave sdk we're talking about here? 
  3. Is the vive-specific controller profile on the input profile or only the generic xr controller or "Vive focus 3 controller"?
    image.thumb.png.4f08cf317ae89f72f9a115062e0e9305.png
  4. What devices are listed in Inputdevices.GetDevices https://docs.unity3d.com/2020.1/Documentation/ScriptReference/XR.InputDevices.GetDevices.html --the event for registering the device may be firing before the connection, and this call will let you know all devices that are connected, regardless of when the script runs or events fire
  5. Is there an active device on the relevant profile? 
  6. As a sanity check - do these repos work for you:
    1. https://github.com/ViveDeveloperRelations/MinimalRepo/tree/wave_controller_examples - the "wave_controller_examples" branch the wave controller sample scene
    2. if on openxr:  https://github.com/hardcoded2/Updated-XR-Interaction-Toolkit-Examples/tree/openxr - does the "openxr" branch work for you? 
    3. if on wave: https://github.com/ViveDeveloperRelations/XR-Interaction-Toolkit-Examples/tree/wave_openxr_xr_origin does the branch "wave" branch work for you in the "vr" project?

 

Link to comment
Share on other sites

@Alex_HTC Thank you for your reply. See answers below in your quoted message. Thank you for your suggestions.

17 hours ago, Alex_HTC said:
  1. Are the controllers otherwise accessible otherwise, do rendermodels show up and/or other visualiztions on the relevant tracked pose driver/controller?
    Yes controllers are otherwise accessible, using the Input system and a customized Input Actions that runs in parallel to the XRI Default Input Action. Rendermodels show up correclty and are tracked correctly. I am using the XR Controller (Action-based). I am able to press the trigger button and the a/b + x/y buttons. RenderModel I got it from the VIVE OpenXR Toolkit Samples and 

    image.thumb.png.d972b84903ef544403d14f9777132703.png
    image.png.a36b847512f51cafc62888a0e34dfe76.png
  2. is this openxr or wave sdk we're talking about here?
    It is purely OpenXR and I would avoid installing a new package for just this.
  3. Is the vive-specific controller profile on the input profile or only the generic xr controller or "Vive focus 3 controller"?
    I have both the HTC Vive Controller when available (trigger) and "the Vive Focus 3 Controller" (trigger/a/b)
  4. What devices are listed in Inputdevices.GetDevices https://docs.unity3d.com/2020.1/Documentation/ScriptReference/XR.InputDevices.GetDevices.html --the event for registering the device may be firing before the connection, and this call will let you know all devices that are connected, regardless of when the script runs or events fire
    Thanks for this suggestion. I might actually use it in case my current solution does not work
  5. Is there an active device on the relevant profile?
    Are you referring to the interaction profiles?
    image.png.dedf344e03e51d9e48061187c841e857.png
  6. As a sanity check - do these repos work for you:
    1. https://github.com/ViveDeveloperRelations/MinimalRepo/tree/wave_controller_examples - the "wave_controller_examples" branch the wave controller sample scene
    2. if on openxr:  https://github.com/hardcoded2/Updated-XR-Interaction-Toolkit-Examples/tree/openxr - does the "openxr" branch work for you? 
    3. if on wave: https://github.com/ViveDeveloperRelations/XR-Interaction-Toolkit-Examples/tree/wave_openxr_xr_origin does the branch "wave" branch work for you in the "vr" project?

 


Anyway I am not sure why InputDevices do not work, but I may be thinking at it wrongly. In my experiment I let the user use only one controller, so that s why I wanted to register to the different bits.
At the end of the day I found an hacky way to check the tracking status to assess if a controller is tracked or not and I use that to detect whether it s on or not.
Here is the code in case someone get a similar problem.

[SerializeField]
        InputActionProperty m_LeftControllerTrackingStateAction = new InputActionProperty(new InputAction("Tracking State", expectedControlType: "Integer"));
        [SerializeField]
        InputActionProperty m_RightControllerTrackingStateAction = new InputActionProperty(new InputAction("Tracking State", expectedControlType: "Integer"));

 private void Awake()
        {

            m_LeftControllerTrackingStateAction.action.performed += OnLeftControllerDetectedTracking;
            m_LeftControllerTrackingStateAction.action.canceled += OnLeftControllerDetectedTracking;
            m_LeftControllerTrackingStateAction.action.Enable();

            m_RightControllerTrackingStateAction.action.performed += OnRightControllerDetectedTracking;
            m_RightControllerTrackingStateAction.action.canceled += OnRightControllerDetectedTracking;
            m_RightControllerTrackingStateAction.action.Enable();
        }

private void OnLeftControllerDetectedTracking(InputAction.CallbackContext context)
        {
            int trackingState = context.ReadValue<int>();
            Debug.Log("Left controller tracking state is " + trackingState);
            if (trackingState > 0)
            {
                //Send event to ack that the controller is currently tracked
            }
            else if (trackingState == 0)
            {
                //Send event to ack that the controller is currently not tracked
            }
            else
            {
                Debug.LogError("Left Controller - Invalid tracking state: " + trackingState);
            }

        }

        private void OnRightControllerDetectedTracking(InputAction.CallbackContext context)
        {
            int trackingState = context.ReadValue<int>();
            Debug.Log("Right controller tracking state is " + trackingState);
            if (trackingState > 0)
            {
                //Send event to ack that the controller is currently tracked
            }
            else if (trackingState == 0)
            {
                //Send event to ack that the controller is currently not tracked
            }
            else 
            {
                Debug.LogError("Right Controller - Invalid tracking state: " + trackingState);
            }
        }




 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...