Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question Can't instantiate a new player with keyboard controls

Discussion in 'Input System' started by soupeater, Aug 6, 2023.

  1. soupeater

    soupeater

    Joined:
    Jul 11, 2018
    Posts:
    2
    I'm currently working on a game with local co-op, based around different controllers being connected to the same machine. This includes a scene where players select who is going to be Player 1 and Player 2, and then the scene switches and loads the actual game scene. Because of this, I need to take the information of the device and control scheme of the controller that selected P1 and pass it into the player 1 game object. The way that I've found to do this is to have a player manager game object retrieve the device and control scheme and then instantiate a new player with that device and control scheme. The code I've used is as follows:
    Code (CSharp):
    1. public void pairController (int playerNumber, PlayerInput inputReference) //Pairs a controller input with a player
    2.     {
    3.         Debug.Log("Control scheme for new player: " + inputReference.currentControlScheme);
    4.         Debug.Log("Device for new player: " + inputReference.devices[0]);
    5.  
    6.         PlayerInput newPlayerInput = PlayerInput.Instantiate(playerPrefab, 0, inputReference.currentControlScheme, -1, inputReference.devices[0]);
    7.  
    8.         Rigidbody2D playerRigidbody = newPlayerInput.GetComponent<Rigidbody2D>();
    9.  
    10.         if (playerNumber == 1) //If the controller input received is assigned to player 1
    11.         {
    12.             player1 = newPlayerInput.gameObject;
    13.  
    14.             playerRigidbody.position = player1StartPos; //Sets a position for if they are player 1
    15.  
    16.             player1Script = player1.GetComponent<PlayerActionTracker>(); //Stores the reference to the player script
    17.             player1Script.setPlayerNumber(1); //Tells player 1 that it is player 1
    18.         }
    19.         else if(playerNumber == 2) //If the controller input received is assigned to player 2
    20.         {
    21.             player2 = newPlayerInput.gameObject;
    22.  
    23.             playerRigidbody.position = player2StartPos; //Sets a position for if they are player 2
    24.  
    25.             player2Script = player2.GetComponent<PlayerActionTracker>(); //Stores the reference to the player script
    26.             player2Script.setPlayerNumber(2); //Tells player 2 that it is player 2
    27.         }
    28.  
    29.         playerCount++;
    30.  
    31.         if (playerCount == 2) //Now that both players have been added
    32.         {
    33.             player1Script.setOtherPlayer(player2); //Gives player 1 a reference to player 2
    34.             player2Script.setOtherPlayer(player1); //Gives player 2 a reference to player 1
    35.         }
    36.  
    37.         cameraScript.setPlayerReference(newPlayerInput.gameObject); //Gives the camera a reference to the newly added player
    38.  
    39.         newPlayerInput.gameObject.SetActive(true); //Player game object is enabled by default so we only see them once they are in position
    40.     }
    This works perfectly fine on gamepad (I've tested it with multiple gamepads and it works exactly as intended). However, if one of the players is using a keyboard, the player does not register any keyboard inputs. The PlayerInput component is, for some reason, only on keyboard, instantiated without any device or control scheme. It looks like this:
    Screenshot 2023-08-06 122243.png

    What is even stranger is what my Debug.log returns.

    Code (CSharp):
    1. Debug.Log("Device for new player: " + inputReference.devices[0]);
    returns "Device for new player: Keyboard:/Keyboard"

    So it seems the information is being passed correctly, but instantiate just doesn't like the keyboard device? Any idea what's going on here?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    37,235
    Line 4 above always refers to device [0]... is that reasonable?

    Wouldn't the two players be using different devices?

    Disclaimer: I haven't used this input system enough to know that so I'm just speculating that this [0] looks out of place.
     
  3. soupeater

    soupeater

    Joined:
    Jul 11, 2018
    Posts:
    2
    This is intentional. PlayerInput.Devices is an array of all the devices attached to one gameObject, not the devices attached to all gameObjects, meaning if a gameObject has only one device attached (as both of these should), only one item would be in the array. To get different devices my script should pull from different PlayerInput components, as it does successfully for gamepads.
     
    Kurt-Dekker likes this.
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    37,235
    Thanks, wasn't sure about that.

    How about the actual raw input devices? What if you just loop through those two and print their outputs directly? Are you even getting separate input streams?