Two identical joysticks?

How can I create bindings in the Action Maps to a button or axis on ONE of two identical joysticks?

I have two Thrustmaster 16000M joysticks attached to my PC, and the unity input debugger shows these as two different devices (one has a ‘1’ appended to its name), yet when I try to bind, I only get Specific Devices->Joysticks->Thrustmaster 16000M. A binding to that is triggered by both sticks. If I use the learn function, unity does not see a difference between the sticks. However, in the InputAction.CallbackContext I can see that the device name is different, depending on which one I use. I would really like to solve this in the action mapping and not in the actual handler…

Guys I could really do with some tips on what to do here. Is this a use case which you’ve simply not considered yet? Is there some way to handle this that I haven’t discovered?

I thought there were docs somewhere, at some point. But I can’t seem to find them.

First, you need to create an instance of your InputActionAssetReference. Then you need to call ApplyBindingOverridesOnMatchingControls(InputDevice) on the InputActionMap you want to use.

Please excuse my crude example; I have a PlayerManager MonoBehaviour with the following code:

// Reference to your Input Action asset.
[SerializeField]
InputControls inputControls;
...

void Awake()
{
    ...
    // Loop through your players
    for (var i = 0; i < players.Length; ++i)
    {
        var player = player[i];
       
        // Create a clone of your input asset
        var controls = new InputControls(Instantiate(inputControls.asset));
        // Bind your actions to your input device.
        controls.ActionMap.Get().ApplyBindingOverridesOnMatchingControls(player.InputDevice);
        // Set your callbacks to your handler (I use this class)
        controls.ActionMap.SetCallbacks(this);
    }
    ...
}

Hope that points you in the right direction.

There are some helper methods, if you have a game object per player. For example…

// Helper method to clone the Input Action asset.
gameControls.MakePrivateCopyOfActions();
gameControls.ActionMap.Get().ApplyBindingOverridesOnMatchingControls(player.InputDevice);
gameControls.ActionMap.SetCallbacks(this);

I also believe they’re implementing some User/Player management classes, as per UserManagement Docs, However, they don’t appear to be ready in the latest release (0.2.0-preview).

Good luck!

Sorry to leave you hanging there @Innovine .

The kind of setup that @Heimlink describes is one way to go about it, though there’s been a few additions since to make it easier. Overall, the idea is that every player gets a copy of the actions and then each player is restricted to specific devices. ApplyBindingOverridesOnMatchingControls() used to be the only way to do that but these days you can simply assign devices to the whole asset or to individual maps through the “devices” property and that does the trick.

However, there’s also a new set of components that are meant to make all this setup largely automatic. One is the PlayerInput component, the other is the PlayerInputManager component. Unfortunately, we don’t yet have much documentation on those and there’s still some unfinished work in there. The only thing as far as help goes is a crappy video I recorded a while ago.

Basically, the idea is that each PlayerInput represents one player and, by default, no two players will end up with the same device. So if you have two Logitech joysticks, each player would get only one specific one and only receive input from that one.

Thanks @Rene-Damm
I suppose there’s nothing stopping me having two PlayerInputs, one for each hand? (Its a single player, dual-stick game).
I got this working by wrapping the InputSystem with my own thing which is able to look at the CallbackContext, and that works for now, although I cant take advantage of any of the fancy Action Mapping stuff. I think for now I will just leave this in place until the PlayerInput components are a bit more mature, and then revisit the whole input thing again. Will anything happen there in the next few months?

Yup, that’s fine, too.

Alternatively, you can set things explicitly for handedness. There’s support for “usages” on devices. E.g. a device can be marked as having “LeftHand” usage and you can bind specifically to devices with that usage.

In the UI, this is supported out of the box for XR controllers, but unfortunately, for other controllers it currently requires dropping the control paths into text mode and manually editing them.

If you want to give this a try, simply pick a control, say the trigger on a joystick, drop it into text mode (in the current UI that’s the “…” button; in the next package, it’s the “T” button which is a toggle now), and edit the path like

// From something like
<Joystick>/trigger

// To something like
<Joystick>{LeftHand}/trigger

At runtime, you can simply assign usages to the devices you have. Like, for example:

InputSystem.SetDeviceUsage(firstJoystick, CommonUsages.LeftHand);
InputSystem.SetDeviceUsage(secondJoystick, CommonUsages.RightHand);

This works for arbitrary usages. You can also come up with your own instead of using “LeftHand” and “RightHand”. In the end, it’s just string tags. You can also have more than one on a device.

In this setup, you can also forego PlayerInput and don’t need to worry about duplicating actions or any other multiplayer concerns. The usages disambiguate input from the devices sufficiently.

For actions, it’s mainly bugfixing and polishing that will happen. Overall, we’re more or less feature complete. Couple of lose ends to tie up around PlayerInput. Otherwise, there’s a few things to do around UI support, work around improving rebinding support, and polishing/improving the editor UI. And yeah, fixing and fixing and fixing :slight_smile:

Hi; I also have two Thrustmaster T.16000m Joysticks, and want to seperate the input from the two joysticks into lefthand and righthand… I cannot get it to work, I guess I am missing some steps…
I have 2021.3.11f and use both input packages, the new package is 1.5.0…
This is a rather old post so maybe something changed.

Can anyone help me with all the steps needed?

This is the script, I get the two joysticks to show as Righthand and Lefthand but somehow the value is not passed…

Any thoughts?

using UnityEngine.InputSystem;
using UnityEngine;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public static class InitCustomDeviceUsages
{
    static InitCustomDeviceUsages()
    {
        Initialize();
    }

    [RuntimeInitializeOnLoadMethod]
    private static void Initialize()
    {
        InputSystem.RegisterLayoutOverride(@"
           {
               ""name"" : ""JoystickConfigurationUsageTags"",
               ""extend"" : ""Joystick"",
               ""commonUsages"" : [
                   ""LeftHand"", ""RightHand""
               ]
           }
       ");
    }
}


public class CustomDeviceUsages : MonoBehaviour
{
   


    protected void OnEnable()
    {
        List<InputDevice> joysticks = new List<InputDevice>();

        foreach (InputDevice device in InputSystem.devices)
        {
            if (device.description.product == "T.16000M") joysticks.Add(device);
        }

        InputSystem.SetDeviceUsage(joysticks[0], CommonUsages.LeftHand);
        InputSystem.SetDeviceUsage(joysticks[1], CommonUsages.RightHand);
    }

  
}


8861127--1209060--upload_2023-3-8_14-40-39.png

I also having similar problems with two Logitech extreme 3d pro Joystick Direction in unity new input system, did you found any solution?

9598876--1360669--upload_2024-1-23_16-53-14.png

I had to use the old input system only for those two joysticks, in the old input system the signals on the identical joysticks are separated