Spawning a new player instance (UNET)

I’m playing around with the new networking system, and I can’t seem to figure out how to spawn a new player instance.

When a player reaches 0 health (or less), I execute the following code on the player GameObject:

NetworkServer.Destroy(gameObject);

// UPDATE: I think I should be using ReplacePlayerForConnection, so added this in code below

After this, I show the respawn GUI (which is just a button right now). When you click the button, it should create a new instance of the player prefab. I tried implementing it like this:

GameObject player = Instantiate<GameObject>(playerPrefab);
NetworkServer.Spawn(player);
NetworkServer.ReplacePlayerForConnection(NetworkManager.singleton.client.connection, player, NetworkManager.singleton.client.connection.playerControllers[0].playerControllerId);

But when I check the GameObject, its isLocalPlayer property isn’t true.

I’m not sure about the parameters of ReplacePlayerForConnection. It looks like this should be possible a lot easier than this…

All the UNET examples don’t destroy the GameObject, but just hide it. However, I want the player to be able to choose between different prefabs I created in the project (e.g. sniper, warrior, scout, whatever…), so that’s not an option.

Other stuff I tried adding:

NetworkClient.connection.playerControllers[0].gameObject = player; // get the local clients connection, get the first playerController (which is the only one) and assign the new player gameobject as its gameobject.

Which doesn’t work.

Anyone having any luck with this?

I think you need to invoke the replacement on the server using a [Command]

[Command]
void CmdReplaceMe(GameObject newPlayerObject)
{
   NetworkServer.Spawn(newPlayerObject);
   NetworkServer.ReplacePlayerForConnection(connectionToClient, newPlayerObject, playerControllerId);

}

Or something similar ( I still just experimenting myself tbh)

hope that helps :slight_smile:

What’s about destroying and recreating the player? I mean when the health drops to 0 on the server, call

NetworkServer.Destroy(player);

which will destroy the specified game object. If you know the NetworkConnection, you can query the corresponding player object if you didnt store it.

NetworkPlayer player;
if (conn.GetPlayer(playerControllerId, out player))
{
    if (player.NetworkIdentity != null && player.NetworkIdentity.gameObject != null)
        NetworkServer.Destroy(player.NetworkIdentity.gameObject);
}

If you have only one player object for each client, then you can call

NetworkServer.DestroyPlayersForConnection(connection);

When you press the respawn button on the client, call the

ClientScene.AddPlayer(0);

which will ask the server to spawn the specified player prefab.

At the bottom of this page, you can find some code which could help you.

Edit:
I just read that you’d like to spawn other object. Well… AFAIK you can have more player for each connection so you could do the following:

  1. Spawn a “Connection” player which doesn’t change
  2. The Connection object can be used to communicate with the server
  3. When the Client press the Respawn button, a message (Command) is sent to the server which would setup which object you want to spawn (sniper, warrior, etc.) using the Connection object.
  4. At the Server-side, you store the prefab for playerControllerId 1
  5. The client sends the add player request for id 1, by calling ClientScene.AddPlayer(1)
  6. In the Server, if you’re using the NetworkManager, you can override the OnServerAddPlayer function
  7. Here you can check if the playerControllerId is 1, you spawn the stored prefab object.

Or something like this…

try NetworkServer.ReplacePlayerForConnection()