null reference exception

hi, i have a problem with my networking code, and im unable to solve it.
im getting this error:

NullReferenceException: Object reference not set to an instance of an object
MultiPlayerManager.Client_SpawnPlayer (NetworkPlayer player, Vector3 position, Quaternion rotation) (at Assets/Custom scripts/MultiPlayerManager.cs:184)
UnityEngine.NetworkView:RPC(String, RPCMode, Object[ ])
MultiPlayerManager:Server_SpawnPlayer(NetworkPlayer) (at Assets/Custom scripts/MultiPlayerManager.cs:177)
MultiPlayerManager:SpawnMenu() (at Assets/Custom scripts/MultiPlayerManager.cs:227)
MultiPlayerManager:OnGUI() (at Assets/Custom scripts/MultiPlayerManager.cs:167)

heres the multiplayer code:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MultiPlayerManager : MonoBehaviour 
{
	
	public static MultiPlayerManager instance;
	public GameObject PlayerManagerPrefab;
	public string PlayerName;
	
	private string MatchName = "";
	private string MatchPassword = "";
	private int MatchMaxUsers = 31;
	
	public List<MPPlayer> PlayerList = new List<MPPlayer>();
	public List<MapSetting> MapList = new List<MapSetting>();
	
	public MapSetting CurrentMap = null;
	public int oldprefix;
	public bool IsMatchStarted = false;

	//General Multiplayer Modes
	public bool MatchLoaded;
	public MPPlayer MyPlayer;
	public GameObject[] Spawnpoints;
	
	void Start()
	{
		instance = this;
		PlayerName = PlayerPrefs.GetString ("Player Name");
		CurrentMap = MapList[0];
		DontDestroyOnLoad (gameObject);
	}
	
	void FixedUpdate()
	{
		instance = this;
	}
	
	public void StartServer(string servername, string serverpassword, int maxusers)
	{
		MatchName = servername;
		MatchPassword = serverpassword;
		MatchMaxUsers = maxusers;
		
		Network.InitializeServer(maxusers, 25002, !Network.HavePublicAddress());
		MasterServer.RegisterHost ("Command and Vanquish", MatchName, "");
		Debug.Log("Master Server Info:" + MasterServer.ipAddress +":"+ MasterServer.port);
		Debug.Log("initializing server");
	}
	
	void OnServerInitalized()
	{
		Server_PlayerJoinRequest (PlayerName, Network.player);
		Debug.Log("Server initialized and ready");
	}
	
	void OnConnectedToServer()
	{
		networkView.RPC ("Server_PlayerJoinRequest", RPCMode.Server, PlayerName, Network.player); 
		Debug.Log("connected to Server");
	}
	
	void OnPlayerDisconnected(NetworkPlayer id)
	{
		networkView.RPC ("Client_RemovePlayer", RPCMode.All, id);
		Debug.Log("Player disconnected");
	}
	
	void OnPlayerConnected(NetworkPlayer player)
	{
		foreach (MPPlayer pl in PlayerList)
		{
			networkView.RPC("Client_AddPlayerToList", player, pl.PlayerName, pl.PlayerNetwork);
		}
		networkView.RPC("Client_GetMultiplayerMatchSettings", player, CurrentMap.MapName, "", "");
		Debug.Log("Player connected");
	}
	
	void OnDisconnectedFromServer()
	{
		PlayerList.Clear();
		Debug.Log("list cleared");
	}
	
	[RPC]
	void Server_PlayerJoinRequest(string playername, NetworkPlayer view)
	{
		networkView.RPC ("Client_AddPlayerToList", RPCMode.All, playername, view);
		Debug.Log("rpc server Player join request sent");
	}
	
	[RPC]
	void Client_AddPlayerToList(string playername, NetworkPlayer view)
	{
		MPPlayer tempplayer = new MPPlayer ();
		tempplayer.PlayerName = playername;
		tempplayer.PlayerNetwork = view;
		PlayerList.Add(tempplayer);
		Debug.Log("rpc client Player added to list");

		if (Network.player == view)
		{
			MyPlayer = tempplayer;
			GameObject play = Network.Instantiate(PlayerManagerPrefab, Vector3.zero, Quaternion.identity, 5)as GameObject;
			play.GetComponent<PlayerManager>().thisplayer = MyPlayer;
		}
	}
	
	[RPC]
	void Client_RemovePlayer(NetworkPlayer view)
	{
		MPPlayer temppl = null;
		
		foreach(MPPlayer pl in PlayerList)
		{
			
			if (pl.PlayerNetwork == view)
			{
				temppl = pl;
			}
			
		}
		
		if (temppl != null)
		{
			PlayerList.Remove(temppl);
		}
		Debug.Log("rpc client removed player");
		
	}
	
	[RPC]
	void Client_GetMultiplayerMatchSettings(string map, string mode, string others)
	{
		CurrentMap = GetMap (map);
		Debug.Log("rpc client multiplayer match settings gotten");
	}
	
	public MapSetting GetMap(string name)
	{
		MapSetting get = null;
		
		foreach (MapSetting st in MapList)
		{
			if (st.MapName == name)
			{
				get = st;
				break;
			}
		}
		return get;
	}
	
	[RPC]
	void Client_LoadMultiplayerMap(string map, int prefix)
	{
		//Network.SetLevelPrefix(prefix);
		Application.LoadLevel(map);
		Debug.Log("rpc client load multiplayer map working");
	}

	void OnGUI()
	{
		if (!MyPlayer.PlayerIsAlive  IsMatchStarted)
			SpawnMenu();

	}



	[RPC]
	void Server_SpawnPlayer(NetworkPlayer player)
	{
		int numberspawn = Random.Range(0, Spawnpoints.Length - 1);
		networkView.RPC("Client_SpawnPlayer", RPCMode.All, player, Spawnpoints[numberspawn].transform.position + new Vector3(0, 2, 0), Spawnpoints[numberspawn].transform.rotation);
	}

	[RPC]
	void Client_SpawnPlayer(NetworkPlayer player, Vector3 position, Quaternion rotation)
	{
		
		MultiPlayerManager.GetMPPlayer(player).PlayerIsAlive = true;
		MultiPlayerManager.GetMPPlayer(player).PlayerHealth = 100;
		if (player == MyPlayer.PlayerNetwork)
		{
			MyPlayer.PlayerManager.ControllerTransform.position = position;	
		    MyPlayer.PlayerManager.ControllerTransform.rotation = rotation;
			MyPlayer.PlayerManager.networkView.RPC("Client_PlayerAlive", RPCMode.All);
		}
		else
		{
			
		}
	}

	void OnLevelWasLoaded()
	{
		if (Application.loadedLevelName == CurrentMap.MapLoadName)
		{
			MatchLoaded = true;
			Spawnpoints = GameObject.FindGameObjectsWithTag("spawnpoint");	
			networkView.RPC("Client_ServerLoaded", RPCMode.AllBuffered, IsMatchStarted);
		}
	}

	public static MPPlayer GetMPPlayer(NetworkPlayer player)
	{
		foreach (MPPlayer play in MultiPlayerManager.instance.PlayerList)
		{
			if (play.PlayerNetwork == player)
			{
				return play;
			}
		}
		return null;
	}

	//Deathmatch
	void SpawnMenu()
	{
		if (GUI.Button(new Rect(5, Screen.height - 40, 250, 35), "Spawn"))
		{
			if(Network.isServer)
			{
				Server_SpawnPlayer(Network.player);
			}

			else
			{
				networkView.RPC("Server_SpawnPlayer", RPCMode.Server, Network.player);
			}
		}
	}

}



