Unity Lobby Multiplayer, multiple player prefabs

Hi all before I ask my question ill show my code… it sort of works. BTW the code is the unity LobbyManager script with a few edits for multiple player prefabs.

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using UnityEngine.Networking;
using UnityEngine.Networking.Types;
using UnityEngine.Networking.Match;
using System.Collections;


namespace Prototype.NetworkLobby
{
    public class LobbyManager : NetworkLobbyManager
    {

        public Button player1Button;
        public Button player2Button;

        int avatarIndex = 0;

        public Canvas characterSelectionCanvas;


        static short MsgKicked = MsgType.Highest + 1;

        static public LobbyManager s_Singleton;


        [Header("Unity UI Lobby")]
        [Tooltip("Time in second between all players ready & match start")]
        public float prematchCountdown = 5.0f;

        [Space]
        [Header("UI Reference")]
        public LobbyTopPanel topPanel;

        public RectTransform mainMenuPanel;
        public RectTransform lobbyPanel;

        public LobbyInfoPanel infoPanel;
        public LobbyCountdownPanel countdownPanel;
        public GameObject addPlayerButton;

        protected RectTransform currentPanel;

        public Button backButton;

        public Text statusInfo;
        public Text hostInfo;

        //Client numPlayers from NetworkManager is always 0, so we count (throught connect/destroy in LobbyPlayer) the number
        //of players, so that even client know how many player there is.
        [HideInInspector]
        public int _playerNumber = 0;

        //used to disconnect a client properly when exiting the matchmaker
        [HideInInspector]
        public bool _isMatchmaking = false;

        protected bool _disconnectServer = false;

        protected ulong _currentMatchID;

        protected LobbyHook _lobbyHooks;

        void Start()
        {
            s_Singleton = this;
            _lobbyHooks = GetComponent<Prototype.NetworkLobby.LobbyHook>();
            currentPanel = mainMenuPanel;

            backButton.gameObject.SetActive(false);
            GetComponent<Canvas>().enabled = true;

            //DontDestroyOnLoad(gameObject);

            player1Button.onClick.AddListener(delegate { AvatarPicker(player1Button.name); });
            player2Button.onClick.AddListener(delegate { AvatarPicker(player2Button.name); });

            SetServerInfo("Offline", "None");
        }

        void AvatarPicker(string buttonName)
        {
            switch (buttonName)
            {
                case "Player1":
                    avatarIndex = 0;
                    break;
                case "Player2":
                    avatarIndex = 1;
                    break;

            }

            playerPrefab = spawnPrefabs[avatarIndex];
            gamePlayerPrefab = spawnPrefabs[avatarIndex];
        }


        public override void OnLobbyClientSceneChanged(NetworkConnection conn)
        {
            if (SceneManager.GetSceneAt(0).name == lobbyScene)
            {
                if (topPanel.isInGame)
                {
                    ChangeTo(lobbyPanel);
                    if (_isMatchmaking)
                    {
                        if (conn.playerControllers[0].unetView.isServer)
                        {
                            backDelegate = StopHostClbk;
                        }
                        else
                        {
                            backDelegate = StopClientClbk;
                        }
                    }
                    else
                    {
                        if (conn.playerControllers[0].unetView.isClient)
                        {
                            backDelegate = StopHostClbk;
                        }
                        else
                        {
                            backDelegate = StopClientClbk;
                        }
                    }
                }
                else
                {
                    ChangeTo(mainMenuPanel);
                }

                topPanel.ToggleVisibility(true);
                topPanel.isInGame = false;
            }
            else
            {
                ChangeTo(null);

                Destroy(GameObject.Find("MainMenuUI(Clone)"));

                //backDelegate = StopGameClbk;
                topPanel.isInGame = true;
                topPanel.ToggleVisibility(false);
            }
        }

