Search code examples
c#unity-game-enginemultiplayer

Unity | NullReferenceException when trying to spawn player with client authority


I am creating a multiplayer game and trying to spawn my player prefab with client authority so each player can be controlled by its respective user.

My workflow is as follows: 1) Host starts, their PlayerUnit is spawned. 2) Client connects, their PlayerUnit is spawned. 3) Game starts, the PlayerUnits spawn the respective PlayerCharacters (This is where the problem is).

I can spawn in the player's fine using NetworkServer.Spawn(player);, however, this allows the host to control all the PlayerCharacters. Therefore, to my understanding, the PlayerCharacters must be spawned with client authority so only the correct user can control them. However, when I spawn the PlayerCharacter in with NetworkServer.SpawnWithClientAuthority(player, connectionToClient);I get the following errors:

NullReferenceException: Object reference not set to an instance of an object
UnityEngine.Networking.NetworkServer.SpawnWithClientAuthority (UnityEngine.GameObject obj, UnityEngine.Networking.NetworkConnection conn) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1565)

SpawnWithClientAuthority NetworkConnection is not ready!
UnityEngine.Networking.NetworkServer:SpawnWithClientAuthority(GameObject, NetworkConnection)

And the host can still control both the player characters.

This is my code for spawning the PlayerUnit (in my CustomNetworkManager):

public override void OnServerAddPlayer(NetworkConnection conn, short playerControllerId)
{
    var player = Instantiate(playerPrefab);
    NetworkServer.AddPlayerForConnection(conn, player, playerControllerId); 
}

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

This is the code for spawning the PlayerCharacter (attached to the PlayerUnit):

[Command]
public void CmdSpawnPlayer(int playerCount)
{
    CustomNetworkHUD.playerCount++;
    var players = new GameObject[] { redPlayer, bluePlayer, greenPlayer, yellowPlayer };
    var player = Instantiate(players[playerCount - 1]);
    player.SetActive(true);
    ClientScene.RegisterPrefab(player);
    NetworkServer.Spawn(player); // No errors, but not desired behaviour
    //NetworkServer.SpawnWithClientAuthority(player, connectionToClient);  
}

Sorry if the problem is very obvious, this is my first time networking with Unity.


Solution

  • This was the solution:

    The problem was in passing the connection between the PlayerUnit and the PlayerCharacters.

    By using NetworkServer.ReplacePlayerForConnection(connectionToClient, player, connectionID); I gave the PlayerCharacter the connection which the PlayerUnit previously owned.

    This is at least my understanding.

    https://docs.unity3d.com/2017.1/Documentation/ScriptReference/Networking.NetworkServer.ReplacePlayerForConnection.html