Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Generic persistent input device id

Discussion in 'Input System' started by DanT6, Dec 21, 2018.

  1. DanT6

    DanT6

    Joined:
    Sep 12, 2018
    Posts:
    1
    Hello, is there a way to retrieve some kind of persistent id of the device, which will remain the same after removal/addition of the device, and is preferably generic regardless of the platform? So far I've only been able to find such id for xbox gamepad (gamepadId), but I can't find anything similar for devices on other platforms.
    I basically need to be able to tell if this device has previously been added to the system, before it has been removed and re-added. And I also need a way to identify it (id).
    Neither controller id (device index) nor device id do not satisfy my needs.
     
  2. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Short answer: I wish there was but there isn't. But there should be some more helpful APIs eventually to at least get a mostly-good-enough-in-practice kind of persistent identification of devices even if it's kind smoke and mirrors.

    Long answer: It's something that should be simple but is surprisingly hard in practice. If you're lucky, the device has a serial which you can get via "InputDevice.description.serial". In this case, you have a fairly reliable means of identifying the device. There's still a chance that the serial is actually some made up nonsense coming from a driver and not from the device but usually, it's trustworthy.

    If the device doesn't have a serial, however, it's mostly down to guesswork based on whether it's similar enough to the data you've retained (product name, manufacturer name, interface info). Even at the OS level, there's no way of telling whether that identical looking USB controller which was just sitting on port 1 but is now sitting on port 2 is actually the same device or not.

    The data to retain sits on InputDeviceDescription. One thing that I think we're still missing there, though, is something like "port ID" in InputDeviceDescription, i.e. a means of identifying the "port" (whatever that means to the actual connection mechanism; USB, Bluetooth, whatever) on which a device is connected. Some interfaces (like XInput) have the data as part of the "capabilities" field but it should be available directly from InputDeviceDescription regardless of the specific interface used by the device.

    Eventually, having something like a "persistentId" property is probably a good idea. Or some other means of determining how close a match you have to something you've seen before. Even though it will come with gotchas and won't work reliably in all cases.
     
  3. Team6Developers

    Team6Developers

    Joined:
    Nov 19, 2018
    Posts:
    12
    Its particularly tricky for Xbox because there's a hard link between the controller and which user is logged in. It should get confirmed if the deviceId is reliable to use in all cases where the controller remains connected. For instance does the deviceId remain the same when suspending the game for a while and coming back later.

    When disconnecting and reconnecting a controller it would be possible to present the user with a dialog, when dismissing this dialog you could get the used controller and map that to the user. (Not sure if this is compliant with Microsoft's technical requirements for Xbox).
     
  4. Kolyasisan

    Kolyasisan

    Joined:
    Feb 2, 2015
    Posts:
    397
    Is there any update on this? Having info about with which port id the device is connected would be super-useful in my specific case.
     
  5. Jen42

    Jen42

    Joined:
    Sep 20, 2017
    Posts:
    4
    We are using the Unity-DirectInput plugin which is successfully getting the serial numbers of the devices out the natives, but Unity's InputSystem is not. eg the ps4 controller gets its device.description.serial set to 'Wireless Controller' by Unity but the direct input plugin gets a persistant serial number between plays out of the Native. I want that serial number set correctly in Unity's input system for comparision so I can disable Unity's Gamepad and just use my DirectInputDevice so they don't argue.
    Is this a bug in Unity? It must be possible to get it if the direct input plug in can get it? Currently I'm having to rely on the order of lists, which is super dangerous.
     
  6. MrRutabaga

    MrRutabaga

    Joined:
    Feb 5, 2018
    Posts:
    1
    Hello !
    I'm currently trying to create a new Input Device class for joycons.
    It's related to the issue above, but is not exactly the same.

    So basically,
    Unity detects the joycon as a HID and I have a class to make it an InputDevice. Everything works properly and the description of my devices looks like this :

    Code (json):
    1. "interface": "HID",
    2.     "type": "",
    3.     "product": "xxxxxxxxxxxxxxxx",
    4.     "serial": "xxxxxxxxxx",
    5.     "version": "0",
    6.     "manufacturer": "xxxxxxx",
    7.     "capabilities": "{\"vendorId\":xxxx,\"productId\":xxxx,\"usage\":x,\"usagePage\":x,\"inputReportSize\":xxx,\"outputReportSize\":xx,\"featureReportSize\":x}
    The thing is sometimes, the "capabilities" value of the description will get a new entry (for already connected joycons) called "elements" filled with a lot of data (which I don't know what it is). It looks like this :

    Code (json):
    1. "capabilities": "{\"vendorId\":xxxx,\"productId\":xxxx,\"usage\":x,\"usagePage\":x,\"inputReportSize\":xxx,\"outputReportSize\":xx,\"featureReportSize\":x,\"elements\":[{\"usage\":1,\"usagePage\":9,\"unit\":0,\"unitExponent\":0,\"logicalMin\":0,\"logicalMax\":0,\"physicalMin\":0,\"physicalMax\":0,\"collectionIndex\":0,\"reportType\":1,\"reportId\":63,\"reportCount\":1,\"reportSizeInBits\":1,\"reportOffsetInBits\":8,\"flags\":2},{\"usage\":2,\"usagePage\":9,\"unit\":0,\"unitExponent\":0,\"logicalMin\":0,\"logicalMax\":0,\"physicalMin\":0,\"physicalMax\":0,\"collectionInd
    2. ...
    3. // It goes like this for like 300000 characters
    The issue with this is that the Unity InputManager checks the equality of the description between disconnected devices and newly connected devices to know if the newly connected joycon is the same device as before (and therefore attributing it to the same player). Here :

    InputManager (InputSysem 1.5.1) line 2311
    Code (CSharp):
    1. private InputDevice TryMatchDisconnectedDevice(string deviceDescriptor)
    2. {
    3. ...
    4. if (!InputDeviceDescription.ComparePropertyToDeviceDescriptor("capabilities", description.capabilities, deviceDescriptor))
    5.     continue;
    6. ...
    7. }
    When (sometimes, I don't really understand how it happens) this "elements" value is in the description, this match doesn't work and the reconnection of my joycon is defined as an Added InputDevice.

    Is it a bug from Unity ?
    I wanted to modify the "capabilities" entry in the description when the joycon disconnects, to remove manually the "elements" part but it is not open to modifications.
    I also tried to remove the current device and add a new one to recreate the description this way but I don't manage to make it work.

    Do you have any clue on how I could make this work ? Should I report a ticket ?