Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

Bug Splitscreen with Join Manually does not work

Discussion in 'Input System' started by VoltDriver, May 3, 2024.

  1. VoltDriver

    VoltDriver

    Joined:
    Nov 16, 2019
    Posts:
    15
    EDIT: Solved by Abdo-Reda.

    Greetings!

    I have an issue trying to use the new input system and the Split Screen feature of the PlayerManager. If I use "Join Players When a Button is Pressed", everything works fine. But If I join my players manually, they never get their camera set up in split screen, or at all actually.

    My Unity version is 2022.3.20f1.

    To isolate the issue, I have created a new, blank project using the 3D URP template. In it, I have a PlayerPrefab and a test controller script. You can see it here:
    upload_2024-5-3_9-51-13.png
    Not much on it. Cube is a 3D cube, no other scripts.
    Camera is a default camera.
    upload_2024-5-3_9-51-37.png


    At the root, I have the player Input.
    upload_2024-5-3_9-51-59.png

    Very standard, very simple.

    Ok, now let's have a look at my TestController script.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.InputSystem;
    5.  
    6. public class TestSplitController : MonoBehaviour
    7. {
    8.     public PlayerInputManager manager;
    9.     public GameObject playerPrefab;
    10.  
    11.     private int _gamepadIndex = -1;
    12.     private int _pIndex = 0;
    13.  
    14.     // Input
    15.     private PlayerInput _playerInput;
    16.     private InputAction _joinAction;
    17.  
    18.     private void Awake()
    19.     {
    20.         manager.playerPrefab = playerPrefab;
    21.    
    22.         if (Gamepad.all.Count > 0)
    23.         {
    24.             _gamepadIndex = 0;
    25.         }
    26.    
    27.         JoinPlayer();
    28.    
    29.         _playerInput = FindObjectOfType<PlayerInput>();
    30.         _joinAction = _playerInput.actions["Escape"];
    31.     }
    32.  
    33.     private void OnEnable()
    34.     {
    35.         _joinAction.performed += OnJoin;
    36.     }
    37.  
    38.     private void OnDisable()
    39.     {
    40.         _joinAction.performed -= OnJoin;
    41.     }
    42.  
    43.     // Start is called before the first frame update
    44.     void Start()
    45.     {
    46.    
    47.     }
    48.  
    49.     // Update is called once per frame
    50.     void Update()
    51.     {
    52.    
    53.     }
    54.  
    55.     public void OnJoin(InputAction.CallbackContext pContext)
    56.     {
    57.         JoinPlayer();
    58.     }
    59.  
    60.     public void JoinPlayer()
    61.     {
    62.         // Determine input device
    63.         InputDevice device = null;
    64.         string controlScheme = "";
    65.         if (_gamepadIndex >= 0)
    66.         {
    67.             if (_gamepadIndex < Gamepad.all.Count)
    68.             {
    69.                 device = Gamepad.all[_gamepadIndex];
    70.                 controlScheme = "Gamepad";
    71.                 _gamepadIndex++;
    72.             }
    73.         }
    74.         if (device == null)
    75.         {
    76.             // No gamepads available. Assign keyboard.
    77.             device = Keyboard.current;
    78.             controlScheme = "Keyboard";
    79.         }
    80.        
    81.         // Join players manually for splitscreen.
    82.         // This also spawns the player object
    83.         PlayerInput spawnedPlayer = manager.JoinPlayer(_pIndex, _pIndex, controlScheme, device);
    84.         spawnedPlayer.enabled = true;
    85.         _pIndex++;
    86.     }
    87. }
    88.  
    This is also very simple, bear with me as I go through. It prioritizes gamepads. When it awakens, it checks the number of gamepads available, and then calls JoinPlayer().
    JoinPlayer() is called at the awake stage, or whenever the Escape action is triggered. It checks first if we have a gamepad that wasn't bound to another player yet. If so, that's what we use. If not, then we use the keyboard.

    Then it joins the player manually by calling JoinPlayer. The split screen index is managed here, the control scheme is one of two ("Gamepad" or "Keyboard") which are defined in the InputActions asset.

    In my scene, I have this PlayerInputManager:
    upload_2024-5-3_9-56-24.png

    That's it. Very simple yes?

    If I do not use this script (as in, it is removed from the scene), and instead put Join Players on Any Button pressed, everything works fine. Each player joins, the screen gets splitted, all seems well.
    upload_2024-5-3_10-2-10.png

    But as soon as I use this script, the split screen no longer works. Players get instantiated correctly. Users have the proper device and control scheme attached. Everything *seems* fine, yet ... black screen on the camera.

    You can see here, the players are in. And in the Hierarchy they are there. No errors in the console whatsoever. But, no display. No camera, nothing.

    What is going on? How can I fix it? I need manual join to work.

    I have uploaded the whole project repo as a zip in google drive, here:
    https://drive.google.com/file/d/1swF-XCqKCzQi8RqwpNjwW4qh-MCglwXX/view?usp=sharing

    Please help. Thank you !
     
    Last edited: May 23, 2024
  2. VoltDriver

    VoltDriver

    Joined:
    Nov 16, 2019
    Posts:
    15
    Bump, anyone has an idea on this?
     
  3. Abdo-Reda

    Abdo-Reda

    Joined:
    Oct 8, 2015
    Posts:
    18
    Hi, I think the problem is with the splitscreen index you are assigning. I don't have multiple gamepads at the moment, can you try the following code and tell me if it works.

    Code (CSharp):
    1. manager.JoinPlayer(_pIndex, controlScheme: controlScheme, pairWithDevice: device);
     
    VoltDriver likes this.
  4. VoltDriver

    VoltDriver

    Joined:
    Nov 16, 2019
    Posts:
    15
    Hey, sorry for the late reply, but I tested your code and.... It works!

    Wow, I have no idea why the splitscreen index was causing problems. Do you have any insight as to why it was the culprit?

    Thank you so much btw, this had me stuck for weeks.
     
    Abdo-Reda likes this.
  5. Abdo-Reda

    Abdo-Reda

    Joined:
    Oct 8, 2015
    Posts:
    18
    No problem at all. Glad it helped.

    To be honest, I am not sure why its causing an issue. my guess is that it has to do with the order of how things are setup or executed. There is a function called UpdateSplitScreen, maybe its not getting called. I will have to debug in order to make sure though.

    We can report it as a bug if you want, I feel like this is unexpected behavior.
     
    Last edited: May 23, 2024
  6. VoltDriver

    VoltDriver

    Joined:
    Nov 16, 2019
    Posts:
    15
    Sure! I am not sure how to flag a bug report to Unity and what's the process, but I think it warrants being flagged.
     
  7. Abdo-Reda

    Abdo-Reda

    Joined:
    Oct 8, 2015
    Posts:
    18
    VoltDriver likes this.
  8. VoltDriver

    VoltDriver

    Joined:
    Nov 16, 2019
    Posts:
    15
    Abdo-Reda likes this.