Search Unity

Bug Certain HID controllers recognised for rebind but no input in-game

Discussion in 'Input System' started by jukibom, May 10, 2021.

  1. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    A few of my users are reporting trouble getting input from Virpil flight sticks. The crazy thing is that the device is recognised and the interactive rebind is working as intended, being detected and serialised into the bindings json preferences as
    <HID::VIRPIL Controls/20210102 L-VPC Stick WarBRD>
    .

    In-game, the device sends no input. At first I thought the device wasn't being paired with the user (I have a steering wheel which exhibits the same behaviour) so I added an in-game console for logging and this potentially dangerous forceful pairing code:

    Code (CSharp):
    1.        
    2.         Console.Instance.LogMessage("** USER INPUT ENABLED **");
    3.         foreach (var inputDevice in InputSystem.devices) {
    4.             Console.Instance.LogMessage(inputDevice.name + " detected");
    5.             InputUser.PerformPairingWithDevice(inputDevice, playerInput.user);
    6.         }
    7.  
    8.         Console.Instance.LogMessage("---");
    9.         foreach (var playerInputDevice in playerInput.devices) {
    10.             Console.Instance.LogMessage(playerInputDevice.displayName + " paired");
    11.         }
    12.  
    Which, for me, does make the steering wheel work. But for my users, nothing is different while the system is reporting that the devices are correctly paired with the user:



    Other devices like an xbox controller work fine for these users. Additionally, if the bindings file simply states
    <joystick>/stick/[axis]
    then the typical axes do work but only for the most common ones like stick x and y.

    As I don't have access to this device myself, is there anything I can add to aid in debugging this? Can I bypass the path system and reference a direct device id or something? I've been fighting this one for the entire weekend and I'm absolutely at a loss.
     
  2. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
  3. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
  4. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Just tried with the more recent input 1.1.0-pre.5 and still no dice.

    User reports bindings file with

    Code (JavaScript):
    1.  
    2.     {
    3.       "action": "Ship/Pitch",
    4.       "id": "89d913f5-1c0b-4f48-ad2b-3bcf86512369",
    5.       "path": "/ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50/stick/y",
    6.       "interactions": "",
    7.       "processors": ""
    8.     },
    9.     {
    10.       "action": "Ship/Roll",
    11.       "id": "7abb1e17-bf1a-4f18-bde7-9f3833f1f333",
    12.       "path": "/ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50/stick/x",
    13.       "interactions": "",
    14.       "processors": ""
    15.     },
    16.     {
    17.       "action": "Ship/LateralH",
    18.       "id": "9e1dd72a-05e2-49c6-9f65-3ddd13ca1e69",
    19.       "path": "/ATMEL/VIRPIL/200325 LEFT VPC Stick MT-50/stick/x",
    20.       "interactions": "",
    21.       "processors": ""
    22.     },
    23.     {
    24.       "action": "Ship/LateralV",
    25.       "id": "72ef87a3-80f5-4c79-a91f-a35cb8d509a5",
    26.       "path": "/ATMEL/VIRPIL/200325 LEFT VPC Stick MT-50/stick/y",
    27.       "interactions": "",
    28.       "processors": ""
    29.     },
    30.  
    and from the Player.log,

    Code (csharp):
    1. ** USER INPUT ENABLED **
    2.  
    3. Keyboard with path </Keyboard> detected
    4.  
    5. Mouse with path </Mouse> detected
    6.  
    7. ATMEL/VIRPIL/200325 LEFT VPC Stick MT-50 with path </ATMEL/VIRPIL/200325 LEFT VPC Stick MT-50> detected
    8.  
    9. ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50 with path </ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50> detected
    10.  
    11. ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50 not paired to user! Pairing ...
    12.  
    13. ---
    14.  
    15. ATMEL/VIRPIL/200325 LEFT VPC Stick MT-50 paired
    16.  
    17. Keyboard paired
    18.  
    19. Mouse paired
    20.  
    21. ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50 paired
    The device is binding, the device is detected, the device is paired and there is still no input from either stick. I am absolutely tearing my hair out over this, so many of my users have this freaking flight stick
     
  5. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    User attempted to use just the left stick (the one that didn't need forceably binding), no difference. I'm convinced there's something about the path causing this issue. The numbers? The extra slashes? the dash? I have no idea.
     
  6. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Has anyone else seen a working controller with path bindings which include a `/` character?
     
  7. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Oof.... I could totally see a situation where the reported HID name contains a '/' in the device causing an issue with path parsing... I wonder if you could manually escape the '/' character to get around that...

    My business develops custom XR peripherals and prototypes, uses HOTAS on the regular, etc. I haven't encountered a device with that kind of HID friendly path.

    Code (csharp):
    1.  
    2.                 {
    3.                     "name": "",
    4.                     "id": "7cdd50b4-389d-4d1a-88ba-935de3127b19",
    5.                     "path": "<HID::Thustmaster Joystick - HOTAS Warthog>/stick",
    6.                     "interactions": "",
    7.                     "processors": "",
    8.                     "groups": "",
    9.                     "action": "TestStick",
    10.                     "isComposite": false,
    11.                     "isPartOfComposite": false
    12.                 }
    13.  
    (Yes I am aware Thustmaster has a missing R in it lol... good job QA team at Thrustmaster)

    The path that InputSystem uses to that is generated with:
    upload_2021-5-21_10-50-2.png


    Do the VIRPIL (sorry I don't have any here!) devices enumerate as HID or are you generating custom device descriptors for them?

    Grab a copy of USB Device Tree View if you don't already have a USB debugger w/ WSDK.
    https://www.uwe-sieber.de/usbtreeview_e.html#download

    Also feel free and ping me with a DM here or on Unity Discord (AngryArugula) - happy to help debug this ugliness because I'm sure it'll come up in my own tasks at some point!
     
  8. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Ahahah it's amazing how rough around the edges things are in HID world

    Unfortunately, I don't have access to any Virpil sticks myself to do some under-the-hood debugging, only what's reported by users. I'm not generating custom descriptors for them.

    One user's stick was detected as
    <HID::VIRPIL Controls/20210102 R-VPC Stick WarBRD>/button31
    while another was detected as
    /ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50/stick/y
    (not sure why one was <HID::[name]>) and both have slashes in the descriptor.

    That said, I dug into the input system code and found this

    Code (CSharp):
    1.             // Try to walk the name as far as we can.
    2.             var indexInComponent = startIndexInComponent;
    3.             while (indexInPath < pathLength)
    4.             {
    5.                 // Check if we've reached a terminator in the path.
    6.                 var nextCharInPath = path[indexInPath];
    7.                 if (nextCharInPath == '\\' && indexInPath + 1 < pathLength)
    8.                 {
    9.                     // Escaped character. Bypass treatment of special characters below.
    10.                     ++indexInPath;
    11.                     nextCharInPath = path[indexInPath];
    12.                 }
    13.                 else
    14.                 {
    15.                     if (nextCharInPath == '/')
    16.                         break;
    It allows for an escape character so I send a modified binding preferences file to one of the affected users with the path's renamed to
    /ATMEL\\/VIRPIL\\/200325 RIGHT VPC Stick MT-50/stick/y
    and that still didn't cut the mustard so that may be a dead end too. Or there's multiple problems at once, who knows?
     
  9. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Did a quick readover of the docs.

    VIRPIL has their own USB filter thing that is *optionally* installed if there are HID/driver conflicts.

    Code (csharp):
    1. <HID::VIRPIL Controls/20210102 R-VPC Stick WarBRD>/button31
    99% chance this is the DirectInput exposed device
    Code (csharp):
    1. /ATMEL/VIRPIL/200325 RIGHT VPC Stick MT-50/stick/y
    This on the other hand might be a virtual input device getting picked up based on VIRPIL's VPC software configuration...

    In lieu of actually having one of the devices on-hand and configured the same way... its possible to just capture every last InputEvent that references the afflicted controllers and write it out to a binary stream, then regenerate it and play it back on your side.

    https://docs.unity3d.com/Packages/c...tyEngine.InputSystem.LowLevel.InputEvent.html

    Code (csharp):
    1.  
    2. using System;
    3. using UnityEngine;
    4. using UnityEngine.InputSystem;
    5. using UnityEngine.InputSystem.LowLevel;
    6. using UnityEngine.InputSystem.Utilities;
    7. using Unity.Collections.LowLevel.Unsafe;
    8. public class InputLogging : MonoBehaviour
    9. {
    10.     private void OnEnable()
    11.     {
    12.         InputSystem.onEvent += OnEvent;
    13.     }
    14.     private void OnDisable()
    15.     {
    16.         InputSystem.onEvent -= OnEvent;
    17.     }
    18.     private void OnEvent(InputEventPtr ptr, InputDevice device)
    19.     {
    20.        
    21.         if(device.name == "Some Silly VIRPIL/Arduino/Path/393510")
    22.         {
    23.             //the important parts used to regenerate exact input events
    24.             FourCC type = ptr.type;
    25.             byte[] data = CopyEventData(ptr);
    26.         }
    27.     }
    28.     unsafe byte[] CopyEventData(InputEventPtr eventPtr)
    29.     {
    30.         var sizeInBytes = eventPtr.sizeInBytes;
    31.         var buffer = new byte[sizeInBytes];
    32.         fixed (byte* bufferPtr = buffer)
    33.         {
    34.             UnsafeUtility.MemCpy((void*)new IntPtr(bufferPtr), eventPtr.data, sizeInBytes);
    35.         }
    36.         return buffer;
    37.     }
    38. }
    39.  
     
    Last edited: May 24, 2021
  10. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Damn, impressive! I feel I really need to get hold of one of these devices if I'm ever going to get something like that to work.

    I had no idea about the filter thing, could you link me to that?
     
  11. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    VPC software from VIRPIL is free to download and setup; but I noticed that the VPC Installer had a checkbox for USB Device Filter which registered some misc virtual USB crap when I clicked it.

    Other than that the docs are pretty sparse. It would make sense for them to have a input-aggregating thing though as they make a huge pile of peripherals with so many different firmwares heh.
     
  12. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Okay so it turns out it IS the `/` in the descriptor and this issue will be resolved by a Virpil software update:



    However, this is still a pretty nasty bug that Unity is not escaping the descriptor in case this happens for other generic devices.
     
  13. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Yep I buy it.

    I don't think its a bug though, I think VIRPIL are the only people on earth using a common path delimiting character as part of their Hardware unique HID identifier. Congrats on sorting them out! :)
     
    jukibom likes this.
  14. Good job seeing this through with them!

    If you think this can be a more generic problem, you should still submit a bug, Unity at least can consider a defense against such a thing. The worst scenario is that they close the bug without doing anything.
     
    jukibom likes this.
  15. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Yep, I already filed a bug so I'll make sure to update it with the new information :)
     
    Lurking-Ninja likes this.
  16. robinlloydmiller

    robinlloydmiller

    Joined:
    Oct 24, 2019
    Posts:
    9
    I absolutely ran into this problem too- generic Teensy joysticks are named "Keyboard/Mouse/Joystick"- and It took me waaaay longer to notice this than you so kudos! I'm +1 to it feeling buggy- in my case I had to modify the USB descriptor to use letters there, and that was a major PITA-
     
  17. jukibom

    jukibom

    Joined:
    Aug 31, 2015
    Posts:
    54
    Interesting! For future reference, how did you actually modify the descriptor? (Or was this done outside the application?)
     
  18. Fenrisul

    Fenrisul

    Joined:
    Jan 2, 2010
    Posts:
    618
    Depending on what an API is reading, a lot of USB information can actually be changed inside the Windows registry *after* the device's driver has been installed. Often you can actually tag additional information like "Friendly Name" that wasn't there at all and that'll get picked up preferentially over the USB HID descriptor.
     
    jukibom likes this.
  19. robinlloydmiller

    robinlloydmiller

    Joined:
    Oct 24, 2019
    Posts:
    9
    It unfortunately wasn't application side- I did try as @Fenrisul suggested and modified registry values, but it's a total PITA and wasn't consistent enough. I was writing the values for a custom TEENSY micro, and I just modified the HID information for it when i was flashing it.

    In general, I'm not terribly knowledgeable about what it was i was doing- It was mostly rabbit holes of information- but generally threads like these: https://forum.pjrc.com/threads/23523-Change-device-name allowed me to eventually modify the correct files to allow me to add my own device info.
     
    jukibom likes this.
  20. HongCruise

    HongCruise

    Joined:
    Dec 14, 2020
    Posts:
    8
    Wow, everyone who replied to this post is my hero. I actually did post an issue on this a good 9 months or so ago and no one replied. I do own two Virbil joysticks as well as the Virgil rudder controls and I tried everything I could to get inputs to register but no go. Clearly smarter people have been able to figure out the problem, jukibom, thanks for letting the Virbil people know. If I remember right their rudder periferal input doesn't even show in unity but I doubt you have any need for that.
     
    jukibom likes this.
  21. Maverick87Shaka

    Maverick87Shaka

    Joined:
    Aug 4, 2017
    Posts:
    3
    Give crazy name to stuff it looks like a common practice for top tier joystick manufacturer:
    <HID::VKB-Sim © Alex Oz 2021 VKBsim Gladiator >/button3
    Is what I'm trying to making works on Quest 3 standalone, and of course it fails.