Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Iterate over all Input Devices?

Discussion in 'Input System' started by Holonet, Aug 2, 2018.

  1. Holonet

    Holonet

    Joined:
    Aug 14, 2017
    Posts:
    84
    First, a thanks to Rene-Damm for the dogged attention to this forum :).

    Anyhoo, this isn't anything critical to me at the moment, but I thought it might be worth a mention.

    Is there any way (or planned way) to iterate all the input devices that are connected? i.e. InputDevice.all instead of just Gamepad.all? It occurred to me when testing a few. I have this amusing Retrolink N64 USB controller that I plugged in, just to have a 2nd controller and test multi-controller functionality...and minor snag was it was picked up as a joystick instead of a gamepad.

    Pshaw, I just grabbed a different gamepad, my game is not planning to mix those breeds! However, I thought it might be a useful ability...to iterate without discriminating the type of device, then use desired logic...for cases like this, where you'd want to "weed out" a type of controller that the player might have plugged in, but you don't want to include in the controller lineup for your game... Some joker has his wheel/pedals/flight chair plugged in, and he/she just wants to sit down for some Wing Commander, etc... :)

    Another thing that comes to mind from my example...maybe easily change the classification of a "joystick" to a "gamepad," but I'm guessing that's in the API with layouts and such, which I haven't dug into much yet. The case I'm thinking of though, is a PC game where the controller used doesn't really matter, if we have a way to just "assume" it's a gamepad (thinking unrecognized devices here), then give the players a way to customize their controls, then we can handle those inputs in a similarly structured way, and the players can use whatever garbage they have with a USB plug and have their LAN party hehe...
     
    Last edited: Aug 2, 2018
  2. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    InputSystem.devices gives you a ReadOnlyArray<InputDevice> containing all currently connected devices. It doesn't allocate (gives read-only access directly to the system's internal array of devices) so you can safely call this whenever you want.

    Our handling of devices we don't specifically support still needs a good deal of improvement. Surprised it came out as a joystick, though. Could you snap me a picture of what the input debugger window for the device (double-click device in input debugger's list) looks like? If it's a HID, maybe also a picture of the HID descriptor window (there's a button "HID Descriptor" in the device's debugger window)?

    Unfortunately, that's a bit of a tricky thing. The layouts describe two things: a hierarchy of input controls (such "this device has a 'leftStick' control and underneath has a 'y' control) but also a memory layout wired to those controls (such as that 'y' control being bit #4 at byte offset 2). The data for the device is coming into the system in some externally decided memory format. For example, if it's a random HID, it's the device itself or the driver that sends us HID input reports in a custom format.

    So changing from a gamepad layout to a joystick layout unfortunately does involve some tricky questions.

    I'm thinking that we will have to have something of the sorts. If not for 1.0, then after. It'd likely be an API mainly enabling the use case of walking the user through a setup to identify each control and generating a layout at the end. Besides that, the HID code also needs lots of tweaking and improvement to improve the layouts it can come up with automatically.
     
    Last edited: Aug 2, 2018
  3. Holonet

    Holonet

    Joined:
    Aug 14, 2017
    Posts:
    84
    Sure thing. It is, indeed, an HID. I took a snip of the top and bottom of the HID descriptor. Elements 0 - 11 all show as Buttons...which is curious because I'm only counting 10 buttons, the dpad & stick lol.

    The bottom element, I noticed is showing up as a HatSwitch, so I'm guessing it sees the N64 stick as the joystick and the dpad as a hat?

    Worth noting, the control stick registers as the X & Y axis in the debugger, but the dpad does not seem to register when I operate it. The Rz & Z axis don't respond to any input, nor do button 11 & 12 (which kinda jives with what I mentioned above). I'm reaching wayyyy outside of knowing wth I'm talking about here :p...but maybe...the dpad, which isn't actually an axis, but discrete inputs...is showing up as the hat, which is treated like an axis but then the discrete inputs don't show up because it's not an axis and....[head explodes].

    For the record, it's noisy and puking out stuff while not pressing anything, but I assume that's a far-away concern at the current stage :).

    Anyway!... InputDebugger.PNG HID_01.PNG HID_02.PNG


    Let me know if there's anything more I can do to assist!
     
  4. Holonet

    Holonet

    Joined:
    Aug 14, 2017
    Posts:
    84
    Just gonna add this in, in case it helps you diagnose. I have a Super Nintendo Retrolink USB gamepad as well, and I just stuck that in there to see the results. It is correctly identified as a gamepad, though curious--the up & down on the dpad register with the y axis, but the left & right on the dpad register on 4 x axes, all seemingly doing the same thing...so somehow the usage for all of those is the X axis, I guess.

    snes1.png

    The last element says undefined as well:

    snes16.PNG

    Not sure if this stuff warrants a different thread...like where people can post this information about non-supported gamepads, etc... Anyhoo, again, just holla if I can be of further service.
     
  5. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Thanks for the detailed screenshots. Very helpful.

    HID has two ways of doing dpads. They can be done as bitfields (in which case they show up as four individual controls) or as hat switches (in which case it's a single control). Looking at the hat switch in the screen shot you posted, it should come out as a working dpad with the latest version of the develop branch. We've recently added support for HID hat switches.

    Yeah, button 11 and 12 not working seems expected. Unfortunately, HID is pretty poor in expressing what stuff means and where it comes from. Even once our generic HID code will do as good a job as it can, it will always remain a best-effort kind of thing that will only be able to do so much in making sense of a device.

    X, Y, Rz and Z not working sounds like a bug. I'll order one of the devices and have a look. This is the device, right?

    That's expected, although we can probably improve on this by suppressing input reports that indeed contain no state changes. Overall, though, the events simply represent the input reporting of the device 1:1 and many HIDs simply sample at a constant rate.

    Unfortunately, we'll always be faced with limits here. Due to how HID works, the generic HID code won't be able by itself to set up a correct gamepad even in the majority of cases. How axes and buttons are assigned is pretty much completely up to the manufacturer.

    We'll keep refining the generic HID fallback and it'll give better results than it does today but overall, the only "proper" and solid way is to have device layouts registered for specific devices. The fallback will always be hit and miss.
     
  6. Holonet

    Holonet

    Joined:
    Aug 14, 2017
    Posts:
    84
    Yup, that's the device (your link). So I tried this again last night after updating to the latest package, and indeed, I do see the hat now, and it responds:

    n64_2.PNG

    Before you order one up though (unless you just want to add it to handled stuff) for debugging, let me be clear on the axes thing. X & Y do work, but rz/Z do not. However, I'm not sure it's Unity's fault. Just to make sure I didn't have something broken, I brought up the Windows interface (Windows 10 x64):

    windows_n64.PNG

    So the X Axis / Y Axis is the control stick. The Point of View Hat is the dpad, and that Z Axis / Z Rotation... I'm not sure what it would be. Everything besides the stick/dpad is just a regular button, nothing I press registers with that Z axis. Also, you'll see, there is a button 11 and 12 here as well, but there are not that many buttons on the controller.

    So bottom line, with the addition of the HAT support, I'm seeing the same response in Unity as the Windows interface. Maybe that all comes from "HID," I'm just not familiar with all that noise :).

    Might the manufacturer have cheaped out and used a generic joystick board of some kind, which registers all of that, and then used whatever they needed for different style controllers? That would explain the phantom buttons.

    The remaining issue is the fact that it's picked up as a joystick (but again, so does Windows). If that's just what the manufacturer ordered...*shrug*. Welp, I'm all for using these wonky knock-offs for edge cases... :cool:
     
  7. Rene-Damm

    Rene-Damm

    Joined:
    Sep 15, 2012
    Posts:
    1,779
    Ah, I see. Ok good, sounds like everything is in order then.

    Yup thinking the same. Looking at the device, seems like it's coming from a generic driver that doesn't really understand the particular device.

    There's chances this won't change. The problem is that the HID code has no way of knowing what's what on the device. The HID spec simply is too vague to rig up a proper gamepad just from the HID descriptor alone.

    So the code *could* go and put together a Gamepad layout based on some educated guesses. And maybe that's the best thing to do in the end. It will be hit and miss. Half the time those gamepads will simply not be mapped correctly. Sticks and triggers may be jumbled, buttons may be in the wrong place.

    Ah and now I realize I'm basically repeating myself :D

    ////EDIT: Just to add that, it's not super tricky to rig up a custom device layout if you have a specific device that you want to work with. Here's an example that can be followed. It rigs up the Xbox controller as a HID on OSX. Admittedly, with the JSON embedded as a C# string, does look a little scary.