using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace Mirror.Examples.MultipleMatch { [RequireComponent(typeof(NetworkMatch))] public class MatchController : NetworkBehaviour { internal readonly SyncDictionary matchPlayerData = new SyncDictionary(); internal readonly Dictionary MatchCells = new Dictionary(); CellValue boardScore = CellValue.None; bool playAgain = false; [Header("GUI References")] public CanvasGroup canvasGroup; public Text gameText; public Button exitButton; public Button playAgainButton; public Text winCountLocal; public Text winCountOpponent; [Header("Diagnostics - Do Not Modify")] public CanvasController canvasController; public NetworkIdentity player1; public NetworkIdentity player2; public NetworkIdentity startingPlayer; [SyncVar(hook = nameof(UpdateGameUI))] public NetworkIdentity currentPlayer; void Awake() { canvasController = FindObjectOfType(); } public override void OnStartServer() { StartCoroutine(AddPlayersToMatchController()); } // For the SyncDictionary to properly fire the update callback, we must // wait a frame before adding the players to the already spawned MatchController IEnumerator AddPlayersToMatchController() { yield return null; matchPlayerData.Add(player1, new MatchPlayerData { playerIndex = CanvasController.playerInfos[player1.connectionToClient].playerIndex }); matchPlayerData.Add(player2, new MatchPlayerData { playerIndex = CanvasController.playerInfos[player2.connectionToClient].playerIndex }); } public override void OnStartClient() { matchPlayerData.Callback += UpdateWins; canvasGroup.alpha = 1f; canvasGroup.interactable = true; canvasGroup.blocksRaycasts = true; exitButton.gameObject.SetActive(false); playAgainButton.gameObject.SetActive(false); } public void UpdateGameUI(NetworkIdentity _, NetworkIdentity newPlayerTurn) { if (!newPlayerTurn) return; if (newPlayerTurn.gameObject.GetComponent().isLocalPlayer) { gameText.text = "Your Turn"; gameText.color = Color.blue; } else { gameText.text = "Their Turn"; gameText.color = Color.red; } } public void UpdateWins(SyncDictionary.Operation op, NetworkIdentity key, MatchPlayerData matchPlayerData) { if (key.gameObject.GetComponent().isLocalPlayer) { winCountLocal.text = $"Player {matchPlayerData.playerIndex}\n{matchPlayerData.wins}"; } else { winCountOpponent.text = $"Player {matchPlayerData.playerIndex}\n{matchPlayerData.wins}"; } } [Command(requiresAuthority = false)] public void CmdMakePlay(CellValue cellValue, NetworkConnectionToClient sender = null) { // If wrong player or cell already taken, ignore if (sender.identity != currentPlayer || MatchCells[cellValue].playerIdentity != null) return; MatchCells[cellValue].playerIdentity = currentPlayer; RpcUpdateCell(cellValue, currentPlayer); MatchPlayerData mpd = matchPlayerData[currentPlayer]; mpd.currentScore = mpd.currentScore | cellValue; matchPlayerData[currentPlayer] = mpd; boardScore = boardScore | cellValue; if (CheckWinner(mpd.currentScore)) { mpd.wins += 1; matchPlayerData[currentPlayer] = mpd; RpcShowWinner(currentPlayer); currentPlayer = null; } else if (boardScore == CellValue.Full) { RpcShowWinner(null); currentPlayer = null; } else { // Set currentPlayer SyncVar so clients know whose turn it is currentPlayer = currentPlayer == player1 ? player2 : player1; } } bool CheckWinner(CellValue currentScore) { if ((currentScore & CellValue.TopRow) == CellValue.TopRow) return true; if ((currentScore & CellValue.MidRow) == CellValue.MidRow) return true; if ((currentScore & CellValue.BotRow) == CellValue.BotRow) return true; if ((currentScore & CellValue.LeftCol) == CellValue.LeftCol) return true; if ((currentScore & CellValue.MidCol) == CellValue.MidCol) return true; if ((currentScore & CellValue.RightCol) == CellValue.RightCol) return true; if ((currentScore & CellValue.Diag1) == CellValue.Diag1) return true; if ((currentScore & CellValue.Diag2) == CellValue.Diag2) return true; return false; } [ClientRpc] public void RpcUpdateCell(CellValue cellValue, NetworkIdentity player) { MatchCells[cellValue].SetPlayer(player); } [ClientRpc] public void RpcShowWinner(NetworkIdentity winner) { foreach (CellGUI cellGUI in MatchCells.Values) cellGUI.GetComponent