So I am using the Network Lobby example from the asset store (Unity Asset Store - The Best Assets for Game Making) to make my game multiplayer. It consists of different mini-games, so there’s a scene and player prefab for each one. The first time it loads the scene I established as the play scene on the inspector, it creates a game player prefab for each player. The thing is that at end of that game/scene i call ServerChangeScene() to go to the next mini-game, but when the scene is loaded it doesn’t create the players.
As user @seanr says in this thread: [Solved] Server not adding player for reconnecting client the auto creation occurs when OnClientSceneChanged and OnClientConnect are called, so I don’t know what is going on. Am I missing something? Thanks in advance!
Ok so I solved it. As I couldn’t find any answer on the internet, I decided to take a look on the source code of the NetworkLobbyManager class (here’s the link: https://bitbucket.org/Unity-Technologies/networking/src/78ca8544bbf4e87c310ce2a9a3fc33cdad2f9bb1/Runtime/NetworkLobbyManager.cs?at=5.3&fileviewer=file-view-default ). I discovered OnServerSceneChanged calls for each player the function SceneLoadedForPlayer, where players are actually created. The thing is that after that, the list of players (stored in var m_PendingPlayers) is cleared, so when the scene is changed again and those function are called again, there are no players to iterate. Here is the code:
public override void OnServerSceneChanged(string sceneName)
{
if (sceneName != m_LobbyScene)
{
// call SceneLoadedForPlayer on any players that become ready while we were loading the scene.
foreach (var pending in m_PendingPlayers)
{
SceneLoadedForPlayer(pending.conn, pending.lobbyPlayer);
}
m_PendingPlayers.Clear();
}
OnLobbyServerSceneChanged(sceneName);
}
So I just had to override the function so it could create every time the players. Here’s what I did:
public override void OnServerSceneChanged(string sceneName)
{
foreach (var lobbys in lobbySlots) {
if (lobbys == null) continue;
var controllerId = lobbys.GetComponent().playerControllerId;
Transform startPos = GetStartPosition();
GameObject gamePlayer;
if (startPos != null)
{
gamePlayer = (GameObject)Instantiate(gamePlayerPrefab, startPos.position, startPos.rotation);
}
else
{
gamePlayer = (GameObject)Instantiate(gamePlayerPrefab, Vector3.zero, Quaternion.identity);
}
OnLobbyServerSceneLoadedForPlayer (lobbys.gameObject, gamePlayer);
NetworkServer.ReplacePlayerForConnection(lobbys.GetComponent().connectionToClient, gamePlayer, controllerId);
}
}
Sorry to bother you but this is the exact issue I am currently facing. I have looked extensively for the answer. I have multiple levels and want to change the spawned player prefab when calling OnServerChangeScene.
Where are you placing this overrided function. Is it in the LobbyManager class. I placed it here and the players don’t spawn at all anymore.
Is there other changes I was meant to make to now make the players spawn?
Again apologies for bringing up a dead thread. Thanks in advance.
I was working on auto-connect players, in kind of ClashRoyale matchmaking, and I had same problem. There is a simple solution.
If there is no lobbys in lobbySlots try giving
DontDestroyOnLoad(this);
to your
CustomLobbyPlayerScript : NetworkLobbyPlayer.
Worked for me. I hope I helped.
e.g.
public class MyLobbyPlayer : NetworkLobbyPlayer {
void Start () {
DontDestroyOnLoad(this);
if (isLocalPlayer)
SendReadyToBeginMessage();
}
}
PS. Yes.
public override void OnServerSceneChanged(string sceneName) should be in NetworkLobbyManager class.
is the Network Lobby Manager different from Lobby Manager???
As the asset only has the Lobby Manager
as you can see for yourself in the source code, networklobbymanager inherits from lobbymanager, and therefor has the same functionality as networkmanager plus ontop its own functionality