[System.Serializable]
public class MPPlayer
{
	public string PlayerName = "";
	public NetworkPlayer PlayerNetwork;
	public PlayerManager PlayerManager;
	public int PlayerHealth = 100;
	public bool PlayerIsAlive;
	public int PlayerScore;
	public int PlayerKills;
	public int PlayerDeahts;
}



[System.Serializable]
public class MapSetting
{
	public string MapName;
	public string MapLoadName;
	public Texture MapLoadTexture;	

}

and the playermanager code:

using UnityEngine;
using System.Collections;

public class PlayerManager : MonoBehaviour 
{
	public MPPlayer thisplayer;

	public PlayerController Controller;
	public Transform ControllerTransform;

	public GameObject OutsideView;

	public Transform CurrentPosition;
	public Quaternion CurrentRotation;


	void Start()
	{
		ControllerTransform.gameObject.SetActive(false);
		thisplayer.PlayerManager = this;
		thisplayer = MultiPlayerManager.GetMPPlayer(networkView.owner);
		OutsideView.SetActive (false);
	}

	void FixedUpdate ()
	{
		if(networkView.isMine)
		{
			
			CurrentPosition.position = ControllerTransform.position;
			CurrentRotation = ControllerTransform.rotation;
		}
		else
		{
			OutsideView.transform.position = CurrentPosition.position + new Vector3(0,-1f,0);
			OutsideView.transform.rotation = CurrentRotation;
		}
	}
	
