PlayerInputManager doesn’t support setups with 2 players on a single keyboard. I tried to setup my own class to do this that would replace PlayerInputManager. I was unable to get it to work. It allows only one player to join. Afterwards, it stops listening on that device. Any idea why?
Here’s a scene showing the issue TestShareDevice.zip (10.7 KB)
Here’s the class most likely causing the trouble:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// <see cref="PlayerInputManager"/> doesn't support multiple players on a single device. This class replaces <see cref="PlayerInputManager"/> specializing in multiple players on a single device.
/// </summary>
public class TestShareDevice : MonoBehaviour
{
[Header("BROKEN - this attempts:\n" +
"A demonstration of multiple players on a single\n" +
"keyboard device. Use either ctrl left, ctrl right,\n" +
"spacebar, or numpad enter to jump a cube.\n")]
[Tooltip("Button to press for a player to join.")]
[SerializeField]
private InputActionReference ActionToJoin;
[SerializeField]
private GameObject PlayerPrefab;
/// <summary> What control schemes have already joined. They're not allowed to join again. </summary>
private List<string> schemesJoined = new List<string>();
private void OnEnable()
{
ActionToJoin.action.performed += OnAction_performed;
ActionToJoin.action.Enable();
}
private void OnDisable()
{
ActionToJoin.action.Disable();
ActionToJoin.action.performed -= OnAction_performed;
}
/// <summary> Similiar to the <see cref="PlayerInputManager"/> function that raises OnPlayerJoined </summary>
private void OnAction_performed(InputAction.CallbackContext ctx)
{
// Get control that triggered from the context.
var control = ctx.control;
// "binding.group" contains the name of the scheme. ref https://discussions.unity.com/t/any-way-to-get-the-control-scheme-for-an-input-through-inputaction-callbackcontext/811484/5
var scheme = ctx.action.GetBindingForControl(control).Value.groups;
// player already joined
if (schemesJoined.Contains(scheme))
{
Debug.Log(scheme + " already added " + Time.frameCount);
return;
}
// join player
else
{
Debug.Log(scheme + " being added " + Time.frameCount);
schemesJoined.Add(scheme);
var playerInput = PlayerInput.Instantiate(PlayerPrefab, controlScheme: scheme, pairWithDevice: control.device);
playerInput.gameObject.name = "Player" + playerInput.playerIndex + playerInput.currentControlScheme;
}
}
}