using System; using System.Collections; using Photon; using UnityEngine; using UnityEngine.UI; public class RpsCore : PunBehaviour, IPunTurnManagerCallbacks { public enum Hand { None = 0, Rock = 1, Paper = 2, Scissors = 3 } public enum ResultType { None = 0, Draw = 1, LocalWin = 2, LocalLoss = 3 } [SerializeField] private RectTransform ConnectUiView; [SerializeField] private RectTransform GameUiView; [SerializeField] private CanvasGroup ButtonCanvasGroup; [SerializeField] private RectTransform TimerFillImage; [SerializeField] private Text TurnText; [SerializeField] private Text TimeText; [SerializeField] private Text RemotePlayerText; [SerializeField] private Text LocalPlayerText; [SerializeField] private Image WinOrLossImage; [SerializeField] private Image localSelectionImage; public Hand localSelection; [SerializeField] private Image remoteSelectionImage; public Hand remoteSelection; [SerializeField] private Sprite SelectedRock; [SerializeField] private Sprite SelectedPaper; [SerializeField] private Sprite SelectedScissors; [SerializeField] private Sprite SpriteWin; [SerializeField] private Sprite SpriteLose; [SerializeField] private Sprite SpriteDraw; [SerializeField] private RectTransform DisconnectedPanel; private ResultType result; private PunTurnManager turnManager; public Hand randomHand; private bool IsShowingResults; public void Start() { turnManager = base.gameObject.AddComponent(); turnManager.TurnManagerListener = this; turnManager.TurnDuration = 5f; localSelectionImage.gameObject.SetActive(false); remoteSelectionImage.gameObject.SetActive(false); StartCoroutine("CycleRemoteHandCoroutine"); RefreshUIViews(); } public void Update() { if (DisconnectedPanel == null) { UnityEngine.Object.Destroy(base.gameObject); } if (Input.GetKeyUp(KeyCode.L)) { PhotonNetwork.LeaveRoom(); } if (Input.GetKeyUp(KeyCode.C)) { PhotonNetwork.ConnectUsingSettings(null); PhotonHandler.StopFallbackSendAckThread(); } if (!PhotonNetwork.inRoom) { return; } if (PhotonNetwork.connected && DisconnectedPanel.gameObject.GetActive()) { DisconnectedPanel.gameObject.SetActive(false); } if (!PhotonNetwork.connected && !PhotonNetwork.connecting && !DisconnectedPanel.gameObject.GetActive()) { DisconnectedPanel.gameObject.SetActive(true); } if (PhotonNetwork.room.PlayerCount > 1) { if (turnManager.IsOver) { return; } if (TurnText != null) { TurnText.text = turnManager.Turn.ToString(); } if (turnManager.Turn > 0 && TimeText != null && !IsShowingResults) { TimeText.text = turnManager.RemainingSecondsInTurn.ToString("F1") + " SECONDS"; TimerFillImage.anchorMax = new Vector2(1f - turnManager.RemainingSecondsInTurn / turnManager.TurnDuration, 1f); } } UpdatePlayerTexts(); Sprite sprite = SelectionToSprite(localSelection); if (sprite != null) { localSelectionImage.gameObject.SetActive(true); localSelectionImage.sprite = sprite; } if (turnManager.IsCompletedByAll) { sprite = SelectionToSprite(remoteSelection); if (sprite != null) { remoteSelectionImage.color = new Color(1f, 1f, 1f, 1f); remoteSelectionImage.sprite = sprite; } return; } ButtonCanvasGroup.interactable = PhotonNetwork.room.PlayerCount > 1; if (PhotonNetwork.room.PlayerCount < 2) { remoteSelectionImage.color = new Color(1f, 1f, 1f, 0f); } else if (turnManager.Turn > 0 && !turnManager.IsCompletedByAll) { PhotonPlayer next = PhotonNetwork.player.GetNext(); float a = 0.5f; if (turnManager.GetPlayerFinishedTurn(next)) { a = 1f; } if (next != null && next.IsInactive) { a = 0.1f; } remoteSelectionImage.color = new Color(1f, 1f, 1f, a); remoteSelectionImage.sprite = SelectionToSprite(randomHand); } } public void OnTurnBegins(int turn) { Debug.Log("OnTurnBegins() turn: " + turn); localSelection = Hand.None; remoteSelection = Hand.None; WinOrLossImage.gameObject.SetActive(false); localSelectionImage.gameObject.SetActive(false); remoteSelectionImage.gameObject.SetActive(true); IsShowingResults = false; ButtonCanvasGroup.interactable = true; } public void OnTurnCompleted(int obj) { Debug.Log("OnTurnCompleted: " + obj); CalculateWinAndLoss(); UpdateScores(); OnEndTurn(); } public void OnPlayerMove(PhotonPlayer photonPlayer, int turn, object move) { Debug.Log(string.Concat("OnPlayerMove: ", photonPlayer, " turn: ", turn, " action: ", move)); throw new NotImplementedException(); } public void OnPlayerFinished(PhotonPlayer photonPlayer, int turn, object move) { Debug.Log(string.Concat("OnTurnFinished: ", photonPlayer, " turn: ", turn, " action: ", move)); if (photonPlayer.IsLocal) { localSelection = (Hand)(byte)move; } else { remoteSelection = (Hand)(byte)move; } } public void OnTurnTimeEnds(int obj) { if (!IsShowingResults) { Debug.Log("OnTurnTimeEnds: Calling OnTurnCompleted"); OnTurnCompleted(-1); } } private void UpdateScores() { if (result == ResultType.LocalWin) { PhotonNetwork.player.AddScore(1); } } public void StartTurn() { if (PhotonNetwork.isMasterClient) { turnManager.BeginTurn(); } } public void MakeTurn(Hand selection) { turnManager.SendMove((byte)selection, true); } public void OnEndTurn() { StartCoroutine("ShowResultsBeginNextTurnCoroutine"); } public IEnumerator ShowResultsBeginNextTurnCoroutine() { ButtonCanvasGroup.interactable = false; IsShowingResults = true; if (result == ResultType.Draw) { WinOrLossImage.sprite = SpriteDraw; } else { WinOrLossImage.sprite = ((result != ResultType.LocalWin) ? SpriteLose : SpriteWin); } WinOrLossImage.gameObject.SetActive(true); yield return new WaitForSeconds(2f); StartTurn(); } public void EndGame() { Debug.Log("EndGame"); } private void CalculateWinAndLoss() { result = ResultType.Draw; if (localSelection == remoteSelection) { return; } if (localSelection == Hand.None) { result = ResultType.LocalLoss; return; } if (remoteSelection == Hand.None) { result = ResultType.LocalWin; } if (localSelection == Hand.Rock) { result = ((remoteSelection != Hand.Scissors) ? ResultType.LocalLoss : ResultType.LocalWin); } if (localSelection == Hand.Paper) { result = ((remoteSelection != Hand.Rock) ? ResultType.LocalLoss : ResultType.LocalWin); } if (localSelection == Hand.Scissors) { result = ((remoteSelection != Hand.Paper) ? ResultType.LocalLoss : ResultType.LocalWin); } } private Sprite SelectionToSprite(Hand hand) { switch (hand) { case Hand.Rock: return SelectedRock; case Hand.Paper: return SelectedPaper; case Hand.Scissors: return SelectedScissors; default: return null; } } private void UpdatePlayerTexts() { PhotonPlayer next = PhotonNetwork.player.GetNext(); PhotonPlayer player = PhotonNetwork.player; if (next != null) { RemotePlayerText.text = next.NickName + " " + next.GetScore().ToString("D2"); } else { TimerFillImage.anchorMax = new Vector2(0f, 1f); TimeText.text = string.Empty; RemotePlayerText.text = "waiting for another player 00"; } if (player != null) { LocalPlayerText.text = "YOU " + player.GetScore().ToString("D2"); } } public IEnumerator CycleRemoteHandCoroutine() { while (true) { randomHand = (Hand)UnityEngine.Random.Range(1, 4); yield return new WaitForSeconds(0.5f); } } public void OnClickRock() { MakeTurn(Hand.Rock); } public void OnClickPaper() { MakeTurn(Hand.Paper); } public void OnClickScissors() { MakeTurn(Hand.Scissors); } public void OnClickConnect() { PhotonNetwork.ConnectUsingSettings(null); PhotonHandler.StopFallbackSendAckThread(); } public void OnClickReConnectAndRejoin() { PhotonNetwork.ReconnectAndRejoin(); PhotonHandler.StopFallbackSendAckThread(); } private void RefreshUIViews() { TimerFillImage.anchorMax = new Vector2(0f, 1f); ConnectUiView.gameObject.SetActive(!PhotonNetwork.inRoom); GameUiView.gameObject.SetActive(PhotonNetwork.inRoom); ButtonCanvasGroup.interactable = PhotonNetwork.room != null && PhotonNetwork.room.PlayerCount > 1; } public override void OnLeftRoom() { Debug.Log("OnLeftRoom()"); RefreshUIViews(); } public override void OnJoinedRoom() { RefreshUIViews(); if (PhotonNetwork.room.PlayerCount == 2) { if (turnManager.Turn == 0) { StartTurn(); } } else { Debug.Log("Waiting for another player"); } } public override void OnPhotonPlayerConnected(PhotonPlayer newPlayer) { Debug.Log("Other player arrived"); if (PhotonNetwork.room.PlayerCount == 2 && turnManager.Turn == 0) { StartTurn(); } } public override void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer) { Debug.Log("Other player disconnected! " + otherPlayer.ToStringFull()); } public override void OnConnectionFail(DisconnectCause cause) { DisconnectedPanel.gameObject.SetActive(true); } }