So am currently developing a way where players in a current room are in a waiting room entering or selecting their specific item. When each player has completed a button is clicked which is 'I am Ready!'...When a player clicks I am ready then an Int variable ReadyPlayers Updates according to how many have clicked the I am ready Button. If the readyplayers (int) match the number of players in the room then a countdown starts. The problem I am facing is configuring the custom properties. I wrote this code hoping that it would solve this problem but I end up getting logical errors where the readyplayers (int) are not counted from the players.
using Hashtable = ExitGames.Client.Photon.Hashtable;
//Variables
public int ReadyPlayers = 0;
//added this to the button on the inspector : onclick event
public void OnClickIamReady()
{
ReadyPlayers = (int)PhotonNetwork.LocalPlayer.CustomProperties["PlayerReady"];
ReadyPlayers ;
Hashtable hash = new Hashtable() { { "PlayerReady", ReadyPlayers } };
PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
//when a player clicks this button deactivate it
IamReadyButton.gameObject.SetActive(false);
foreach (Player player in PhotonNetwork.PlayerList)
{
Debug.Log(player.NickName.ToString() " " " is Ready. " " " " Players Who are Ready : " player.CustomProperties["PlayerReady"].ToString());
}
}
CodePudding user response:
It makes no sense that every player uses his own custom properties in order to store how many ready players he is aware of in total.
Instead you rather want to set only yourself to ready.
Then check of everyone is ready and start the match. But you don't want to make this check on the clients themselves. What about network lag? What if two clients press the button at the same time and the properties are not synced yet?
-> I would rather only check on the Master client within OnPlayerPropertiesUpdate
So something like
using System.Linq;
...
public void OnClickIamReady()
{
// Do not use a new hashtable everytime but rather the existing
// in order to not loose any other properties you might have later
var hash = PhotonNetwork.LocalPlayer.CustomProperties;
hash["Ready"] = true;
PhotonNetwork.LocalPlayer.SetCustomProperties(hash);
IamReadyButton.gameObject.SetActive(false);
if(!PhotonNetwork.IsMasterClient) return;
CheckAllPlayersReady ();
}
public override void OnPlayerPropertiesUpdate (Player targetPlayer, Hashtable changedProps)
{
if(!PhotonNetwork.IsMasterClient) return;
if(!changedProps.ContainsKey("Ready")) return;
CheckAllPlayersReady();
}
public override void OnMasterClientSwitched(Player newMasterClient)
{
if(newMasterClient != PhotoNework.LocalPlayer) return;
CheckAllPlayersReady ();
}
private void CheckAllPlayersReady ()
{
var players = PhotonNetwork.PlayerList;
// This is just using a shorthand via Linq instead of having a loop with a counter
// for checking whether all players in the list have the key "Ready" in their custom properties
if(players.All(p => p.CustomProperties.ContainsKey("Ready") && (bool)p.CustomProperties["Ready"]))
{
Debug.Log("All players are ready!");
}
}