Итак, я пытался создать многопользовательскую карточную игру на Unity и добавил стрелку, показывающую текущего игрока. Хост Игрок 1 находится слева, клиент Игрок 2 — справа, и в этом примере у меня есть два компьютерных игрока с базовой карточной логикой. Как вы можете видеть в этом примере, когда играет Игрок 1, стрелка в обоих представлениях перемещается к Игроку 2. Игрок 2 играет, и только Игрок 1 обновляется, указывая на Игрок 3, затем после того, как Игрок 3 уходит, и Игрок 1, и Игрок 2 переходят к Игроку 4. По какой-то причине это всегда происходит с Игроком 2.
Это вызывается после того, как я нажимаю кнопку выбора. Значения карт объединены в сеть, поэтому в основном это поиск соответствующей карты, выбранной в руке игрока, и создание игрового объекта для помещения в общую зону сброса, уничтожение карты в руке и добавление всего в зону сброса.
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;
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 (синглтон для игровой логики) и добавляет карту, затем переходит к endturn, где она должна закончиться обновлением NextPlayer, а затем стрелочным скриптом.
[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);
}
Тогда это стрелочный скрипт. Эпос — это позиция противника по отношению к игроку. Я не понимаю, почему Игрок 2 не получает обновления после своего хода.
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}");
Итак, я пытался создать многопользовательскую карточную игру на Unity и добавил стрелку, показывающую текущего игрока. Хост Игрок 1 находится слева, клиент Игрок 2 — справа, и в этом примере у меня есть два компьютерных игрока с базовой карточной логикой. Как вы можете видеть в этом примере, когда играет Игрок 1, стрелка в обоих представлениях перемещается к Игроку 2. Игрок 2 играет, и только Игрок 1 обновляется, указывая на Игрок 3, затем после того, как Игрок 3 уходит, и Игрок 1, и Игрок 2 переходят к Игроку 4. По какой-то причине это всегда происходит с Игроком 2. [img]https://i.sstatic.net/tCiC4PDy.gif[/img]
Это вызывается после того, как я нажимаю кнопку выбора. Значения карт объединены в сеть, поэтому в основном это поиск соответствующей карты, выбранной в руке игрока, и создание игрового объекта для помещения в общую зону сброса, уничтожение карты в руке и добавление всего в зону сброса. 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 (синглтон для игровой логики) и добавляет карту, затем переходит к endturn, где она должна закончиться обновлением NextPlayer, а затем стрелочным скриптом. [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); }
Тогда это стрелочный скрипт. Эпос — это позиция противника по отношению к игроку. Я не понимаю, почему Игрок 2 не получает обновления после своего хода. 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}");