Search Unity

Third Party Can't sync player switched item through network [PUN 2]

Discussion in 'Multiplayer' started by Voltonik_, Mar 11, 2021.

  1. Voltonik_

    Voltonik_

    Joined:
    Jan 21, 2018
    Posts:
    22
    Hello, I've been trying to do this for 2 days now. Here is my current code:

    Code (CSharp):
    1.  
    2.    public void SwitchTo(int item_index) {
    3.         if (multiplayer) {
    4.             if (photonView.IsMine) {
    5.                 photonView.RPC("RPC_Switch", RpcTarget.All, item_index);
    6.             }
    7.         }
    8.         else {
    9.             RPC_Switch(item_index);
    10.         }
    11.     }  
    12.  
    13.     [PunRPC]
    14.     public void RPC_Switch(int item_index) {
    15.         var item = WeaponHelper.FindWeaponByID(item_index);
    16.         Debug.Log($"{gameObject.name} switching to {item.gameObject.name}");
    17.  
    18.         inventorySelector = pm.inventory.IndexOf(item) + 1;
    19.         if (!item.pickedUp) {
    20.             item.OnPickup(gameObject);
    21.             item.Setup();
    22.             Destroy(item.gameObject.GetComponent<Rigidbody>());
    23.             if (pm.startingWeapon.type == type.Unarmed)
    24.                 pm.startingWeapon.isEquiped = false;
    25.         }
    26.         if (item.gameObject.activeSelf == false)
    27.             item.gameObject.SetActive(true);
    28.         foreach (Weapon otherItem in pm.inventory) {
    29.             if (otherItem.gameObject != item.gameObject) {
    30.                 otherItem.isEquiped = false;
    31.                 if (otherItem.gameObject != gameObject)
    32.                     otherItem.gameObject.SetActive(false);
    33.             }
    34.         }
    35.         if (item.gameObject != gameObject) {
    36.             if (item.type == type.Melee)
    37.                 item.transform.SetParent(meleePlaceholder, false);
    38.             else if (item.type == type.Ranged)
    39.                 item.transform.SetParent(rangedPlaceholder, false);
    40.             item.transform.localPosition = Vector3.zero;
    41.             item.transform.localRotation = new Quaternion(0, 0, 0, 0);
    42.         }
    43.         item.isEquiped = true;
    44.         pm.currentWeapon = item;
    45.         if (item.type == type.Melee) {
    46.             Dictionary<string, float> layersToSet = new Dictionary<string, float>();
    47.             layersToSet.Add("MeleeMovements", 1f);
    48.             SetAnimationLayer(layersToSet);
    49.         } else {
    50.             foreach (Weapon weapon in pm.inventory)
    51.                 if (weapon.type == type.Melee)
    52.                     weapon.gameObject.GetComponent<Melee>().SwordSlashFXToggle("1,false");
    53.         }
    54.         if (item.type == type.Unarmed) {
    55.             Dictionary<string, float> layersToSet = new Dictionary<string, float>();
    56.             layersToSet.Add("Unarmed", 1f);
    57.             SetAnimationLayer(layersToSet);
    58.  
    59.         }
    60.         if (item.type == type.Ranged) {
    61.             Dictionary<string, float> layersToSet = new Dictionary<string, float>();
    62.             layersToSet.Add("RangedMovements", 1f);
    63.             SetAnimationLayer(layersToSet);
    64.             gameObject.GetComponent<MonoBehaviour>().StartCoroutine(WaitUntil(item.transform.parent = rangedPlaceholder, () => rigBuilder.layers[0].active = true));
    65.         } else {
    66.             rigBuilder.layers[0].active = false;
    67.         }
    68.     }
    69.  
    So here is what's happening, when the game starts players switch to a weapon. when the master player joins he switches to the weapon, but when the other player joins the weapon disappears from the master client and is equipped by the other player. Im guessing this is because of this part (line 35:42):

    Code (CSharp):
    1. if (item.gameObject != gameObject) {
    2.             if (item.type == type.Melee)
    3.                 item.transform.SetParent(meleePlaceholder, false);
    4.             else if (item.type == type.Ranged)
    5.                 item.transform.SetParent(rangedPlaceholder, false);
    6.             item.transform.localPosition = Vector3.zero;
    7.             item.transform.localRotation = new Quaternion(0, 0, 0, 0);
    8.         }
    Please correct me if Iam wrong but from my understanding, the RPC_Switch() method should be called on all network instances of the player who sent the RPC.
    So if I have two players, A and B, and player A switched to a weapon, all instances of player A across the network will switch as well.
    If Iam understanding this correctly then what am I doing wrong?

    Also I tried achieving this using custom player properties but I got similar if not the same results as using RPC's

    Thank you.
     
  2. Voltonik_

    Voltonik_

    Joined:
    Jan 21, 2018
    Posts:
    22
    Found the issue!
    The problem was nothing to do with RPC's. It was simply this line of code
    var item = WeaponHelper.FindWeaponByID(item_index);

    WeaponHelper.FindWeaponByID() is a method I wrote to find a weapon by its unique ID generated at Awake()
    The problem was that this ID was not synced across the network! so that method would return incorrect weapons explaining the behaviour I was getting.
    Fixed it by finding the weapon by their PhotonViews' view ID's instead of the unsynced ID system I had before.
     
    tobiass likes this.