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.
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;
}
}