	void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
	{
		Vector3 position = CurrentPosition.position;


		if (stream.isWriting)
		{
			stream.Serialize(ref position);
			stream.Serialize(ref CurrentRotation);
		}
		else
		{
			stream.Serialize(ref position);
			stream.Serialize(ref CurrentRotation);
		}  
	}
	void HandleBulletDamage (int damage)
	{
		if (Network.isServer)
		{
		Server_HandleBulletDamage (damage);
		}
		else
		{
		networkView.RPC ("HandleBulletDamage", RPCMode.Server, damage);
		}
	}
	[RPC]
	public void Server_HandleBulletDamage (int damage)
	{
		thisplayer.PlayerHealth -= damage;

		if(thisplayer.PlayerHealth <= 0)
		{
			thisplayer.PlayerIsAlive = false;
			thisplayer.PlayerHealth = 0;
			networkView.RPC ("Client_PlayerDead", RPCMode.All);
		}

		else
		{

		}
	}

	[RPC]
	public void Client_PlayerDead()
	{
		OutsideView.SetActive(false);
		if (networkView.isMine)
	    {
			
			ControllerTransform.gameObject.SetActive(false);
		}
	}

	[RPC]
	public void Client_PlayerAlive()
	{
		if (networkView.isMine)
		{
			ControllerTransform.gameObject.SetActive(true);
		}

		else
		{
		    OutsideView.SetActive(true);
		}
	}
}

so far im not sure whats causing this, im having the problem that my name doesnt appear on the playerlist though if im the guy hosting. id really like to hear what you guys think as ive been on this issue for several hours, without success.

From the looks of the error, I’d guess that “player” is null in this code (where I added the comment):

        [RPC]
        void Client_SpawnPlayer(NetworkPlayer player, Vector3 position, Quaternion rotation)
        {
           
            MultiPlayerManager.GetMPPlayer(player).PlayerIsAlive = true;  // <-- is player null here?
            MultiPlayerManager.GetMPPlayer(player).PlayerHealth = 100;
            if (player == MyPlayer.PlayerNetwork)
            {
                MyPlayer.PlayerManager.ControllerTransform.position = position; 
                MyPlayer.PlayerManager.ControllerTransform.rotation = rotation;
                MyPlayer.PlayerManager.networkView.RPC("Client_PlayerAlive", RPCMode.All);
            }
            else
            {
               
            }
        }

Some Debug.Log messages there would probably be helpful. That, and you really should be checking objects for null prior to blindly accessing them.

Jeff

thanks for your answer jeff. if i delete line 5 and 6 however, it points me to the myplayer. lines inside the if statement. a friend of mine says its a networking issue, and points out that myplayer is set to null by default, im not sure though.

