Game Room Manager

mail@pastecode.io avatar
unknown
csharp
9 days ago
9.7 kB
3
Indexable
Never
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Unity.Netcode;
using EditorAttributes;
using System.Collections;
using DG.Tweening;
using Unity.Services.Multiplayer;
using Unity.Collections.LowLevel.Unsafe;
using System.Collections.Generic;

public class LobbyRoomManager : MonoBehaviour
{
    WaitForSeconds _oneSecondWaitTime = new(1);
    [SerializeField] TextMeshProUGUI _statusText;
    Tween _statusTextChangeTween;

    [SerializeField] TextMeshProUGUI _lobbyRoomCodeText;
    [SerializeField] Button _readyButton;

    [Header("Host")]
    [SerializeField] TextMeshProUGUI _hostNameText;
    [SerializeField] Image _hostLeaderImage;
    [SerializeField] GameObject _hostReadyDisplay;

    [Header("Guest")]
    [SerializeField] TextMeshProUGUI _guestNameText;
    [SerializeField] Image _guestLeaderImage;
    [SerializeField] GameObject _guestReadyDisplay;

    [Space(10)]
    [SerializeField] Button _openDeckSelectButton;
    [SerializeField] Image _selectedDeckLeaderImage;
    [SerializeField] TextMeshProUGUI _selectedDeckNameText;
    [SerializeField/*, ReadOnly*/] DeckSO _selectedDeck;
    bool _isReady = false;
    bool _countingDown = false;
    Tween _countdownTween;

    //Network Variables
    NetworkVariable<int> _hostLeaderId;
    NetworkVariable<int> _guestLeaderId;

    //Empty Values
    [SerializeField] Sprite _emptyDeckImage;
    string _emptyDeckName = "Ningun mazo seleccionado";
    string _defaultGuestName = "Esperando oponente...";

    //Temp
    [Header("Temp")]
    [SerializeField/*, ReadOnly*/] DeckSO _defaultDeck;
    public ISession _currentSession { get; private set; }
    public bool RoomFound { get; private set; }
    Tween _updateTextOnPlayerJoined;

