using System; using System.Collections; using System.Collections.Generic; using Firebase.Database; using Firebase.Extensions; using TMPro; using UnityEngine; using UnityEngine.UI; using UnityEngine.UIElements; /// /// This is the game state manager on the phone side /// public class GameManager : MonoBehaviour { private GameState currentState; private List players = new List(); private Player currentPlayer = null; [Header("Other component")] public float explanationTime = 4f; private float currentExplanationTime = 0; [Header("Home Connection Component")] public TMP_InputField roomCodeField; public TextMeshProUGUI roomError; public TMP_InputField playerNameField; public TextMeshProUGUI nameError; public UnityEngine.UI.Button submitNewPlayer; [Header("WaitingRoom Component")] public TextMeshProUGUI listPlayersUI; public GameObject submitStartGame; [Header("Pages")] [SerializeField] public GameObject HomeConnection; [SerializeField] public GameObject WaitingRoom; [SerializeField] public GameObject BeforeStart; [SerializeField] public GameObject TakePicture; [SerializeField] public GameObject VotePicture; [SerializeField] public GameObject WaitingOtherPlayers; [SerializeField] public GameObject EndGame; private DatabaseReference realtimeDB; private Room myRoom; private DatabaseReference myOnlineRoom; private void Awake() { FirebaseInitializer.Instance.onFirebaseReady += Initialize; } private void Start() { currentExplanationTime = explanationTime; HomeConnection.SetActive(true); submitNewPlayer.interactable = false; } public GameState GetCurrentState() { return currentState; } private void Initialize() { FirebaseInitializer.Instance.onFirebaseReady -= Initialize; realtimeDB = FirebaseDatabase.DefaultInstance.RootReference; Debug.Log("Realtime DB initialized"); submitNewPlayer.interactable = true; } /// /// Send your name and game room to the server /// public void PlayerValidateNameAndServerRoom(string _name, string _code) { nameError.gameObject.SetActive(false); roomError.gameObject.SetActive(false); if (string.IsNullOrEmpty(_name)) { Debug.LogError("Player name is empty", this); nameError.text = "You have to put a valid name"; nameError.gameObject.SetActive(true); //TODO : MARINE : use the error label to explain to the user that they have forget to put a name return; } if (string.IsNullOrEmpty(_code)) { Debug.LogError("Room code is empty", this); roomError.text = "You have to put a room code"; roomError.gameObject.SetActive(true); //TODO : MARINE : use the error label to explain to the user that they have forget to put a room code return; } currentPlayer = new Player(_name); //check if the room exists, if not display an error message CheckIfRoomExists(_code, room => { if (room == null) { Debug.LogError("The room doesn't exists"); roomError.text = "Error: the room doesn't exists"; roomError.gameObject.SetActive(true); } else { myOnlineRoom = realtimeDB.Child("rooms").Child(_code); //if room exists, join it JoinRoom(() => { //then subscribe to it myOnlineRoom.ValueChanged += OnRoomUpdate; currentState = GameState.WaitingForOtherPlayersToJoin; players.Add(currentPlayer); WaitingRoom.SetActive(true); HomeConnection.SetActive(false); UpdateDisplayedListUser(); }); } }); } private void CheckIfRoomExists(string _roomCode, Action callback_Room) { realtimeDB.Child("rooms").Child(_roomCode).GetValueAsync().ContinueWithOnMainThread(task => { if (task.IsFaulted) { Debug.LogException(task.Exception); } else if (task.IsCompleted) { DataSnapshot snapshot = task.Result; if (snapshot == null) { callback_Room?.Invoke(null); } else { callback_Room?.Invoke(JsonUtility.FromJson(snapshot.GetRawJsonValue())); } } }); } /// /// Add this player to the room /// private void JoinRoom(Action callback_OnRoomJoined) { string JSON = JsonUtility.ToJson(currentPlayer); Debug.Log(JSON); try { myOnlineRoom.Child("players").Child(currentPlayer.id).SetRawJsonValueAsync(JSON).ContinueWithOnMainThread(task => { if (task.IsFaulted) { Debug.LogException(task.Exception); } else { Debug.Log($"{currentPlayer.name} has been added to the room", this); callback_OnRoomJoined?.Invoke(); } }); } catch (Exception ex) { Debug.LogException(ex); } } /// /// Call this only by the first player /// public void StartGame() { // send Start Game currentState = GameState.Explanation; WaitingRoom.SetActive(false); BeforeStart.SetActive(true); } /// /// Dislay on the screen the current prompt ask to you and another player /// Also show all the camera stuff /// /// The prompt to display public void MakeAProposition(Prompt _prompt) { currentState = GameState.MakeProposition; } /// /// Create a proposition from the picture taken and send it to server. /// Then go to next proposition (if any) or the page "WaitingForOtherPlayers" /// public void SubmitProposition() { Proposition temp = new Proposition(); } /// /// Display the voting page /// public void StartToVote() { } /// /// Choose one result and send it to the server /// Then go to the next vote (if any) or to the page "WaitingForOtherPlayers" /// public void Vote() { } /// /// Display the UI of the end screen /// public void DisplayEndScreen() { } /// /// Automatically called when something change in your room /// private void OnRoomUpdate(object sender, ValueChangedEventArgs e) { try { myRoom = JsonUtility.FromJson(e.Snapshot.GetRawJsonValue()); } catch (Exception ex) { Debug.LogException(ex); } switch (currentState) { case GameState.WaitingForOtherPlayersToJoin: { // players = new list en fonction de ce qu'envoie fangh UpdateDisplayedListUser(); break; } } } private void UpdateDisplayedListUser() { listPlayersUI.text = string.Empty; for (int i = 0; i < players.Count; i++) { listPlayersUI.text += "\n" + players[i].name; } } public void OnClickSubmitSignIn() { string playerName = playerNameField.text; string roomCode = roomCodeField.text; PlayerValidateNameAndServerRoom(playerName, roomCode); } } public enum GameState { EnteringName, WaitingForOtherPlayersToJoin, Explanation, MakeProposition, PropositionsSent, WaitingForOtherPlayers, VotingTime, Ending }