PlayerNode / Playerlist not populating

So i looked into the tutorials and examples and found the GameSetup Script and Scoreboard system and attempted to implement them into my game. However i don't think the playerlist is populating correctly here is my trimmed down code for my scoreboard;

[code2=csharp]public class ScoreBoard : Photon.MonoBehaviour
{

public static ScoreBoard SP;
public GUISkin skin;

//static string newRecordMessage = "";

private GUIText highscoreText;


private string scoreText = "Loading scores";

private int scoreBoardHeight = 60;
private GameSetup gameSetupScript;

void Awake()
{
SP = this;
gameSetupScript = GetComponent<GameSetup>() as GameSetup;

highscoreText = GetComponent<GUIText>() as GUIText;
highscoreText.enabled = false;
}

void OnGUI()
{
GUI.skin = skin;

scoreText = "Scoreboard:\n";

foreach (FPSPlayerNode entry in gameSetupScript.playerList)
{
scoreText += entry.playerName + " \t" + entry.kills + " kills " + entry.deaths + " deaths\n";
}

GUILayout.BeginArea(new Rect((Screen.width - 185), 20, 175, scoreBoardHeight));
GUILayout.Box(scoreText);
GUILayout.EndArea();

}

FPSPlayerNode GetPlayer(PhotonPlayer networkP)
{
foreach (FPSPlayerNode playerInstance in gameSetupScript.playerList)
{
if (networkP == playerInstance.networkPlayer)
{
return playerInstance;
}
}
Debug.LogError("GetPlayer couldn't find player!");
return null;
}

public void LocalPlayerHasKilled()
{

FPSPlayerNode pNode = GetPlayer(PhotonNetwork.player);
pNode.kills += 1;

//Overwrite the data of other players with the new correct score
photonView.RPC("UpdateScore", PhotonTargets.All, PhotonNetwork.player, pNode.kills, pNode.deaths);
}

public void LocalPlayerDied()
{
FPSPlayerNode pNode = GetPlayer(PhotonNetwork.player);
pNode.deaths += 1;

//Overwrite with new correct score
photonView.RPC("UpdateScore", PhotonTargets.All, PhotonNetwork.player, pNode.kills, pNode.deaths);
}


[RPC]
void UpdateScore(PhotonPlayer player, int kills, int deaths)
{
Debug.Log((PhotonNetwork.player == player) + "=local " + kills + "kills & deaths=" + deaths);

FPSPlayerNode pNode = GetPlayer(player);
if (pNode != null)
{
pNode.kills = kills;
pNode.deaths = deaths;
}
else
{
Debug.LogError("Could not find network player " + player + " in the gamesetup playerlist!");
}
scoreBoardHeight = gameSetupScript.playerList.Count * 15 + 40;
}
}[/code2]

GameSetupScript

[code2=csharp]public Transform playerPref;
public string playerName = "";
public int plyrs = 0;

NetworkManager net;

//Server-only playerlist
public List<FPSPlayerNode> playerList = new List<FPSPlayerNode>();

public static bool started = false;
public bool paused;
Chat chat;


// Use this for initialization
void Awake() {
playerName = accNameScript.accUsername;
GameObject network = GameObject.Find("NetworkManager");
net = network.GetComponent<NetworkManager>();


print("AddPlayer");
//chatScript.SetShowChatWindow(true);
photonView.RPC("AddPlayer", PhotonTargets.AllBuffered);

}
[RPC]
//Sent by newly connected clients, recieved by server
void AddPlayer(PhotonMessageInfo info)
{
print("Adding");
playerPref = net.playerPrefab;
PhotonPlayer netPlayer = info.sender;
FPSPlayerNode newEntry = new FPSPlayerNode();
newEntry.playerName = netPlayer.name;
newEntry.networkPlayer = netPlayer;
playerList.Add(newEntry);


}
void OnPhotonPlayerDisconneced(PhotonPlayer player)
{
//Remove player from the server list
foreach (FPSPlayerNode entry in playerList as List<FPSPlayerNode>)
{
if (entry.networkPlayer == player)
{
//chatScript.addGameChatMessage(entry.playerName + " disconnected " + player);
playerList.Remove(entry);
break;
}
}
}
void Start () {
PhotonNetwork.isMessageQueueRunning = true;
started = true;


}
IEnumerator chatfunction()
{
yield return new WaitForSeconds(1);
chat.turnchatOn();
}
// Update is called once per frame
void Update () {

plyrs = playerList.Count;
// GameObject chatobject = GameObject.Find("Chat");
// chat = chatobject.GetComponent<Chat>();
// StartCoroutine(chatfunction());
}
void OnNetworkLoadedLevel()
{
net.spawn();

// Randomize starting location
//GameObject[] spawnpoints = GameObject.FindGameObjectsWithTag("Spawnpoint");
//Debug.Log("spawns: " + spawnpoints.Length);

//Transform spawnpoint = spawnpoints[Random.Range(0, spawnpoints.Length)].transform;
//PhotonNetwork.Instantiate(playerPref.name, Vector3.Zero, spawnpoint.rotation, 0);
}[/code2]

