Multiplayer Team Spawning

I’m trying to add a Team/Class system to my multiplayer code. I have a TeamManager script and a couple canvas’s that open and close and call functions in the TeamManager script. I can spawn a player on a spawn point for red or for blue but if I try connecting another player it doesn’t work at all. Also it won’t give control to the player after spawning. I don’t know where this code should be, what it should be attached to or how to implement the server/client stuff. There’s no simple tutorials on this that explains it well.

I have been trying to get this working for the past week and can’t seem to find any solid info.

I don’t know a whole lot about Unity multiplayer. I know a little about [Command] and [ClientRpc] but I don’t really know what it does… sends to server then server sends it to client or something? I’ve been reading the docs and it’s no help.

I’m going to post my code here can someone please help me get a team/class system spawning working?

I’ve read about this but this doesn’t work either. I’ve tried a hundred different ways.

GameObject player = (GameObject)Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);

Here’s my TeamManager script which is attached to an empty and has a network identity component.

using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class TeamManager : NetworkBehaviour
{
    private string Team;
    private string PlayerClass;

    private GameObject Hud;
    public GameObject joinTeamCanvas;
    public GameObject ClassCanvas;

    public Text TeamText; // Used to display team
    public Text ClassText; // Used to display class

    GameObject redSpawnPoint;
    GameObject blueSpawnPoint;

    [SerializeField]
    private GameObject RedPlayerPrefab;

    [SerializeField]
    private GameObject BluePlayerPrefab;

    private GameObject _player;

    // Use this for initialization
    void Start()
    {
        Debug.Log("TeamManager: Start() called.");

        Hud = GameObject.FindGameObjectWithTag("NetworkManager");
        //Hud.gameObject.SetActive(true);

        //joinTeamCanvas = GameObject.FindGameObjectWithTag("TeamMenuCanvas");
        joinTeamCanvas.gameObject.SetActive(false);

        //ClassCanvas = GameObject.FindGameObjectWithTag("ClassMenuCanvas");
        ClassCanvas.gameObject.SetActive(false);

        redSpawnPoint = GameObject.Find("SpawnPointRed01");
        blueSpawnPoint = GameObject.Find("SpawnPointBlue01");
    }

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

    }

    // Join a team
    [Command]
    public void CmdJoinTeamBlue()
    {
        Team = "Blue";
        SetTeamText();
        //ClassCanvas.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(false);
        RpcJoinTeamBlue();
    }

    [ClientRpc]
    public void RpcJoinTeamBlue()
    {
        GameObject _player = (GameObject)Instantiate(BluePlayerPrefab, blueSpawnPoint.transform.position, blueSpawnPoint.transform.rotation);
        
    }


    [Command]
    public void CmdJoinTeamRed()
    {
        Team = "Red";
        SetTeamText();
        //ClassCanvas.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(false);
        RpcJoinTeamRed();
    }

    [ClientRpc]
    public void RpcJoinTeamRed()
    {
        GameObject _player = (GameObject)Instantiate(RedPlayerPrefab, redSpawnPoint.transform.position, redSpawnPoint.transform.rotation);        
    }

    public void Class1()
    {
        PlayerClass = "Class1";
        SetClassText();
        Hud.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(true);
        ClassCanvas.gameObject.SetActive(false);
    }

    public void Class2()
    {
        PlayerClass = "Class2";
        SetClassText();
        Hud.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(true);
        ClassCanvas.gameObject.SetActive(false);
    }

    public void Class3()
    {
        PlayerClass = "Class3";
        SetClassText();
        Hud.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(true);
        ClassCanvas.gameObject.SetActive(false);
    }

    public void Class4()
    {
        PlayerClass = "Class4";
        SetClassText();
        Hud.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(true);
        ClassCanvas.gameObject.SetActive(false);
    }

    public void Class5()
    {
        PlayerClass = "Class5";
        SetClassText();
        Hud.gameObject.SetActive(true);
        joinTeamCanvas.gameObject.SetActive(true);
        ClassCanvas.gameObject.SetActive(false);
    }

    // Set the Team UI text
    public void SetTeamText()
    {
        TeamText.text = "Team: " + Team;
    }

    // Set the Class UI text
    public void SetClassText()
    {
        ClassText.text = "Class: " + PlayerClass;
    }


}

Here’s my networkmanager script which doesn’t do a lot right now (it opens and closes popups) and I’ve commented out a lot of things I’ve tried like spawning the player from OnServerAddPlayer.

using UnityEngine;
using UnityEngine.Networking;

public class _NetworkManager : NetworkManager{

    public GameObject JoinTeamCanvas;
    public GameObject classCanvas;
    public TeamManager myTeamManager;
    
    /*
    [SerializeField]
    private GameObject myPlayerPrefab;
    private GameObject _player;
    private NetworkConnection _myConn;      // Make a copy of the connection
    private short _myPlayerControllerID;    // Make a copy of the PlayerControllerId
    */

    // Count how many players are connected
    private int playersConnectedCount = 0;


    public void Start()
    {
        //JoinTeamCanvas = GameObject.Find("JoinTeamCanvas");
        JoinTeamCanvas.gameObject.SetActive(false);
        //classCanvas = GameObject.Find("ClassCanvas");
        classCanvas.gameObject.SetActive(false);

        myTeamManager = GetComponent<TeamManager>();
    }



    
    public override void OnServerConnect(NetworkConnection conn)
    {
        Debug.Log("_NetworkManager:OnServerConnect New client connected, ID: " + conn.connectionId.ToString());
    }