Bottom line, you’re going to have to figure out what is null in that method and then figure out why. I’d definitely start by adding a block of Debug.Log statements at the top of the method to figure out the what. Then start looking for the why.

Jeff

player might be null (doubtful since it’s coming through via RPC) or player might not be in the list of players in which case your GetMPPlayer method will return null and throw a null reference exception on PlayerIsAlive. It also seems odd to me to put a static method onto a singleton like that - but that just might be me.

yeah my thought exactly, kelso, though i wrote that code a while ago so ill have to look at it tomorrow. it stroke me as odd too that i cant see my own name on the list.

ive been doing some debugging, and it seems i get some unreachable code warnings when i deal with this:

public static MPPlayer GetMPPlayer(NetworkPlayer player)
	{
		Debug.Log ("static mpplayer working");
		foreach (MPPlayer play in MultiPlayerManager.instance.PlayerList)
		{

			if (play.PlayerNetwork == player)
			{
				return play;
			}
		}
		return null;
	}

if i want to debug the lines inside for each it becomes unreachable.

Anything after the if but inside the foreach would be unreachable. Just put it before the if.

tried it, it doesnt show up even when put before the if statement.

That means your list is empty. And therefore your method returns null :slight_smile:

another thing i noticed: it takes a long time to connect to a host. just when the client connects to the game, you see your name (in green) for a split second… im confused. ill test the getMpplayer again just to be sure, but even if the list is empty… how am i supposed to fill it ? why would it be empty in the first place ?

is this a connection issue , or a method issue ? if its the first then i have no clue how to deal with it, but if its a method ive got to dig deeper. the code was nearly not explained at all in the tutorial so this might take a bit.

yesterday i tested the networking with a buddy i could connect to easily before implementing the spawn system. now its impossible to connect to him… can this be tied to the spawn system ? if so how is this even possible to break connection with something like this ?

yep, the

foreach (MPPlayer play in MultiPlayerManager.instance.PlayerList)

is not returning the debug log, so the list really is empty just like you said ! that is, only if i as a server, am trying to spawn in the game im hosting, then it returns to zero. it seems the player hosting it is just not on the list.