a few notes with the code, the models are instantiated in a separate script called NetworkManager, i added in the print("Added"); to check if the RPC "AddPlayer" was being called and it isn't.

I've also tried
[code2=csharp]if (PhotonNetwork.isMasterClient)
{
photonView.RPC("AddPlayer", PhotonTargets.AllBuffered);
}
}
else if (PhotonNetwork.isNonMasterClientInRoom)
{
photonView.RPC("AddPlayer", PhotonTargets.AllBuffered);

}
}[/code2]
but still no luck, Everytime i try and access the playernodes it gives me; [code2=csharp]NullReferenceException: Object reference not set to an instance of an object[/code2]

Any ideas where i could be going wrong? I am new to this and have very basic networking knowledge.

Edit: forgot to show my playernode code;
[code2=csharp]public class FPSPlayerNode
{
public string playerName;
public PhotonPlayer networkPlayer;

public int kills = 0;
public int deaths = 0;

}[/code2]

Comments

  • isMasterClient and isNonMasterClientInRoom are not really related. The second tells you if any user, except the master client is in the room. This implies: 2 players. If there is only 1 player, this player is automatically the master client.

    There is a player list in PUN. Unless someone scores, you don't have to save anything about the users (if their score is not found, assume it's 0).

    Please post the full error message. The callstack that's below the message itself is very useful to find those issues. I don't know where it breaks exactly, e.g.
  • I get no errors from the actual scoreboard when i start the game, but whenever a player dies it throws out two errors;

    [code2=csharp]GetPlayer couldn't find player!
    UnityEngine.Debug:LogError(Object)
    ScoreBoard:GetPlayer(PhotonPlayer) (at Assets/Resources/Scripts/ScoreBoard.cs:55)
    ScoreBoard:LocalPlayerHasKilled() (at Assets/Resources/Scripts/ScoreBoard.cs:62)
    CombatScript:ApplyDamage(Int32) (at Assets/Resources/Scripts/CombatScript.cs:37)
    UnityEngine.Component:SendMessage(String, Object, SendMessageOptions)
    Orb:OnTriggerEnter(Collider) (at Assets/Resources/Scripts/Orb.cs:23)[/code2]

    [code2=csharp]NullReferenceException: Object reference not set to an instance of an object
    ScoreBoard.LocalPlayerHasKilled () (at Assets/Resources/Scripts/ScoreBoard.cs:63)
    CombatScript.ApplyDamage (Int32 Damage) (at Assets/Resources/Scripts/CombatScript.cs:37)
    UnityEngine.Component:SendMessage(String, Object, SendMessageOptions)
    Orb:OnTriggerEnter(Collider) (at Assets/Resources/Scripts/Orb.cs:23)[/code2]

    The scoreboard in the top right also doesn't populate with the players names and score it just stays blank
  • Sorry but I can't help with that at the moment.
    You could debug this by printing out the values you get in ApplyDamage and which you use in GetPlayer. Not sure what you do.
  • Thanks Tobias, I managed to get it fixed it wasn't adding the player because the script was being loaded before the player joined, so I moved AddPlayer to a co routine and waited a few seconds to initialize it and that solved the issue
  • There are several callbacks that might be more accurate than a timed coroutine.
    Try this to wait for another user to join:

    public void OnPhotonPlayerConnected(PhotonPlayer newPlayer) { }

    Find enum PhotonNetworkingMessage to get a list of the callbacks available.