Need help with Hashtables

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.
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited December 2020
    Hi @Moses,

    Thank you for choosing Photon!
    By 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.

    source