the foreach statement is working if i connect to the build that hosts the game , it returns the log, but it doesnt spawn at all. i cklick on the button and nothing happens, it stays in the spawn menu ( the background image and buttons are still from the lobby menu, but youre actually in the spawn menu, hence you see the spawnn button, but for some reason it doesnt switch properly.

since the foreach works, the issue might be on the map (wrongly configured spawnpoint objects)
or in the spawnbutton function.

ill check that and keep you guys updated.

alright, narrowed it even more. added a bunch of debug.logs to the code so it looks like this now:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MultiPlayerManager : MonoBehaviour 
{
	
	public static MultiPlayerManager instance;
	public GameObject PlayerManagerPrefab;
	public string PlayerName;
	
	private string MatchName = "";
	private string MatchPassword = "";
	private int MatchMaxUsers = 31;
	
	public List<MPPlayer> PlayerList = new List<MPPlayer>();
	public List<MapSetting> MapList = new List<MapSetting>();
	
	public MapSetting CurrentMap = null;
	public int oldprefix;
	public bool IsMatchStarted = false;

	//General Multiplayer Modes
	public bool MatchLoaded;
	public MPPlayer MyPlayer;
	public GameObject[] Spawnpoints;
	
	void Start()
	{
		instance = this;
		PlayerName = PlayerPrefs.GetString ("Player Name");
		CurrentMap = MapList[0];
		DontDestroyOnLoad (gameObject);
	}
	
	void FixedUpdate()
	{
		instance = this;
	}
	
	public void StartServer(string servername, string serverpassword, int maxusers)
	{
		MatchName = servername;
		MatchPassword = serverpassword;
		MatchMaxUsers = maxusers;
		
		Network.InitializeServer(maxusers, 25002, !Network.HavePublicAddress());
		MasterServer.RegisterHost ("Command and Vanquish", MatchName, "");
		Debug.Log("Master Server Info:" + MasterServer.ipAddress +":"+ MasterServer.port);
		Debug.Log("initializing server");
	}
	
	void OnServerInitalized()
	{
		Server_PlayerJoinRequest (PlayerName, Network.player);
		Debug.Log("Server initialized ");
	}
	
	void OnConnectedToServer()
	{
		networkView.RPC ("Server_PlayerJoinRequest", RPCMode.Server, PlayerName, Network.player); 
		Debug.Log("OnConnectedToServer(), Server_PlayerJoinRequest called");
	}
	
	void OnPlayerDisconnected(NetworkPlayer id)
	{
		networkView.RPC ("Client_RemovePlayer", RPCMode.All, id);
		Debug.Log("Player disconnected, Client_RemovePlayer called");
	}
	
	void OnPlayerConnected(NetworkPlayer player)
	{
		foreach (MPPlayer pl in PlayerList)
		{
			networkView.RPC("Client_AddPlayerToList", player, pl.PlayerName, pl.PlayerNetwork);
			Debug.Log("foreach (MPPlayer pl in PlayerList),Client_AddPlayerToList called ");
		}
		networkView.RPC("Client_GetMultiplayerMatchSettings", player, CurrentMap.MapName, "", "");
		Debug.Log("Player connected");
	}
	
	void OnDisconnectedFromServer()
	{
		PlayerList.Clear();
		Debug.Log("OnDisconnectedFromServer() list cleared");
	}
	
	[RPC]
	void Server_PlayerJoinRequest(string playername, NetworkPlayer view)
	{
		networkView.RPC ("Client_AddPlayerToList", RPCMode.All, playername, view);
		Debug.Log("rpc Server_PlayerJoinRequest sent");
	}
	
	[RPC]
	void Client_AddPlayerToList(string playername, NetworkPlayer view)
	{
		MPPlayer tempplayer = new MPPlayer ();
		tempplayer.PlayerName = playername;
		tempplayer.PlayerNetwork = view;
		PlayerList.Add(tempplayer);
		Debug.Log("rpc Client_AddPlayerToList working");

		if (Network.player == view)
		{
			MyPlayer = tempplayer;
			GameObject play = Network.Instantiate(PlayerManagerPrefab, Vector3.zero, Quaternion.identity, 5)as GameObject;
			play.GetComponent<PlayerManager>().thisplayer = MyPlayer;
		}
	}
	
	[RPC]
	void Client_RemovePlayer(NetworkPlayer view)
	{
		MPPlayer temppl = null;
		
		foreach(MPPlayer pl in PlayerList)
		{
			
			if (pl.PlayerNetwork == view)
			{
				temppl = pl;
			}
			
		}
		
		if (temppl != null)
		{
			PlayerList.Remove(temppl);
		}
		Debug.Log("rpc Client_RemovePlayer(NetworkPlayer view) working");
		
	}
	
	[RPC]
	void Client_GetMultiplayerMatchSettings(string map, string mode, string others)
	{
		CurrentMap = GetMap (map);
		Debug.Log("rpc Client_GetMultiplayerMatchSettings(string map, string mode, string others) gotten");
	}
	
	public MapSetting GetMap(string name)
	{
		MapSetting get = null;
		
		foreach (MapSetting st in MapList)
		{
			if (st.MapName == name)
			{
				get = st;
				break;
			}
		}
		return get;
	}
	
	[RPC]
	void Client_LoadMultiplayerMap(string map, int prefix)
	{
		//Network.SetLevelPrefix(prefix);
		Application.LoadLevel(map);
		Debug.Log("rpc Client_LoadMultiplayerMap(string map, int prefix) map working");
	}

	void OnGUI()
	{
		if (!MyPlayer.PlayerIsAlive  IsMatchStarted)
			SpawnMenu();

	}



	[RPC]
	void Server_SpawnPlayer(NetworkPlayer player)
	{
		Debug.Log ("Server_SpawnPlayer function found");
		int numberspawn = Random.Range(0, Spawnpoints.Length - 1);
		Debug.Log ("Server_SpawnPlayer function int numberspawn working");
		networkView.RPC("Client_SpawnPlayer", RPCMode.All, player, Spawnpoints[numberspawn].transform.position, Spawnpoints[numberspawn].transform.rotation);
		Debug.Log ("Server_SpawnPlayer function,Client_SpawnPlayer function is called");
	}

	[RPC]
	void Client_SpawnPlayer(NetworkPlayer player, Vector3 position, Quaternion rotation)
	{
		Debug.Log ("client_SpawnPlayer function found");
		MultiPlayerManager.GetMPPlayer(player).PlayerIsAlive = true;
		MultiPlayerManager.GetMPPlayer(player).PlayerHealth = 100;
		if (player == MyPlayer.PlayerNetwork)
		{
			Debug.Log ("client_SpawnPlayer myplayer.playernetwork called");
			MyPlayer.PlayerManager.ControllerTransform.position = position;
			Debug.Log ("client_SpawnPlayer myplayer.playernetwork controllertransform position got");
			MyPlayer.PlayerManager.ControllerTransform.rotation = rotation;
			Debug.Log ("client_SpawnPlayer myplayer.playernetwork controllertransform rotation got");
			MyPlayer.PlayerManager.networkView.RPC("Client_PlayerAlive", RPCMode.All);	
			Debug.Log ("client_SpawnPlayer myplayer.playernetwork client_PlayerAlive called");
		}
		else
		{
			
		}
	}

	void OnLevelWasLoaded()
	{
		if (Application.loadedLevelName == CurrentMap.MapLoadName)
		{
			MatchLoaded = true;
			Spawnpoints = GameObject.FindGameObjectsWithTag("spawnpoint");	
			networkView.RPC("Client_ServerLoaded", RPCMode.AllBuffered, IsMatchStarted);
		}
	}

	[RPC]
	void Client_ServerLoaded(bool started)//Add parameter for boolean IsMatchStarted
	{
		MatchLoaded = true;
		IsMatchStarted = started;
	}

	public static MPPlayer GetMPPlayer(NetworkPlayer player)
	{
		Debug.Log ("static mpplayer working");
		foreach (MPPlayer play in MultiPlayerManager.instance.PlayerList)
		{
			Debug.Log ("foreach mpplayer play in multiplayermanager working");
			if (play.PlayerNetwork == player)
			{
				return play;
			}
		}
		return null;
	}

	//Deathmatch
	void SpawnMenu()
	{
		if (GUI.Button(new Rect(5, Screen.height - 40, 250, 35), "Spawn"))
		{
			Debug.Log ("spawn button pressed");
			if(Network.isServer)
			{
				Server_SpawnPlayer(Network.player);
				Debug.Log ("Network.isServer, Server_SpawnPlayer(Network.player) in spawnmenu called");
			}

			else
			{
				networkView.RPC("Server_SpawnPlayer", RPCMode.Server, Network.player);
				Debug.Log ("non server client, Server_SpawnPlayer called");
			}
		}
	}

}



[System.Serializable]
public class MPPlayer
{
	public string PlayerName = "";
	public NetworkPlayer PlayerNetwork;
	public PlayerManager PlayerManager;
	public int PlayerHealth = 100;
	public bool PlayerIsAlive;
	public int PlayerScore;
	public int PlayerKills;
	public int PlayerDeahts;
}



[System.Serializable]
public class MapSetting
{
	public string MapName;
	public string MapLoadName;
	public Texture MapLoadTexture;	

}

and here the log in the console:

another weird thing : when pressing the connect button to connect to the server, im only entering the lobby if i switch between the two build windows (editor / playable build ) im not sure why. otherwise id be stuck in the server browser. my name appears on the player list only if i switch between the two windows too. im not sure whats causing this.

alright, this has been finally solved, the playermanager prefab was set to inactive by default, hence giving null reference.

just by ticking the active box in the editor made the whole thing work just fine.