MrTimcakes / Unity-DirectInput

Unity Native Plugin to expose DirectX DirectInput ForceFeedback
GNU Lesser General Public License v3.0
31 stars 11 forks source link

Unable to rebind to any controls belonging to Virtual Devices #6

Open AugGust opened 1 year ago

AugGust commented 1 year ago

Tested with InputSystem 1.3.0 and and 1.4.3, DirectInput devices show up in the Input Debugger, and the values of their controls do change properly. However, InputAction.PerformInteractiveRebinding() does not detect any of these virtual devices.

Regular devices that are detected natively through the InputSystem do function properly.

Is there a special way to perform rebinding on them?

Thanks!

AugGust commented 1 year ago

Just wrote a tiny test script to verify, but it indeed does with with PerformInteractiveRebinding. It was something else to do with the way the other InputAction was set up.

MrTimcakes commented 1 year ago

Good to hear you've solved it, I hadn't tried interactive rebinding.

AugGust commented 1 year ago

Sorry to reopen the issue, but it seems that the problem is not completely solved.

There indeed seems to be an issue/bug with PerformInteractiveRebinding when using control schemes belonging to a InputActionAsset.

This is my test scenario

Test device is a USB Handbrake, with a single axis. The default unity input system considers it Unsupported, but DirectInput works with it! image

If I create an InputAction directly in a script and try to PerformInteractiveRebinding on it, it detects the handbrake axis movement no problem

public InputAction inputAction;

//Works just fine!
void RebindInput()
{
    inputAction.PerformInteractiveRebinding().Start();
}

However if the InputAction belongs to a ControlScheme in a InputActionAsset, the rebinding operation will not be able to find the device, and it also does not show up as a list of candidates.

It is possible to workaround this problem by adding the [DirectInput Device] as a type of device in the control scheme image image Now, the rebinding operation is able to detect the handbrake.

Now, this is where I think is a potential bug With this set up, it is only possible to detect the Handbrake, but no other DirectInput device! It seems that adding DirectInputDevice to the control scheme should have handled this, but it does not.

Further investigation revealed that when viewing the InputActionAsset file as text, it shows that the devicePath was added explicitly as <DI_Handbrake>, hence preventing detection of any other kind of DI device image

Could this be a potential bug, and the device path for virtual DI devices should all fall under the same umbrella instead, such as <DirectInputDevice> instead of specific device names?

Thanks for your help!

AugGust commented 1 year ago

Possible Solution

I've done a workaround to deal with this, posting as reference for anyone else that might be stuck

Modify GenerateISLayouts() in VirualInputSystemDevice to register a single layout instead of per device layouts

This will cause all DirectInputDevices the share the same layout, so you can now add this layout as a type of device to your desired control scheme. However, now each DirectInputDevice will be named "DirectInputDevice", "DirectInputDevice1", "DirectInputDevice2" etc, and their naming is now dependent on the order of their connection. Meaning, you can't get a guaranteed device name anymore, it might change the next time you reconnect the device, especially if you have to use multiple at one time. This breaks compatibility with override bindings, as they rely on the device names.

To fix this, I've made a translation layer between device names and their serial (InputDevice.description.serial). Upon saving, it converts the deviceName in the override paths to serial, and vice versa on loading. Hope this helps anyone who meets the same issue!