- Home /
Don't destroy player after disconnecting or calling ClientScene.RemovePlayer()
I have the following scenario: In my game there are 4 players, one of them is controlled by the host the other 3 are controlled by the AI, located on the server. When another client connects, one of the AI controlled players will then be controlled by the new client. This works so far using the following code:
public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
//base.OnServerAddPlayer(conn, playerControllerId);
for (int i = 0; i < 4; i++)
{
if (allPlayers[i].clientAuthorityOwner == null)
{
NetworkIdentity player = allPlayers[i];
NetworkServer.AddPlayerForConnection(conn, player.gameObject, playerControllerId);
player.AssignClientAuthority(conn);
return;
}
}
}
However the problem appears when the client disconnects again or ClientScene.RemovePlayer() is called. Since his player has client authority the player will be destroyed. However, this is not what I want. Instead the AI should take over the player again in order to keep exactly 4 players.
Overriding NetworkManager.OnServerDisconnect() prevents desotroying the player when the client disconnects, but not if ClientScene.RemovePlayer() is called on the client:
public override void OnServerDisconnect(NetworkConnection conn)
{
//base.OnServerDisconnect(conn);
}
I have already found this in the documentation but I have no clue how to disable it:
http://docs.unity3d.com/ScriptReference/Networking.NetworkServer.DestroyPlayersForConnection.html
Just to make it clear: A client should be able to control multiple players. I plan to make a game that supports both split screen and lan multiplayer at the same time. If one of the split screen players leaves again, ClientScene.RemovePlayer() has to be called to give control back to the server.
Answer by jayl · Jun 28, 2016 at 04:38 PM
I have found a working solution by overriding the NetworkManager.OnServerRemovePlayer() Method:
public override void OnServerRemovePlayer(NetworkConnection conn, PlayerController player)
{
GameObject newPlayer = Instantiate(playerPrefab);
NetworkServer.Spawn(newPlayer);
for (int i = 0; i < 4; i++)
{
if(allPlayers[i] == player.unetView)
{
allPlayers[i] = newPlayer.GetComponent<NetworkIdentity>();
break;
}
}
base.OnServerRemovePlayer(conn, player);
}
However, I do not really like this approach since the player has to be destroyed and recreated instead of just changing some authority stuff (or whatever). Therefore I will not mark this as the correct answer.
I hope someone knows a better approach.