Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Get error messages when spawning PlayerInput prefabs

Discussion in 'Input System' started by Magic-4e, Feb 24, 2021.

  1. Magic-4e

    Magic-4e

    Joined:
    May 9, 2018
    Posts:
    25
    Not sure if this is a bug or that I am doing something wrong, but when I spawn a player trough:
    PlayerInput.Instantiate(GameObject, Int32, String, Int32, InputDevice)

    I get the following error messages:
    upload_2021-2-24_14-3-35.png

    Does anybody know why?

    The code for this:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.InputSystem;
    3. using UnityEngine.InputSystem.Users;
    4.  
    5. public class PlayerManagerInputHandeler : MonoBehaviour
    6. {
    7.     //*Target objects
    8.     //Player prefab
    9.     public GameObject playerPrefab;
    10.  
    11.     //*Components
    12.     /// <summary>The InputUser struct of the PlayerInputManager</summary>
    13.     //(This is used to listen to inputs and filter them based on player/controller paring)
    14.     private InputUser user0;
    15.  
    16.     //*Memory
    17.     /// <summary>The memory value of the start button</summary>
    18.     private float buttonMem = 0;
    19.     private int playerInputCountMem = 0;
    20.  
    21.     //#### Unity functions ####
    22.     //## Awake is called when this script instance is being loaded
    23.     private void Awake()
    24.     {
    25.         //Get the PlayerInputManager's InputUser (user 0 is the first created user)
    26.         user0 = PlayerInput.all[0].user;
    27.  
    28.         //Unpair and repair all unpaired devices from input manager/user 0 (basically refresh it)
    29.         user0.UnpairDevices();
    30.  
    31.         foreach (InputDevice unPairDev in InputUser.GetUnpairedInputDevices())
    32.         {
    33.             InputUser.PerformPairingWithDevice(unPairDev, user0);
    34.         }
    35.     }
    36.  
    37.     //## Update is called once per frame
    38.     private void Update()
    39.     {
    40.         //Get any newly added devices
    41.         if (InputUser.GetUnpairedInputDevices().Count != 0)
    42.         {
    43.             //Unpair and repair all unpaired devices from input manager/user 0 (basically refresh it)
    44.             user0.UnpairDevices();
    45.  
    46.             foreach (InputDevice unPairDev in InputUser.GetUnpairedInputDevices())
    47.             {
    48.                 InputUser.PerformPairingWithDevice(unPairDev, user0);
    49.             }
    50.         }
    51.     }
    52.  
    53.     //#### My functions ####
    54.     //## Inputs
    55.     /// <summary>Reads a device's start input and creates a new player to pair with that device</summary>
    56.     public void StartDevice(InputAction.CallbackContext context)
    57.     {
    58.         if (buttonMem != context.ReadValue<float>())
    59.         {
    60.             buttonMem = context.ReadValue<float>();
    61.  
    62.             if (context.ReadValue<float>() > 0)
    63.             {
    64.                 buttonMem = 0;
    65.  
    66.                 //Spawn a new player and assign the device from the received input
    67.                 CreatePlayer(playerPrefab, context.control.device);
    68.             }
    69.         }
    70.     }
    71.  
    72.     //## Outputs
    73.     /// <summary>Spawn a player and assign a device to it</summary>
    74.     private void CreatePlayer(GameObject playerPrefab, InputDevice inputDevice)
    75.     {
    76.         //Create an player instance and get it's InputUser
    77.         var playerInstance = PlayerInput.Instantiate(playerPrefab, PlayerInput.all.Count, default, default, inputDevice);
    78.  
    79.         var userInstance = playerInstance.user;
    80.  
    81.         if (inputDevice == Mouse.current || inputDevice == Keyboard.current)
    82.         {
    83.             //Pair mouse and keyboard to the created player
    84.             InputUser.PerformPairingWithDevice(Mouse.current, userInstance);
    85.             InputUser.PerformPairingWithDevice(Keyboard.current, userInstance);
    86.  
    87.             //Unpair mouse and keyboard
    88.             user0.UnpairDevice(Mouse.current);
    89.             user0.UnpairDevice(Keyboard.current);
    90.         }
    91.         else
    92.         {
    93.             //Pair a device to the created player
    94.             InputUser.PerformPairingWithDevice(inputDevice, userInstance);
    95.  
    96.             //Unpair current device
    97.             user0.UnpairDevice(inputDevice);
    98.         }
    99.     }
    100. }
     
  2. Magic-4e

    Magic-4e

    Joined:
    May 9, 2018
    Posts:
    25
    Ok I think I found the cause.
    It's this function:
    Code (CSharp):
    1. user0.UnpairDevice(InputDevice);
    I run this code every time I spawn a player.
    It is supposed to just remove a player from my manager object, but for some reason it causes 4 error messages that don't mean anything to me.

    I replaced this function with:
    Code (CSharp):
    1. user0.UnpairDevices();
    Instead of removing the exact device that was paired to the new player, it removes all players.
    I can do this because in Update I check for devices with no players paired to them and bind them back to the manager.

    First I still received errors, but I discovered that they appear too when
    user0.UnpairDevices()
    is ran when no devices are paired to the manager.

    The reason why it runs more than once should be because the input event runs 2 times with button events.
    Once for on
    Once for off
    But sometimes it just runs on un expected moments.
    I don't know why.

    To counter this effect, I made a setup that every time the Start Device input event is ran it disables it self with an if statement.
    It waits until Update is ran once.

    After that it works perfectly.

    Note that
    user0.UnpairDevice()
    still gives error messages even if it's ran just once.

    But that's it.
    There is still a bug, but this is a little work around.
    I hope I helped somebody else too with this.