Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Netcode] Changing NetworkVariable in one NetworkeBehavior changesit inside ALL NetworkBehaviours

Discussion in 'Unity Transport' started by ANLevant, Nov 25, 2023.

  1. ANLevant

    ANLevant

    Joined:
    Jun 10, 2014
    Posts:
    21
    So I'm making a multiplayer card game, based in Triple Triad using Netcode. I have a Card NetworkBehaviour with an attribute called IsBlue, which determines the color of the background for the card (and player currently owning the card)

    Code (CSharp):
    1. public class Card : Interactible //Interacbile is a NetworkBehaviour
    2. {
    3.     ...
    4.     public NetworkVariable<bool> IsBlue = new NetworkVariable<bool>(false);
    5.     ...
    6.  
    7.     void Update()
    8.     {
    9.         if (IsChangingSides.Value)
    10.         {
    11.             ChangeSides();
    12.         }
    13.     }
    14.     ...
    15.     public override void OnNetworkSpawn()
    16.     {
    17.         CardName.OnValueChanged += (FixedString64Bytes previousValue, FixedString64Bytes newValue) => {              ChangeCardMaterial(); };
    18.         IsBlue.OnValueChanged += (bool previousValue, bool newValue) =>
    19.         {
    20.             Debug.Log("Changed Color!");
    21.             ChangeCardMaterial();
    22.         };
    23.     ...
    24.     private void ChangeSides()
    25.     {
    26.         ....
    27.         ChangeColorClientRpc(!IsBlue.Value);
    28.         IsChangingSides.Value = false;
    29.         RevealCardClientRpc();
    30.     }
    31.     ...
    32.     [ClientRpc]
    33.     public void ChangeColorClientRpc(bool isBlue)
    34.     {
    35.         Debug.Log(name);
    36.         IsBlue.Value = isBlue;
    37.         ChangeCardMaterial();
    38.     }
    39.     ....
    40. }
    41.  
    When I first start the game, I randomly decide which player will be the first one and change the value of their IsBlue variable individually inside the server, then I register a listener for the OnValueChanged event, which updates the material for each card. This is working like a charm

    Code (CSharp):
    1.  
    2. public class GameController : NetworkBehaviour
    3. {
    4.     ...
    5.     public Hand[] PlayerHands;
    6.     ...
    7.     private void SetupCards()
    8.     {
    9.         foreach (Hand playerHand in PlayerHands)
    10.         {
    11.             foreach (Card card in playerHand.cards)
    12.             {
    13.                 ...
    14.                 card.IsBlue = card.OwningPlayer.IsBlue;
    15.                 ...
    16.             }
    17.         }
    18.     }
    19. ...
    20. }
    21.  
    Now, when playing, after a player makes a move and takes the enemy's card, the card is supposed to change colors, but when I change the IsBlue value for the card, it changes on all of the other cards too! what's worse, the OnValueChanged listener for the variable is never called!

    Code (CSharp):
    1. public class Player : NetworkBehaviour
    2. {
    3.     ...
    4.     //This is the entry point for players using their card, this triggers ther est of the process
    5.     [ServerRpc(RequireOwnership = false)]
    6.     public void SelectInteractibleServerRpc(NetworkObjectReference interactibleNetworkReference,
    7.         ServerRpcParams serverRpcParams = default)
    8.     {
    9.         NetworkObject rawInteractible;
    10.         bool couldFetchIteractible = interactibleNetworkReference.TryGet(out rawInteractible);
    11.  
    12.         if (couldFetchIteractible)
    13.         {
    14.             Interactible interactible = rawInteractible.gameObject.GetComponent<Interactible>();
    15.             if (IsPlaying.Value && (rawInteractible.OwnerClientId == serverRpcParams.Receive.SenderClientId || interactible is BoardSlot))
    16.             {
    17.                 ...
    18.                 interactible.ToggleSelect();
    19.                ...
    20.            }
    21.         ...
    22.         }
    23.     ...
    24.     }
    25. ...
    26. }
    As a footnote, I am now changing the value inside an RPC because, as mentioned above, when I tried changing it inside the server itself, it was just changing the value for the variable for all Card NetworkObjects in scene, never calling the listener so the materials where never updating. I decided to create a ClientRpc and manually chagne the material, but the issue of all cards having their NetworkVariable changed at the same time persisted when I change the variable inside the ClientRpc
    Code (CSharp):
    1. public class BoardSlot : Interactible //Interacbile is a NetworkBehaviour
    2. {
    3.     private Card OccupyingCard;
    4.  
    5.     public BoardSlot TopSlot;
    6.     ...
    7.  
    8.     public override void ToggleSelect()
    9.     {
    10.         if (OccupyingCard == null && GameController.Singleton.SelectedCard != null)
    11.         {
    12.             OccupyingCard = GameController.Singleton.SelectedCard;
    13.             GameController.Singleton.SelectedCard.PlayCard(transform.position);
    14.             RevealPlayedCardClientRpc(GameController.Singleton.SelectedCard.NetworkObject);
    15.             GameController.Singleton.SelectedCard = null;
    16.             CalculateMove();
    17.             GameController.Singleton.ReportPlayerMove();
    18.         }
    19.     }
    20.     ...
    21.     private void CalculateMove()
    22.     {
    23.         if (TopSlot != null && TopSlot.OccupyingCard != null && TopSlot.OccupyingCard.BottomValue.Value < OccupyingCard.TopValue.Value && TopSlot.OccupyingCard.IsBlue.Value != OccupyingCard.IsBlue.Value)
    24.         {
    25.             TopSlot.OccupyingCard.IsChangingSides.Value = true;
    26.             Debug.Log("Brute Force Taken!");
    27.         }
    28. ...
    29. }
    I verified and the ClientRpc is only being called on the desired card, but still, all cards are updated with the new IsBlue.

    Am I doing something wrong? Or am I just the unluckiest person in the world to stumble upon two bugs at the same time? Help please :(
     
    Last edited: Nov 25, 2023