Unity provides an inbuilt network manager that is really good for small games and quick prototyping.It comes as an out if the box pluggable component that can be added to any game object in the scene and configured to an extent using the Unity UI itself. However, using this script “as is” does take away some of the flexibility that the Unity’s HLAPI is actually capable of. One such functionality is the ability to use different player prefabs for different players.

In this post, I will show you how you can use a custom network manager to control player spawning for different connections.

What are Player Objects ?

So, what are player Objects in UNET and how do they differ from other networked objects ?. Why can’t you spawn them just like other networked Objects using NetworkServer.Spawn ?.

Player objects are special in a sense because they are local to a single client connection. The NetworkBehavior class for player objects provides a variable isLocalPlayer that can be used to identify whether a player is local to the current game or not. This is important in a networked game because out of the many player instances only the local instance should accept inputs from the user. This is what makes the spawning process of a player object different. Here is a list of steps that take place when a player object is to be spawned for a connection

A client connects to the host

client calls the ClientScene.AddPlayer() or sends a network message of type MsgType.AddPlayer to the server

or sends a network message of type to the server Server receives the message and invokes OnServerAddPlayer() on the NetworkManager with the requesting client information

on the NetworkManager with the requesting client information The player game object is instantiated and is passed to NetworkServer.AddPlayerForConnection() along with the client information.

along with the client information. A network message of type MsgType.Owner is sent to the client that added the player (only that client!)

is sent to the client that added the player (only that client!) The above message when received by the client causes the isLocalPlayer to be set to true for that client’s game instance.

So that’s the theory behind the process. ready to experiment with it?

What will we be making

In this post, I will walk you through making a basic character selection scene. After connecting to the game the user will see three buttons letting him select from one of the three player classes. upon clicking a button a message would be sent to the server and the player will be spawned local to that connection

Preparing the scene

Create a new project in unity and

Add a new 3D plane to the scene at position (0,0,0) and with scale (10,1,10). This will be the plane our players will walk on.

Add a new button to the screen by right-clicking on the hierarchy pane -> UI -> Button. This will automatically create a canvas game object and add your button to it.

Duplicate the button 2 times and arrange all three buttons on the top right corner of the screen.

change the text displayed as well as the name of the buttons to “SpawnRedButton”, “SpawnBlueButton” and “SpawnRedButton” respectively.

your scene should look something like this

Creating the players and a basic player controller

create a new Capsule Game Object. This will be the base for our very basic, just for the sake of this tutorial players.

Create a cube game object inside the player game object positioned at (0,0.56,0.13) with scale (0.9,0.2,0.7) . This will act as a visor which will tell us the direction in which the player is facing.

with scale . This will act as a visor which will tell us the direction in which the player is facing. Next, Add a RigidBody Component and restrict the rotation in the x and y axes. This is to prevent our players from toppling over.

Finally, and a red colored material and your player should look something like this

Create a new script, name it as PlayerController and add the following code into it

pay attention to how we are making use of the isLocalPlayer variable to make sure only the local player would respond to keyboard input. If you run the game now you should be able to move your player on the plane using the WASD keys.

Since our players are networked objects and need to transmit their movements. we will also need to add the NetworkIdentity and the NetworkTransform components to them.

and the components to them. Finally, Create the other two player types with green and blue materials respectively and save all the three Game Objects as prefabs

our badass players

Writing the network logic

Now we can start writing the network logic.

To inform the server which player class to spawn, the client will need to send an extra message to the server along with the MsgType.AddPlayer message. Lest start by defining this message.

message. Lest start by defining this message. create a new script PlayerInfoMessage.cs and add the following code to it

Any message that needs to be sent over the network (Just like our message) needs to inherit from the MessageBase class.

After this, we can start writing the custom network Manager. The custom network manager will inherit from the base NetworkManager and override the OnServerAddPlayer allowing us to control player instantiation.

Create a new script customNetworkManager and add the following code to it

The OnServerAddPlayer instantiates a player object and calls the AddPlayerForConnection to make the player local to that connection It uses a NetworkReader to read the playerInfoMessage passed from the client and uses it to choose the Prefab to spawn.

To make this custom network manager active, attach the script to a game object. and assign the player prefabs to it from the Editor UI.

Also attach the NetworkHUD component to the same game object.

now that we have a network manager ready and capable to process spawn requests from the clients, let us write the code to send these requests.

Create a new script ButtonHandlers.cs and add the following code to it

A little explanation of the code — In the start method we add listeners for the three buttons created in the initial step. Each of these listeners define a PlayerInfoMessage with the required PlayerClass and pass it to the ClientScene.AddPlayer() call. Notice that the second argument to the call is always 0 . this is to make sure that only one player per client connection can be called. To spawn more players, this value should be incremented

After this, create a parent game object to the three spawn buttons and attach this script to it. Name this game object “SpawnButtons”.

Since the Listeners reference to NetworkClient.connection . we need to make sure that the client is indeed connected to a host before any of these buttons are clicked. else the connection object simply does not exist

. we need to make sure that the client is indeed connected to a host before any of these buttons are clicked. else the connection object simply does not exist To do this add the following code to the customNetworkManager class

The OnStartClient and OnStopClient methods are called on a client when the client is started and stopped respectively. we leverage these callbacks to show the UI when a connection is active and hide it when its now.

So that’s about it !. If you build the game now you can see it spawning players across the network.

Source Code

You can find the sample project for this post at https://github.com/pulkitjuneja/UNET-Multiple-Players