Splitscreen with Join Manually does not work

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:
9812334--1409373--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.

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

Very standard, very simple.

Ok, now let’s have a look at my TestController script.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class TestSplitController : MonoBehaviour
{
    public PlayerInputManager manager;
    public GameObject playerPrefab;
 
    private int _gamepadIndex = -1;
    private int _pIndex = 0;
 
    // Input
    private PlayerInput _playerInput;
    private InputAction _joinAction;

    private void Awake()
    {
        manager.playerPrefab = playerPrefab;
    
        if (Gamepad.all.Count > 0)
        {
            _gamepadIndex = 0;
        }
    
        JoinPlayer();
    
        _playerInput = FindObjectOfType<PlayerInput>();
        _joinAction = _playerInput.actions["Escape"];
    }

    private void OnEnable()
    {
        _joinAction.performed += OnJoin;
    }

    private void OnDisable()
    {
        _joinAction.performed -= OnJoin;
    }
 
    // Start is called before the first frame update
    void Start()
    {
    
    }

    // Update is called once per frame
    void Update()
    {
    
    }

    public void OnJoin(InputAction.CallbackContext pContext)
    {
        JoinPlayer();
    }

    public void JoinPlayer()
    {
        // Determine input device
        InputDevice device = null;
        string controlScheme = "";
        if (_gamepadIndex >= 0)
        {
            if (_gamepadIndex < Gamepad.all.Count)
            {
                device = Gamepad.all[_gamepadIndex];
                controlScheme = "Gamepad";
                _gamepadIndex++;
            }
        }
        if (device == null)
        {
            // No gamepads available. Assign keyboard.
            device = Keyboard.current;
            controlScheme = "Keyboard";
        }
        
        // Join players manually for splitscreen.
        // This also spawns the player object
        PlayerInput spawnedPlayer = manager.JoinPlayer(_pIndex, _pIndex, controlScheme, device);
        spawnedPlayer.enabled = true;
        _pIndex++;
    }
}

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:
9812334--1409382--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.

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:

Please help. Thank you !

Bump, anyone has an idea on this?

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.

manager.JoinPlayer(_pIndex, controlScheme: controlScheme, pairWithDevice: device);
1 Like

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.

2 Likes

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.

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.

I never reported a bug before, but I found this link Unity QA: Building quality with passion if you are not lazy like me and have time, you should try and report it.

1 Like

Thank you, I will!

1 Like