        public void ChangeTo(RectTransform newPanel)
        {
            if (currentPanel != null)
            {
                currentPanel.gameObject.SetActive(false);
            }

            if (newPanel != null)
            {
                newPanel.gameObject.SetActive(true);
            }

            currentPanel = newPanel;

            if (currentPanel != mainMenuPanel)
            {
                backButton.gameObject.SetActive(true);
            }
            else
            {
                backButton.gameObject.SetActive(false);
                SetServerInfo("Offline", "None");
                _isMatchmaking = false;
            }
        }

        public void DisplayIsConnecting()
        {
            var _this = this;
            infoPanel.Display("Connecting...", "Cancel", () => { _this.backDelegate(); });
        }

        public void SetServerInfo(string status, string host)
        {
            statusInfo.text = status;
            hostInfo.text = host;
        }


        public delegate void BackButtonDelegate();
        public BackButtonDelegate backDelegate;
        public void GoBackButton()
        {
            backDelegate();
            topPanel.isInGame = false;
        }

        // ----------------- Server management

        public void AddLocalPlayer()
        {
            TryToAddPlayer();
        }

        public void RemovePlayer(LobbyPlayer player)
        {
            player.RemovePlayer();
        }

        public void SimpleBackClbk()
        {
            ChangeTo(mainMenuPanel);
        }

        public void StopHostClbk()
        {
            if (_isMatchmaking)
            {
                matchMaker.DestroyMatch((NetworkID)_currentMatchID, 0, OnDestroyMatch);
                _disconnectServer = true;
            }
            else
            {
                StopHost();
            }


            ChangeTo(mainMenuPanel);
        }

        public void StopClientClbk()
        {
            StopClient();

            if (_isMatchmaking)
            {
                StopMatchMaker();
            }

            ChangeTo(mainMenuPanel);
        }

        public void StopServerClbk()
        {
            StopServer();
            ChangeTo(mainMenuPanel);
        }

        class KickMsg : MessageBase { }
        public void KickPlayer(NetworkConnection conn)
        {
            conn.Send(MsgKicked, new KickMsg());
        }




        public void KickedMessageHandler(NetworkMessage netMsg)
        {
            infoPanel.Display("Kicked by Server", "Close", null);
            netMsg.conn.Disconnect();
        }

        //===================

        public override void OnStartHost()
        {
            base.OnStartHost();

            ChangeTo(lobbyPanel);
            backDelegate = StopHostClbk;
            SetServerInfo("Hosting", networkAddress);
        }

        public override void OnMatchCreate(bool success, string extendedInfo, MatchInfo matchInfo)
        {
            base.OnMatchCreate(success, extendedInfo, matchInfo);
            _currentMatchID = (System.UInt64)matchInfo.networkId;
        }

        public override void OnDestroyMatch(bool success, string extendedInfo)
        {
            base.OnDestroyMatch(success, extendedInfo);
            if (_disconnectServer)
            {
                StopMatchMaker();
                StopHost();
            }
        }

        //allow to handle the (+) button to add/remove player
        public void OnPlayersNumberModified(int count)
        {
            _playerNumber += count;

            int localPlayerCount = 0;
            foreach (PlayerController p in ClientScene.localPlayers)
                localPlayerCount += (p == null || p.playerControllerId == -1) ? 0 : 1;

            addPlayerButton.SetActive(localPlayerCount < maxPlayersPerConnection && _playerNumber < maxPlayers);
        }

        // ----------------- Server callbacks ------------------

