How to spawn multiple prefabs at the same time through Network Manager?

I know that you can spawn a player prefab by giving a prefab in the Inspector shown above. Is it possible to increase the number of prefabs (prefabs that are all different from each other) here, so you spawn multiple player prefabs instead?

Use case: A level where the player controls 3 different units at the start in Scenario Campaign.

Or the Inspector is hinting me to use this?

Then again, I’m not sure if there are any video tutorials covering the Registered Spawnable Prefabs and how this is used…

I am also working on a game which players may have multiple characters, and I’m still looking for an easy way to do that.

First, about registerd prefabs:
Registered spawnable prefabs shows the objects that can be spawned through the network, if a prefab is not registered, NetworkServer.Spawn(obj) will not work.

To register a prefab you can do it at runtime, just use ClientScene.RegisterPrefab

And second, about multiple characters…

Yesterday I tried using an empty game object with ‘GameController’ component as player prefab and to do the controlling and synchronizing jobs with my GameController based on network message system.

Now I can spawn multiple controllable objects for a client, but it seems that I have to rewrite all the functions that UNET has already given just because the built-in ones have some creepy limitations like ‘non-localplayer is not able to send Command’, ‘networkConnection cannot be sent via Command’ and so on.

hope it helps and still waiting for further solution

Please see my reply.

I tried a simple way, and it worked.
you can just play with ClientScene.AddPlayer, then all the objects added are all set local.

if you’d like you can have a look at my code.

public class MyNetworkManager : NetworkManager {

    [SerializeField]
    GameObject[] playerCharacterPrefabs;

    short playerControllerHighestId = 0;

    void OnGUI()
    {
        if(GUI.Button(new Rect(10, Screen.height - 60, 400, 50), "spawn a new character of mine"))
        {
            // pay attention here !!
            ClientScene.AddPlayer(client.connection, playerControllerHighestId++);
        }
    }

    public override void OnStartClient (NetworkClient client)
    {
        base.OnStartClient (client);

        // always remember to register prefabs before spawning them.
        foreach(GameObject go in playerCharacterPrefabs)
            ClientScene.RegisterPrefab(go);

        Debug.Log("Connect to a new game");

    }

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

    public override void OnServerAddPlayer (NetworkConnection conn, short playerControllerId)
    {
        GameObject newPlayer = GameObject.Instantiate(playerCharacterPrefabs[playerControllerId%2]);
        newPlayer.transform.position = Vector3.zero + Vector3.right * playerControllerId;
        NetworkServer.Spawn(newPlayer);

        // object spawned via this function will be a local player
        // which belongs to the client connection who called the ClientScene.AddPlayer
        NetworkServer.AddPlayerForConnection(conn, newPlayer, playerControllerId);
    }

}

OH! That how you make the units spawn in a network game and make the client have authority over the spawned units, or it seems like it.

For the OnServerAddPlayer(), why do we need to set the transform/position first before we spawn through NetworkServer?

yes, one client can have many ‘localPlayered’ objects if you create them like that

as for setting the position… my habit :> never mind

Ah, okay. Thanks a ton!

Hope I’m not too late to this party, but I’ve been trying to do the same thing and Stormouse’s code (above) does not compile correctly for me. Specifically, I get these errors:

Line 13: “client.connection” is highlighted as bad code; MonoDevelop says: “The name ‘client’ does not exist in the current context.” (Yes, I have using UnityEngine.Networking at the top.)

Lines 19 & 31: these give me errors unless I delete “base.” from the beginning of the line.

Any help? Thanks.

I should also say that all the “override” methods trigger this error:

‘MyNetworkManager.OnStartClient(UnityEngine.Networking.NetworkClient)’ is marked as an override but no suitable method found to override

Thanks Glabrezu. My code begins (after the “using . . .” declarations, of course) with “public class MyNetworkManager : NetworkManager”. Am I still missing something?

using UnityEngine.Networking?

Yup, I have that too. Here’s the whole thing:

using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class MyNetworkManager : NetworkManager {
  
    [SerializeField] GameObject[] playerCharacterPrefabs;
  
    short playerControllerHighestId = 0;
  
    void OnGUI()
    {
        if(GUI.Button(new Rect(10, Screen.height - 60, 400, 50), "spawn a new character of mine"))
        {
            // pay attention here !!
            ClientScene.AddPlayer(client.connection, playerControllerHighestId++);
        }
    }
  
    public override void OnStartClient (NetworkClient client)
    {
        base.OnStartClient (client);
      
        // always remember to register prefabs before spawning them.
        foreach(GameObject go in playerCharacterPrefabs)
            ClientScene.RegisterPrefab(go);
      
        Debug.Log("Connect to a new game");
      
    }
  
    public override void OnClientConnect (NetworkConnection conn)
    {
        base.OnClientConnect (conn);
    }
  
    public override void OnServerAddPlayer (NetworkConnection conn, short playerControllerId)
    {
        GameObject newPlayer = GameObject.Instantiate(playerCharacterPrefabs[playerControllerId%2]);
        newPlayer.transform.position = Vector3.zero + Vector3.right * playerControllerId;
        NetworkServer.Spawn(newPlayer);
      
        // object spawned via this function will be a local player
        // which belongs to the client connection who called the ClientScene.AddPlayer
        NetworkServer.AddPlayerForConnection(conn, newPlayer, playerControllerId);
    }
  
}

Here are the errors:

client.connection in Line 16 gives me “the name ‘client’ does not exist in the current context.”

OnStartClient in Line 22 gives me “‘Network Manager’ does not contain a definition for ‘OnStartClient.’”

OnClientConnect in Line 34 gives me “‘Network Manager’ does not contain a definition for ‘OnClientConnect.’”

(Note that for lines 22 & 34, I can get rid of the error by deleting “base.”)

Finally, for all the override functions, I get “`MyNetworkManager.OnStartClient(UnityEngine.Networking.NetworkClient)’ is marked as an override but no suitable method found to override”.

Any help is greatly appreciated.

I feel like you need to look up how the class is used, rather than use the already-incomplete class code provided. The code provided was merely a pseudo-code and not the full script.

Line 16: Think about this: What is the “client” variable? And where is it declared?
Line 22 & 34: You need to use your own implementation of the OnStartClient() and OnClientConnect(). They are virtual functions.