c# – Why isn’t client updating after its turn?


So I was trying to make a multiplayer card game on unity and I added this arrow that shows the current player. Player 1 host is on the left, Player 2 client is on the right and in this example I have 2 computer players with basic card logic. As you can see in this example, when Player 1 plays, the arrow moves on both views to Player 2. Player 2 plays and only Player 1 updates to point to Player 3 then after Player 3 goes both Player 1 and Player 2 moves to Player 4. This always happens with Player 2 for some reason.

gameplay video

This gets called after I click the select button. The values of the cards are networked so this is mostly finding the corresponding card that was selected in the player’s hand and creating a game object to put in the shared dropzone, destroying the card in the hand and adding everything to the dropzone.

 public void addCardsToDropzone()
 {
   
     List<int> temp = new List<int>();
     List<GameManager.PlayedCardState> dc =  new List<GameManager.PlayedCardState>();
     for (int i = 0; i < selectedTags.Count; i++)
     {
         GameObject c = selectedCards[i];
         Debug.Log($"This is the id for {c.name}: {cardNametoId[c.name]}");
         temp = GameManager.Instance.getRandomCardData(i, selectedTags.Count);
         if(GameManager.Instance.cardRank[c.tag] == 8)
         {
             GameManager.Instance.settingEightServerRpc();
         }

         GameManager.PlayedCardState cardInfo =  new GameManager.PlayedCardState(cardNametoId[c.name], PlayerId, temp[0], temp[1], temp[2], GameManager.Instance.cardRank[c.tag]);
         dc.Add(cardInfo);
         Destroy(c);
     }
     GameManager.Instance.PlayCardServerRpc(dc.ToArray(), PlayerId, PlayerHandCount.Value);
     PlayerHandCount.Value -= selectedCards.Count;

     //callingPlayerPassClientRpc(0, PlayerHandCount.Value, PlayerId);
     callingPlayerPass(0, PlayerHandCount.Value, PlayerId);
     selectedCards.Clear();
     selectedTags.Clear();


 }

Then it calls the Gamemanager (a singleton for game logic) and adds the card then goes to endturn where it should end up at updatingNextPlayer and then the arrowscript.

  [ServerRpc(RequireOwnership = false)]
  public void PlayCardServerRpc(PlayedCardState[] dc, ulong playerId, int count)
  {

      if (!IsServer) return;
      foreach(PlayedCardState card in dc)
      {
          dropzoneCards.Add(new PlayedCardState { CardNetworkId = card.CardNetworkId, PlayerId = playerId, X = card.X, Y = card.Y, Rotate = card.Rotate, CardRank = card.CardRank });
      }

      EndTurn(count,playerId);
  }

  public void EndTurn(int handcount, ulong playerId)
  {
      broadcastedCurPlayer = false;
      Debug.Log("In end turn");
   
   /* Shouldn't go here for this example, no 8s were played the handcount isn't 0 and the passes haven't reached 3*/
      if (dropzoneCards.Count > 0 && (eightPlayed || handcount == 0 || (playerPass.Value == allPlayerId.Count - 1 )))
      {
          StartCoroutine(pauseBeforeContinue(handcount, playerId));
      }
      else
      {
          Debug.Log($"broadcast bool: {broadcastedCurPlayer}");
          int temp = (currentPlayer.Value + 1) % 4;
          broadcastingPlayerClientRpc(temp);

          Debug.Log($"Before player set");
          //setNextPlayerServerRpc(temp);
          updatingNextPlayer(temp);

          Debug.Log($"after player set");

      }
  }


 public void updatingNextPlayer(int temp)
 {
     Player player = NetworkManager.Singleton.LocalClient.PlayerObject.GetComponent<Player>();
     if (player == null) return;

     Debug.Log("Is setting new player");
     player.arrow.GetComponent<ArrowScript>().SetTurn(temp);

     setNextPlayerServerRpc(temp);
 }

Then this is the arrowscript. Epos is the position of the enemy in reference to the player. I’m not sure why Player 2 isn’t getting the update after their turn.

public void SetTurn(int temp)
{
    ulong playerId = NetworkManager.Singleton.LocalClient.ClientId;

    int index = GameManager.Instance.allPlayerId.IndexOf(playerId);
    ulong target = GameManager.Instance.allPlayerId[temp];
    int ePos = (GameManager.Instance.allPlayerId.IndexOf(target) - index + 4) % 4;

    if (index == -1)
        ePos = 0;

    Debug.Log($"Index: {index} \nTarget: {target}");
    Debug.Log($"Index of target: {GameManager.Instance.allPlayerId.IndexOf(target)}");
    Debug.Log($"epos: {ePos}");

    Debug.Log($"Player {target} position is at {ePos}");

    switch (ePos)
    {
        case 0:
            // Player(-640, -230--260) rot 180
            transform.localPosition = new Vector3(-640, -230, 180);
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, 180));
            targetPos = new Vector3(-640, -245, 0);
            floatX = false;
            //floatY = true;
            break;

        case 1:
            // Right(660 - 680, -260) rot - 90
            transform.localPosition = new Vector3(660, -260, 0);
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, -90));
            targetPos = new Vector3(670, -260, 0);
            floatX = true;
            break;

        case 2:
            // Up(640, 200-260/230-260) rot = 0
            transform.localPosition = new Vector3(640, 230, 0);
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
            targetPos = new Vector3(640, 245, 0);
            floatX = false;
            break;

        case 3:
            // Left(-660 - -680, 260) rot 90
            transform.localPosition = new Vector3(-660, 260, 0);
            transform.rotation = Quaternion.Euler(new Vector3(0, 0, 90));
            targetPos = new Vector3(-670, 260, 0);
            floatX = true;
            break;

        default:
            Debug.Log("Arrow case went to default.");
            break;



    }

}


Leave a Reply

Your email address will not be published. Required fields are marked *