How to use InputUser.PerformPairingWithDevice to swap controls in multiplayer?

So basically I wish to swap controls from one prefab to another (as seen in sports games) using the new input system. I attempt to do so by disabling one player prefab (whose playerInput is attached) and enabling another (whose playerInput is also attached). Unity then does an auto-pairing which then wrongly assigns an already used device to the player which results in a player being able to control multiple prefabs with one device. Here is my code that hopes to do this pairing based off of simple individual indices:

foreach (GameObject p in levelManager.GetPlayers())
            {
                if (p.GetComponent<Player>().hasJoystick)
                {
                    Player pScript = p.GetComponent<Player>();
                    PlayerInput pInput = pScript.controller3DObject.GetComponent<PlayerInput>();
                    InputUser pUser = pInput.user;
                   Gamepad g = Gamepad.all[pScript.joystick.number];
                   InputUser.PerformPairingWithDevice(g, pUser, InputUserPairingOptions.UnpairCurrentDevicesFromUser);
                }
             
            }
3 Likes

I wish to swap controls from one prefab to another (as seen in sports games) using the new input system

Just to clarify, what exactly you’re trying to achieve here? Control different characters from same device or something? Could you provide an example of a game were something like this is implemented (just so I can write up context for the bug)

1 Like

Yes @dmytro_at_unity ! Thanks for the response.
To clarify, “Controlling different characters from the same device” is exactly what I’m trying to do. For some reason the swap works fine with one controller connected. Here simply disabling one playerInput and enabling another works fine, but when multiple devices are detected, I run into a heap of problems as mentioned above.

To clarify, “Controlling different characters from the same device” is exactly what I’m trying to do. For some reason the swap works fine with one controller connected. Here simply disabling one playerInput and enabling another works fine, but when multiple devices are detected, I run into a heap of problems as mentioned above.

Ok makes sense, PlayerInput is not really designed with this in mind, it’s more for split screen multiplayer, where “player” stands for physical person playing the game.

Usecase where all you in-game characters are prefabs with same level nestedness is also valid.
I would recommend making a prefab which represents a physical player, and then making a layer to forward input data to relevant character in-game instead, this way you have one source of truth and it will be more robust overall.

1 Like

Ok thank you. This is interesting. So architecturally within the context of the input system, would this look like having a playerInput per physical user/device detected? If so, the question then would be how to take a playerInput component and attach it to another prefab during runtime?

I could be wrong, but it seems PlayerInput.HandleControlsChanged is pretty much hardcoded to sending events to current object, so you will only getting events on whatever GameObject you added PlayerInput controller to.

So one way could be is to add one PlayerInput to a scene to some general input managing game object (if you don’t need split screen multiplayer), and then from there make a proxy-script to listen to events and call events on “current selected in-game character” manually.

Another way would be to tech PlayerInput to target different game objects, though this is more of a new feature.

1 Like

You can force any PlayerInput<->device combination(s) manually through SwitchCurrentControlScheme.

// Give controls from player #1 to player #2.
var player1 = PlayerInput.all[0];
var player2 = PlayerInput.all[1];
player2.SwitchCurrentControlScheme(
    player1.currentControlScheme,
    player1.devices.ToArray());

// Silence player1's input for now while we use player #2's input.
player1.DeactivateInput();
4 Likes

Agh! These are all helpful! Thank you both @Rene-Damm & @dmytro_at_unity