Setting custom player properties?

I'm trying to load in player weapons from a static scriptable object, and I'm doing this by first:
Adding a custom player property per weapon part
Then, getting the player's custom properties and loading that in

for some reason this doesn't work. The script that does this isn't disabled for other players, should I make it run only if isMine is true?

Here's what I've got so far:
void Start()
    {
        if(current == null)
        {
            current = this;
        }
        shooting = GetComponent<Shooting>();
        view = gameObject.GetPhotonView();
        LoadWeapon(WeaponManager.instance.ourWeapon);
    }
    /// <summary>
    /// Begins loading the weapon in from a data file
    /// </summary>
    public void LoadWeapon(WeaponData w)
    {
        ExitGames.Client.Photon.Hashtable parts = new ExitGames.Client.Photon.Hashtable();
        parts.Add("Body", WeaponManager.instance.ourWeapon.body);
        parts.Add("Barrel", WeaponManager.instance.ourWeapon.barrel);
        if (WeaponManager.instance.ourWeapon.underBarrel != null)
            parts.Add("UnderBarrel", WeaponManager.instance.ourWeapon.underBarrel);
        if (WeaponManager.instance.ourWeapon.overBarrel != null)
            parts.Add("OverBarrel", WeaponManager.instance.ourWeapon.overBarrel);
        PhotonNetwork.player.SetCustomProperties(parts);

        print(view.owner.NickName + "'s weapon body is: " + view.owner.CustomProperties["Body"].ToString());
    }

For some reason this doesn't work consistently every time, and sometimes only works for the person who joined first. Anyone know what's wrong?

Answers

  • Updated my code a bit, works more consistently but still doesn't synchronise a lot of the time.
    public void SetupWeapons()
        {
            if(view.isMine)
            {
                //Basically cramming everything into one string.
                //Should look like BODY:(body)|BARREL:(barrel)|OB:(overbarrel)|UB:(underbarrel)
                string WeaponString = "BODY:" + WeaponManager.instance.ourWeapon.body + "|" + "BARREL:" + WeaponManager.instance.ourWeapon.barrel;
                if (WeaponManager.instance.ourWeapon.overBarrel != null)
                {
                    WeaponString += "|OB:" + WeaponManager.instance.ourWeapon.overBarrel;
                }
                if (WeaponManager.instance.ourWeapon.underBarrel != null)
                {
                    WeaponString += "|UB:" + WeaponManager.instance.ourWeapon.underBarrel;
                }
                ExitGames.Client.Photon.Hashtable props = new ExitGames.Client.Photon.Hashtable();
                props.Add("Weapon 1", WeaponString);
                PhotonNetwork.player.SetCustomProperties(props);
            }
    
            LoadWeapon(view.owner.CustomProperties["Weapon 1"].ToString());
        }
    

    This method is ran on Start() for every person in the room. I've crammed it into one splittable string now which works a lot more
  • bump
  • bump

  • JohnTube
    JohnTube ✭✭✭✭✭
    edited May 2020
    Hi @LeytonMate,

    Did you implement OnPhotonPlayerPropertiesChanged callback?
    It will tell you that properties have been updated.

    Make sure clients are joined to the same room.
    Check error logs.

    Side notes (optimization):
    Also, can you split this into multiple properties instead of a one with a single long string value?
    It's better especially if each part of that string is updated separately individually with different frequencies.
    Also you could maybe replace the string value with int/byte/short as index or pointer for enum or actual value on client for efficiency.
  • How will I be able to tell that the property that changed was the weapons?

  • Also, how can i tell whos properties changed?
    @JohnTube
  • JohnTube
    JohnTube ✭✭✭✭✭
    edited May 2020
    Hi @LeytonMate,

    as you can read in the documentation of the callback:
    void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps) {
        PhotonPlayer player = playerAndUpdatedProps[0] as PhotonPlayer;
        Hashtable props = playerAndUpdatedProps[1] as Hashtable;
        //...
    }
    

    and the hashtable has the key/value pairs that have been changed.
    e.g.
    Hashtable props = playerAndUpdatedProps[1] as Hashtable;
    object temp;
    if (props.TryGetValue("Weapon 1", out temp))
    {
        string weapon = temp as string;
    }
    

    Note: it would help to make some efforts and do some research instead of bump spam.
  • I did that, but when comparing it against the PhotonNetwork.player it says it's null?