    void Start()
    {
        _currentSession = null;
        _selectedDeck = null;
        AddButtonListeners();
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Backslash))
            _selectedDeck = _defaultDeck;
    }

    void SetStatusText(string text, float duration = 3f)
    {
        if (_statusTextChangeTween != null)
        {
            _statusTextChangeTween.Kill();
        }

        duration -= 0.3f;

        _statusText.text = text;
        _statusTextChangeTween = _statusText.DOFade(1, 0.15f).From(0).OnComplete(() =>
        {
            _statusTextChangeTween = _statusText.DOFade(1, duration).From(1).OnComplete(() =>
            {
                _statusTextChangeTween = _statusText.DOFade(0, 0.15f).OnComplete(() =>
                {
                    _statusText.text = "";
                    _statusTextChangeTween = null;
                });
            });
        });
    }

    void AddButtonListeners()
    {
        _readyButton.onClick.AddListener(() => { StartCoroutine(ReadyUp()); });
        _openDeckSelectButton.onClick.AddListener(() => { SelectDeck(); });
    }

    public async void CreateRoom()
    {
        // Check if player is in a lobby already, if so quit it
        RoomFound = false;

        try
        {
            var options = new SessionOptions
            {
                MaxPlayers = 2
            }.WithRelayNetwork();

            var session = await MultiplayerService.Instance.CreateSessionAsync(options);
            RoomFound = true;
            _currentSession = session;
            session.PlayerPropertiesChanged += UpdatePlayerStatus;
            session.CurrentPlayer.SetProperty("PlayerName", new(AuthenticationManager.Instance.PlayerName()));
            session.CurrentPlayer.SetProperty("PlayerReady", new("false"));
            await session.SaveCurrentPlayerDataAsync();

            //_hostNameText.text = AuthenticationManager.Instance.PlayerName();
            _lobbyRoomCodeText.text = session.Code;
        }
        catch (SessionException e)
        {
            Debug.Log(e);
        }
    }

    public async void JoinRoom(string roomCode)
    {
        RoomFound = false;

        try
        {
            var session = await MultiplayerService.Instance.JoinSessionByCodeAsync(roomCode);
            RoomFound = true;
            _currentSession = session;

            session.PlayerPropertiesChanged += UpdatePlayerStatus;
            session.CurrentPlayer.SetProperty("PlayerName", new(AuthenticationManager.Instance.PlayerName()));
            session.CurrentPlayer.SetProperty("PlayerReady", new("false"));
            await session.SaveCurrentPlayerDataAsync();

            //_guestNameText.text = AuthenticationManager.Instance.PlayerName();
            _lobbyRoomCodeText.text = session.Code;
        }
        catch (SessionException e)
        {
            Debug.Log(e);
        }
    }

    void UpdatePlayerStatus()
    {
        float transitionDuration = 0.25f;
        bool isGuestReady = false;
        bool isHostReady = false;

        if (_updateTextOnPlayerJoined != null)
            _updateTextOnPlayerJoined.Kill();

        _updateTextOnPlayerJoined = _readyButton.image.DOFade(1, transitionDuration).From(1).OnComplete(() =>
        {
            foreach (var player in _currentSession.Players)
            {
                var playerId = player.Id;
                var playerName = player.Properties["PlayerName"].Value;
                var playerReady = bool.Parse(player.Properties["PlayerReady"].Value);

                if (_currentSession.Host == playerId)
                {
                    isHostReady = playerReady;
                    _hostReadyDisplay.SetActive(playerReady);
                    _hostNameText.text = playerName;
                }
                else
                {
                    isGuestReady = playerReady;
                    _guestReadyDisplay.SetActive(playerReady);
                    _guestNameText.text = playerName;
                }
            }

            CheckForPlayersReady(isGuestReady, isHostReady);
        });


    }

    void CheckForPlayersReady(bool guestReady, bool hostReady)
    {
        float waitTimeToStart = 5f;

        if (!_countingDown)
        {
            if (guestReady && hostReady)
            {
                //Start countdown
                _countingDown = true;
                SetStatusText("Comenzando juego...", waitTimeToStart - 1);

                if (_countdownTween != null)
                    _countdownTween.Kill();


                _countdownTween = _updateTextOnPlayerJoined = _readyButton.image.DOFade(1, waitTimeToStart - 1f).From(1).OnComplete(() =>
                {
                    _readyButton.interactable = false;

                    _countdownTween = _updateTextOnPlayerJoined = _readyButton.image.DOFade(1, 1f).From(1).OnComplete(() =>
                    {
                        SetStatusText("Cargando...", 5f);
                        StartGame();
                    });
                });
            }
        }
        else
        {
            if (!guestReady || !hostReady)
            {
                //Game cancelled
                SetStatusText("Partida Cancelada...", 5f);

                if (_countdownTween != null)
                    _countdownTween.Kill();

                _countdownTween = _updateTextOnPlayerJoined = _readyButton.image.DOFade(1, 1f).From(1).OnComplete(() =>
                {
                    _readyButton.interactable = true;
                });
            }
        }
    }

    public void QuitLobby()
    {
        //Remove this player from lobby
        //If it's the host, close the lobby and kick guest if any

        //Ready = false and make buttons interactable again
        //Clear Player Data

        _selectedDeckNameText.text = _emptyDeckName;
        _selectedDeck = null;
        _isReady = false;

        if (!_currentSession.IsHost)
            _guestNameText.text = _defaultGuestName;

        ChangeReadyStatus();
    }

    public void SelectDeck()
    {

    }

    public void OpenDeckSelectMenu()
    {

    }

    IEnumerator ReadyUp()
    {
        if (!_isReady)
        {
            if (_selectedDeck == null)
            {
                SetStatusText("No hay ningun mazo seleccionado", 2f);
                _readyButton.interactable = false;
                _openDeckSelectButton.interactable = false;

                yield return _oneSecondWaitTime;
                yield return _oneSecondWaitTime;

                _readyButton.interactable = true;
                _openDeckSelectButton.interactable = true;
                yield return null;
            }
            else
            {
                _isReady = true;
                ChangeReadyStatus();

                _readyButton.interactable = false;
                _openDeckSelectButton.interactable = false;

                yield return _oneSecondWaitTime;
                _readyButton.interactable = true;
            }
        }
        else
        {
            _isReady = false;
            ChangeReadyStatus();
            _readyButton.interactable = false;
            yield return _oneSecondWaitTime;
            _readyButton.interactable = true;
            _openDeckSelectButton.interactable = true;
        }

    }

    async void ChangeReadyStatus()
    {
        var session = _currentSession;
        session.CurrentPlayer.SetProperty("PlayerReady", new(_isReady.ToString()));
        await session.SaveCurrentPlayerDataAsync();
    }

    public void StartGame()
    {
        Debug.Log("Partida comenzo.");
    }
}
Leave a Comment