        //we want to disable the button JOIN if we don't have enough player
        //But OnLobbyClientConnect isn't called on hosting player. So we override the lobbyPlayer creation
        public override GameObject OnLobbyServerCreateLobbyPlayer(NetworkConnection conn, short playerControllerId)
        {
            GameObject obj = Instantiate(lobbyPlayerPrefab.gameObject) as GameObject;

            LobbyPlayer newPlayer = obj.GetComponent<LobbyPlayer>();
            newPlayer.ToggleJoinButton(numPlayers + 1 >= minPlayers);


            for (int i = 0; i < lobbySlots.Length; ++i)
            {
                LobbyPlayer p = lobbySlots *as LobbyPlayer;*

if (p != null)
{
p.RpcUpdateRemoveButton();
p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
}
}

return obj;
}

public override void OnLobbyServerPlayerRemoved(NetworkConnection conn, short playerControllerId)
{
for (int i = 0; i < lobbySlots.Length; ++i)
{
LobbyPlayer p = lobbySlots as LobbyPlayer;

if (p != null)
{
p.RpcUpdateRemoveButton();
p.ToggleJoinButton(numPlayers + 1 >= minPlayers);
}
}
}

public override void OnLobbyServerDisconnect(NetworkConnection conn)
{
for (int i = 0; i < lobbySlots.Length; ++i)
{
LobbyPlayer p = lobbySlots as LobbyPlayer;

if (p != null)
{
p.RpcUpdateRemoveButton();
p.ToggleJoinButton(numPlayers >= minPlayers);
}
}

}

public override bool OnLobbyServerSceneLoadedForPlayer(GameObject lobbyPlayer, GameObject gamePlayer)
{
//This hook allows you to apply state data from the lobby-player to the game-player
//just subclass “LobbyHook” and add it to the lobby object.

if (_lobbyHooks)
_lobbyHooks.OnLobbyServerSceneLoadedForPlayer(this, lobbyPlayer, gamePlayer);

return true;
}

// — Countdown management

public override void OnLobbyServerPlayersReady()
{
bool allready = true;
for (int i = 0; i < lobbySlots.Length; ++i)
{
if (lobbySlots != null)
allready &= lobbySlots*.readyToBegin;*
}

if (allready)
StartCoroutine(ServerCountdownCoroutine());
}

public IEnumerator ServerCountdownCoroutine()
{
float remainingTime = prematchCountdown;
int floorTime = Mathf.FloorToInt(remainingTime);

while (remainingTime > 0)
{
yield return null;

remainingTime -= Time.deltaTime;
int newFloorTime = Mathf.FloorToInt(remainingTime);

if (newFloorTime != floorTime)
{//to avoid flooding the network of message, we only send a notice to client when the number of plain seconds change.
floorTime = newFloorTime;

for (int i = 0; i < lobbySlots.Length; ++i)
{
if (lobbySlots != null)
{//there is maxPlayer slots, so some could be == null, need to test it before accessing!
(lobbySlots as LobbyPlayer).RpcUpdateCountdown(floorTime);
}
}
}
}

for (int i = 0; i < lobbySlots.Length; ++i)
{
if (lobbySlots != null)
{
(lobbySlots as LobbyPlayer).RpcUpdateCountdown(0);
}
}

ServerChangeScene(playScene);
}

// ----------------- Client callbacks ------------------

public override void OnClientConnect(NetworkConnection conn)
{
base.OnClientConnect(conn);

infoPanel.gameObject.SetActive(false);

conn.RegisterHandler(MsgKicked, KickedMessageHandler);

if (!NetworkServer.active)
{//only to do on pure client (not self hosting client)
ChangeTo(lobbyPanel);
backDelegate = StopClientClbk;
SetServerInfo(“Client”, networkAddress);
}
}

public override void OnClientDisconnect(NetworkConnection conn)
{
base.OnClientDisconnect(conn);
ChangeTo(mainMenuPanel);
}

public override void OnClientError(NetworkConnection conn, int errorCode)
{
ChangeTo(mainMenuPanel);
infoPanel.Display("Cient error : " + (errorCode == 6 ? “timeout” : errorCode.ToString()), “Close”, null);
}
}
}

OK SO. When you click the buttons it changes on that players version of the game the:
- game player prefab
- player prefab
but when players spawn in (after countdown and scene change)they all share the same prefab chosen by what I believe is the last player to join the lobby. It says they all have a different prefab before the scene loads but then they all share the same player prefab. The code works in the way that there can be more than 1 prefab but players cant chose a different one from each other…
(All players inherit the prefab of the host)
Any help would be nice !!!
THANKS IN ADVANCE

Hi, what does your lobby player script say? It looks like you’re always spawning the same “lobbyPlayerPrefab” at the host so are you somehow sending a CMD from your client to let the host know what to switch to?

Areleli