Need help with Hashtables
The whole answer can be found below.
Try Our
Documentation
Please check if you can find an answer in our extensive documentation.
Join Us
on Discord
Meet and talk to our staff and the entire Photon-Community via Discord.
Read More on
Stack Overflow
Find more information on Stack Overflow (for Circle members only).
Need help with Hashtables
Moses
2020-12-18 18:06:18
Hello,
Can't get why
Hashtable roleHash = new Hashtable();
roleHash.Add("Role", 0);
PhotonNetwork.LocalPlayer.SetCustomProperties(roleHash);
Debug.Log("My hash in the beginning says that I'm the " + (int)PhotonNetwork.LocalPlayer.CustomProperties["Role"]);
gives me "NullReferenceException: Object reference not set to an instance of an object" error on the last line.
At the same time
Hashtable tempHash = new Hashtable();
tempHash.Add("ReadyState", false);
tempHash.Add("ReadyCounter", 0);
tempHash.Add("Start", false);
PhotonNetwork.LocalPlayer.SetCustomProperties(tempHash);
and Debugging each of these properties with "(bool)PhotonNetwork.LocalPlayer.CustomProperties["ReadyState"]" e.g. works perfectly fine.
Do I miss something obvious?
The funny thing that I had the same problem recently, and fixed it somehow, but didn't get how exactly, it was 5 A.M. then :lol:
Help :C
Comments
Well, probably i should mention that the working code placed in callbacks, ant the one that doesn't work is in Start function. Maybe there is a problem?
Okay, I moved the code to the other script where it works and now can't set the player properties.
Here are valueable parts of code:
public override void OnConnectedToMaster()
{
Debug.Log("Connection established!");
Hashtable tempHash = new Hashtable();
tempHash.Add("ReadyState", false);
tempHash.Add("ReadyCounter", 0);
tempHash.Add("Start", false);
tempHash.Add("Role", "Slave");
PhotonNetwork.LocalPlayer.SetCustomProperties(tempHash);
}
and
IEnumerator CountdownCoroutine()
{
for (int i = 5; i >= 0; i--)
{
countdown.text = $"Game starts in {i}...";
yield return new WaitForSeconds(1.0f);
}
if (PhotonNetwork.IsMasterClient)
{
RoleAssignement();
}
PhotonNetwork.LoadLevel("Game");
}
and
public void RoleAssignement()
{
Debug.Log("Role Assignmet Started.");
int rand = Random.Range(0, playersAmount - 1);
Debug.Log(rand + " is a random number.");
Hashtable hash = new Hashtable();
hash.Add("Role", "Master");
PhotonNetwork.CurrentRoom.GetPlayer(rand + 1).SetCustomProperties(hash);
Debug.Log("Role Assignmet Done, " + PhotonNetwork.CurrentRoom.GetPlayer(rand + 1).NickName + " is a MASTER, and is " + (string)PhotonNetwork.CurrentRoom.GetPlayer(rand + 1).CustomProperties["Role"] + " according to his hash.");
}
Sorry for giving too much code, but I'm not sure where exactly I'm making a mistake.
The problem is that in the "RoleAssignment" function Debug says the nickname correct, which means that i accessed the proper player. Bu then it says that he is a Slave according to his hash which is a default value from the first part of the code. It makes me think that I can't change the player properties by "PhotonNetwork.CurrentRoom.GetPlayer(rand + 1).SetCustomProperties(hash);". How then I supposed to do that? Previously I only changed the properties of PhotonNetwork.localPlayer? and it worked fine.
Hi @Moses,
Thank you for choosing Photon!
Back to topBy default, setting properties for actor or room properties will not take effect on the sender/setter client (actor that sets the properties) immediately when joined to an online room unlike what it used to be in PUN Classic. Now, instead, the sender/setter client (actor that sets the properties) will wait for the server event PropertiesChanged to apply/set changes locally. So you need to wait until OnPlayerPropertiesUpdate or OnRoomPropertiesUpdate callbacks are triggered for the local client in order to access them. The new behaviour is due to the introduction of the new room option flag roomOptions.BroadcastPropsChangeToAll which is set to true by default. The reason behind this is that properties can easily go out of synchronization if we set them locally first and then send the request to do so on the server and for other actors in the room. The latter might fail and we may end up with properties of the sender/setter client (actor that sets the properties) different locally from what's on the server or on other clients. If you want to have the old behaviour (set properties locally before sending the request to the server to synchronize them) set roomOptions.BroadcastPropsChangeToAll to false before creating rooms. But we highly recommend against doing this.