Why are all my gamepads shown as XInput devices?

Hey, so I’m working on some button prompts in my game and want to show different icons depending on what gamepad the user is using.

I’ve tried the following:

  • InputDevice device name, device description, manufacturer
  • Gamepad.current is DualSenseGamepadHID || Gamepad.current is DualShock4GamepadHID
  • Input.GetJoystickNames();

When playing in editor this works as expected, but after building all my gamepads are XInput devices with no other information…

Can someone explain why this happens, and how I could approach detecting a specific gamepad? Thanks!

Hi @JordyBan, thanks for reaching out.

InputDevice name, device description manufacturer as well as checking whether a device instance is of a certain device type as suggested are viable approaches to get you what you need. All of this these mentioned seem to reference the Input System.

However I am confused regarding Input.GetJoystickNames() since that references Input Manager functionality (surfaced via Unity.Input namespace). Are you using Input System or Input Manager?

The device names and manufacturer information that Input System surfaces typically comes from what is reported by the underlying OS driver or API being used. With a standard setup on desktop DualSense or DualShock gamepads should be routed via HID interface if not building for that console platform with a console build. However, in your case it sounds like you are experiencing that likely another backend is used in the built player causing this problem.

Some questions that could make it easier to help you out:

  1. What target platform are you on (editor) and what target platform are you targeting when building?
  2. Would you mind posting a screenshot of the Input Debugger when the device is connected similar to the one I have posted in this thread?
  3. What model of the DualSense/DualShock do you have? It’s written on the back of it, e.g. IC-409B-CFIZCT1.

Here is a screenshot of how a DualSense connected via Bluetooth on my macOS machine looks like in the Input Debugger. I understand your issue though is within a built player and not in editor, right?

Is this similar to what you see in editor? And in player you get something different suggesting the device is routed via an Xbox compatible driver or API?

I tested this with a DualSense CFIZCT1 on Windows as well in editor and in player using the following script:

using UnityEngine;
using UnityEngine.InputSystem;

public class TestScript : MonoBehaviour
{
    private void OnGUI()
    {
        var gamepad = Gamepad.current;
        string str;
        if (gamepad != null) {
            str = $"Gamepad.current: {Gamepad.current}, type: {Gamepad.current.GetType()}, vendor: {Gamepad.current.description.manufacturer}, product: {Gamepad.current.description.product}, interface: {Gamepad.current.description.interfaceName}";
        }
        else
        {
            str = "No gamepad connected";
        }
        GUI.TextArea(new Rect(100,100, 500,500), str);
    }
}

And it reported the following in editor and built player on Win 10:


If this gives other results when tested with your gamepad it would be valuable to know what you get instead, it might be that there is a FW update or another DualSense model we haven’t accounted for which could lead to Windows Gaming Input backend (native) picks the controller up instead of routing it as a generic HID device.

Hey, thank you for taking some time to help us.

  • We are using the input system. We quickly tried using input.GetJoystickNames() as an experiment.
  • We are using unity 2022.3.49 on Windows and our target platform is Windows.
  • Input debugger:

  • DualSense model: IC-409B-CFIZCT1A

This all seems alright. I did find out something curious when testing the small script.

in editor it shows correctly:

When testing in build, the following is shown:

The controller is always shown as XInput, but the reason this could be is because the build is launched with the Steam client.

I tested a build not launched from the Steam client and it works as you would expect. So I assume the issue is not related to Unity, but as you said another backend (Steam) is using the input. I still don’t understand it completely and don’t really know how to fix it, but the Unity part seems fine.

Again, thank you for putting us on the right track here, hopefully we’ll figure out how to fix it :slight_smile:

That is an interesting find indeed. Sounds like we should test this scenario, it might be that Steam is using some filter drivers or similar to redefine how the device is being detected by OS. Unity only enumerates HID devices as well as Xbox compatible gamepads in this case as reported by Windows HID APIs as well as Windows Gaming Input. If there are additional findings it would be very valuable to share them in this thread so we can provide a better experience.

May I ask if you are also using some custom gamepad adapter drivers or tools in addition to this or some non-default HID drivers outside of Steam? Did you notice whether just running Steam in the background was sufficient or was it only when launched through Steam?

Hey, thanks again.

So we’ve had some time to take another look at this. We did a few things:

  1. Steamworks Configuration: We made sure that Steam Input is not enabled for the affected gamepads in Steamworks.

  2. Steam Setting: In the Steam Controller settings for the game, setting it to “Use Default Settings” allows the game to detect the gamepad and display the appropriate button prompts.

These changes have worked for us, but it depends on the user’s Steam Controller setting. If the settings are not set to “Use Default Settings,” the gamepads may still register as empty…

Through Steam Input you are presented with a virtualized controller that intentionally doesn’t identify itself. You can also only default opt-out of Steam Input, users can always opt-in and Steam doesn’t provide a way to completely disable Steam Input for your game.

Since users can freely remap inputs, knowing the gamepad type only gets you halfway, you still need to figure out what a virtual input actually maps to on the original device.

The only way to do this is to use Steam’s API. The Steam Input Gamepad Emulation - Best Practices goes into detail on how to detect the controller used and map inputs to their origin.

Unfortunately, I don’t think it’s possible to get the required XInput slot index for an InputDevice, which would be required to match the devices reported by Unity and the Steam Input API. You could try to use some heuristic but that’s possible to break at some point.

You’d need to also take the input data from the Steam API for things to match properly. Unity has done some work on a Steam Input Plugin that does that but it hasn’t really been updated in years and I think isn’t officially supported.

What I’ve done, because using the Steam API for everything would have been too much work, is to default opt-out all controllers and assume an Xbox controller for unidentifiable controllers. This should at least give players a good default experience. You could add an option to override the gamepad type inside the game but that’s again only a partial solution, since it doesn’t cover remapped inputs.

I’d really wish Unity invest more time to expand the Input System device support. Work has been mostly on fixing things, improving the editor experience and the API. Device support has mostly stagnated since the early days, things like advanced gamepad features and haptics have been missing for years. This also includes built-in support for Steam Input.