I’ll continue from my previous report on Jan 16 2020 where I struggled to rebind my Thrustmaster TX wheel:
This is still an issue, especially for the rebinding. I recorded small clip to showcase the issue:
On this clip, I simply click on any rebindable input with a mouse and it always assigns same wheel pedal axis to it and scrolls down the list. Why this happens is pretty obvious just by looking at the input debugger:
the highlighted parts are my steering wheel pedals, brake pedal gets set to “Stick Y” which here gets -1 value when pedal not pressed, which in turn drives the “stick down” that moves the menu. To prevent it from scrolling down I’d have to hold the pedal pressed to half way as the pedal axis have range of 1…-1.
This is just one wheel that has this issue but there are countless others that have axis setup like this, rendering whole rebinding impossible to use as is. So basically there are few separate issues present here:
UI moves by stick on devices where it clearly can’t work (even this device has hat switches like seen on above image and UI navigation should use it instead)
rebinding just polls nonzero values regardless if they are active. In my case I immediately always just get bind for “rz” no matter what I do.
binding doesn’t normalize the flipped axis inputs (this could be just a checkbox on the rebinding UI I guess)
binding should detect actual change, not current values
As additional note, I have no clue why Unity detects the Y-axis as -1 on this device when pedal is not pressed. It should start from 1 like the rest of the pedals (they are all inverted and go from 1 to -1 when fully pressed down).
I also tried this with the Rebinging UI sample by allowing the gamepad side of the sample to be binded by joystick. Runtime rebinding worked just fine for Vector2 and Buttons but as soon as I changed the Control Type to Axis, it just immediately binds rz on my device. Same thing happens on editor side rebinding with Listen-option but there I can at least select the option I really need.
With Listen it lists these four entries on my device immediately after I hit listen:
HatSwitch/X, HatSwitch/Y, Rz and Slider. It doesn’t list Stick/Y for some reason until I actually press the brake pedal despite the value defaulting to nonzero value of -1 so it’s kinda hard to see logic behind this. Seems like there are some magic rules set behind the curtain.
Yeah, unfortunately the HID fallback still leaves things to be desired. ATM it does a worse job than the generic HID code for the old input system. And unfortunately, the rebinding code is rather susceptible to devices that aren’t set up properly so it easily ends up picking up “input” from HIDs that isn’t there but rather comes down to bad layouts generated by the HID fallback. Which is even more unfortunate as rebinding is especially useful for HIDs that aren’t specifically supported.
Working the kinks out of the HID fallback is on the list. Due to the nature of HID, there will always be controls the fallback won’t be able to figure out correctly but it can definitely do a much better job than it does now. And for the rest, hopefully we can tweak the rebinding code to be able to more smartly filter some stuff out automatically.
Unfortunately, the problem here is mainly with the HID code.
You are probably right on this. I now got custom device setup for DirectInput and it doesn’t give immediate bind at rebinding even if the values are set to 1 for some axis out of the box (I just ignore the HID now by setting others than Joystick option on control scheme). In other words binding does work as expected on my custom device.
I can use custom device approach (I need DirectInput for FFB anyway) as workaround for the time being as I don’t really need to support HID devices that aren’t supported via DI anyway but I’d love to have the HID support as last fail-safe option so hoping the immediate binding issue at least would get resolved some day
One additional weird thing I noticed though with the custom device setup was that for some reason all runtime binds now get the product name of the first custom device of the same type regardless which connected device I use (when testing this with RebindingUISample and using “Don’t Omit Device” option). For example my first custom device is Logitech G25 and second is Thrustmaster TX, both using same DirectInput custom device I’ve made. If I have both of these enabled, runtime bind always reports the device as G25 regardless which device I use to bind it.
EDIT: remembered your older reply regarding this. I had to put this to rebinding script to stop it from generalizing the bind:
rebind.WithoutGeneralizingPathOfSelectedControl();
With this in place, it binds properly per device but I still feel it’s bit weird it just tries to guess the device name without this option - instead of just showing generic custom device name - which would be DirectInputController in this case.
As another note I’ve now removed the stick and trigger mappings like this for now (neither of these should exist on generic input device IMO as they only confuse users with say, wheel controllers):
I could fix rest of the binding UI navigation issues by omitting Joystick controls from the UI control scheme and adding my own DirectInput custom devices D-Pad input there.
There is still also one other rebinding issue with HID input… often if I just wait long enough, I still get bind for wheel’s X axis regardless of me not touching the wheel. It feels like there should be some bigger threshold for binding.
Additionally, I wonder if I could remove HID devices that my custom device implements? Could detect them by vid & pid etc. This way I could only use HID as last fallback option. EDIT: I guess I could just use DisableDevice for the HID versions.
EDIT2: DisableDevice didn’t disable binding! Why would the binding work on disabled device? RemoveDevice did do the trick though.
I’m exactly in the same situation of Olento - and again, I’m trying to rebind some pedals and wheels.
How did you solve this without altering the source packages? Are there any workarounds over 1 year later?
@rz_0lento could you post a snippet on how to remap an axis? I’m trying to make it work on different console SDKs, and every SDK has a separate package for the Input System.
Is there any workaround? I’d love to support as many wheels as possible by letting them rebind the axes - that operate often different in different ways (1 depressed - 0 pressed, -1 depressed 1 pressed, or inverted).
I can’t create a map for every possible existing wheel, past present or future so (I was already doing that) pedal rebinding is really tricky.
My workaround was to disable Input System’s HID support beyond what they used it for playstation controllers. It was just too bugged with wheels and it didn’t seem to get big prio from Unity’s side.
My main concern with the built-in HID support is that every second DirectInput device I plug in has SOME issue on this input system’s HID module that isn’t related to previous devices issues, while I could work around the issues per device, knowing how many different wheels we have out there + other DI devices, it’s practically impossible to work with this Input Systems current HID logic and have something that works for majority of the devices (talking about steering wheels now).
What I did instead was that I modified input system a bit also to take my own DirectInput wrapper in as a custom device. Custom devices itself don’t need source modification for Input System but there were bunch of “by design” issues that prevented it from working nicely without. With extra changes I finally got it to function like I wanted but it wasn’t all straight forward, took me about month to figure all that stuff out which in hindsight wasn’t really worth the time spent on this. What I’ve done for that part is proprietary code now so it’s not something I can publicly share here, sorry
As for the axis remapping, you can do that on input processors but it doesn’t solve your rebinding issue: remember that if you remap the axis to work the other way around, there will always be another device that wants it in opposite so it will then be wrong for that one. As example Logitech and Thrustmaster wheels have pedals axis mapped in different direction.
If you are fine by just supporting the most popular wheels, I’m fairly certain you could just invert the axis based on the wheel manufacturer as at least every Logitech wheel I have tried have had it mapped the same way but you’d need some robust way in detecting the manufacturer too. You get this from HID info to some extent (can’t remember if Input System exposed this proper) but it’s good to remember that same manufacturer may also have multiple ID’s from different era devices.
That gave me a better insight of the issue. Basically - there’s no out of the box solution.
I’m wondering if I could just poll the device (problem 1: which one), and read some values from it for maybe, 1 second?
And then filter that list, purge it a bit until only 1 is left.
Pretty much in the same way the “Listen” button in the input bindings window works - I wished we had a similar function out of the box.
Lastly, shrink it to a single path, and do a manual rebinding of the old input with the new path (I don’t know if it’s possible to do manual A to B override at the moment - I really hope there’s an overload for that - or it’s going to be a problem).