    public override void OnServerDisconnect(NetworkConnection conn)
    {
        Debug.Log("_NetworkManager:OnServerDisconnect:  Client disconnected, ID: " + conn.connectionId.ToString());
    }

    
    public override void OnClientConnect(NetworkConnection conn)
    {
        Debug.Log("_NetworkManager:OnClientConnect: Connected to Server, ID:" + conn.connectionId.ToString());

        // Count players connected
        playersConnectedCount++;
        Debug.Log("_NetworkManager:OnClientConnect: Players Connected Count: " + playersConnectedCount);        
        
        ClientScene.Ready (conn);
        ClientScene.AddPlayer(0);

        // Show Join Team Menu        
        classCanvas.gameObject.SetActive(true);

    }
    

    public override void OnClientDisconnect(NetworkConnection conn)
    {
        Debug.Log("_NetworkManager:OnClientDisconnect: Disconnected from Server, ID:" + conn.connectionId.ToString());

        // Count players connected
        playersConnectedCount--;
        if (playersConnectedCount <= 0)
        {
            playersConnectedCount = 0;
        }
        Debug.Log("_NetworkManager:OnClientDisconnect:  Players Connected Count: " + playersConnectedCount);
    }
    
    
        
    public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
    {
        Debug.Log("_NetworkManager:OnServerAddPlayer called. ID: " + conn.connectionId.ToString());


        /*
        // Get a reference to the TeamManager so we know what team the player joined. - not working - only getting the local host.
        teamManager = GameObject.FindObjectOfType<TeamManager>();
        
        Debug.Log(" _NetworkManager OnServerAddPlayer called." );       
        
        if (teamManager.Team == "Blue")
        {
            Debug.Log("_NetworkManager: OnServerAddPlayer:  Team Joined is Blue");
        }
        else if (teamManager.Team == "Red")
        {
            Debug.Log("_NetworkManager: OnServerAddPlayer:  Team Joined is Red");
        }
        */

        /*
        _myConn = conn;
        _myPlayerControllerID = playerControllerId;

        _player = Instantiate(myPlayerPrefab) as GameObject;
        _player.name = myPlayerPrefab.name;
        _player.transform.position = new Vector3(0, 1, 0);
        _player.transform.Rotate(0, 0, 0);
        NetworkServer.AddPlayerForConnection(conn, myPlayerPrefab, playerControllerId);
        */

        /*
        GameObject player = (GameObject)Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
        NetworkServer.AddPlayerForConnection(conn, player, playerControllerId);
        */
        
    }


}

I also have this playerSetup script attached to my player object prefab that when it’s not using the team/class system it spawns players in one spawnpoint using the autospawn on networkmanager.

The if (!isLocalPlayer) doesn’t seem to get the local player when I’m using the team system. It won’t give me control of the player. If I remove all that code it will but then it controls all players…

using UnityEngine;
using UnityEngine.Networking;

[RequireComponent(typeof(Player))]
//[RequireComponent(typeof(MatchSettings))]
public class PlayerSetup : NetworkBehaviour {

    [SerializeField]
    Behaviour[] componentsToDisable;

    [SerializeField]
    string remoteLayerName = "RemotePlayer";

    [SerializeField]
    string dontDrawLayerName = "DontDraw";

    [SerializeField]
    GameObject playerGraphics;

    [SerializeField]
    GameObject playerUIPrefab;

    private GameObject playerUIInstance;

    Camera sceneCamera;


    // Use this for initialization
    void Start () {

        Debug.Log("PlayerSetup: Start() called.");

        if (!isLocalPlayer)
        {
            DisableComponents();
            AssignRemoteLayer();            
        }
        else
        {
            sceneCamera = Camera.main;
            if (sceneCamera != null)
            {
                sceneCamera.gameObject.SetActive(false);
            }

            // Disable graphics for local player
            SetPlayerRecursively(playerGraphics, LayerMask.NameToLayer(dontDrawLayerName));

            // Create player UI - Crosshair
            playerUIInstance = Instantiate(playerUIPrefab);
            playerUIInstance.name = playerUIPrefab.name;
        }         
    }



    // Used to disable the 3rd person player model from drawing on the player
    void SetPlayerRecursively(GameObject obj, int newLayer)
    {
        obj.layer = newLayer;

        foreach (Transform child in obj.transform)
        {
            SetPlayerRecursively(child.gameObject, newLayer);
        }
    }

    public override void OnStartClient()
    {
        Debug.Log("PlayerSetup:OnStartClient() called.");

        base.OnStartClient();

        string _netID = GetComponent<NetworkIdentity>().netId.ToString();
        Player _player = GetComponent<Player>();

        GameManager.RegisterPlayer(_netID, _player);      
    }


    void AssignRemoteLayer()
    {
        gameObject.layer = LayerMask.NameToLayer(remoteLayerName);
    }

    void DisableComponents()
    {
        for (int i = 0; i < componentsToDisable.Length; i++)
        {
            componentsToDisable*.enabled = false;*

}
}

// Called when object is destroyed or player leaves game.
void OnDisable()
{
Destroy(playerUIInstance);

if (sceneCamera != null)
{
sceneCamera.gameObject.SetActive(true);
}
GameManager.UnRegisterPlayer(transform.name);
}
}

This kind of no response on of the Unity Network System and no explanation or lack of documents makes me want to give up unity.