In a local multiplayer setup once players and devices have been matched in some lobby scene, loading the next scene loses all the InputUser instances. So even if you have some “Don’tDestroyOnLoad” GameManager holding references to users, devices, prefabs etc., those InputUser references are invalid on a scene change.
Is this the expected behaviour?
What is the recommended way to hold all the user<->device setups from previous levels?
Between scenes everything is destroyed - the only thing which survives a scene change is the GameManager which holds housekeeping arrays of users and devices.
// From the lobby scene we have the users, their devices and the character prefabs
// in a static class called PlayerSettings which contains three static arrays.
InputUser[] users;
InputDevice[] devices;
GameObject[] PlayerPrefabs;
In the next scene the GameManager will re-create the players using the code
var user = InputUser.PerformPairingWithDevice(PlayerSettings.devices[0], PlayerSettings.users[0], InputUserPairingOptions.UnpairCurrentDevicesFromUser);
user.AssociateActionsWithUser(inputActionAsset);
The first call to PerformPairingWithDevice will throw the error InvalidUser. Also when the scene changes but before the GameManager attempts to spawn the players I notice that all users device pairings vanish from the InputSystemDebugger window (very useful tool BTW).
You probably should keep the “real” Players gameobjects aswell, and distinguish between a “Real player” (PlayerInput/InputUser) from an “InGame player” (Character or whatever)
I do indeed do that, but I was exploring what else InputUser had to offer in situations where the platform provides user information. If InputUser references can’t be carried over between scenes then platform user specific support will have to be handled differently.