Space-Smash-Out/Assets/Scripts/Multiplayer/LobbyManager.cs

225 lines
5.1 KiB
C#

using System.Collections.Generic;
using System.Reflection;
using FishNet.Object;
using log4net;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class LobbyManager : MonoBehaviour
{
private static readonly ILog Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
#region Fields
[SerializeField] private TMP_InputField usernameLabel;
[SerializeField] private TextMeshProUGUI roomNameLabel;
[SerializeField] private Canvas lobbyCanvas;
[SerializeField] private Canvas roomCanvas;
[SerializeField] private Transform roomItemContainer;
[SerializeField] private Transform playerItemContainer;
[SerializeField] private GameObject roomItemPrefab;
[SerializeField] private GameObject playerItemPrefab;
private Dictionary<string, GameObject> playerRoomItems = new();
private Dictionary<string, GameObject> roomItems = new();
private Canvas previousCanvas;
private SSOLobby lobby;
#endregion
#region Init
private void Awake()
{
Locator.RegisterService<LobbyManager>(this);
lobbyCanvas.gameObject.SetActive(false);
roomCanvas.gameObject.SetActive(false);
}
public void InitClient(SSOLobby lobby)
{
this.lobby = lobby;
lobby.SignIn();
}
#endregion
#region Events
private void SubscribeToRoomAndPlayerEvents(bool subscribe)
{
if (subscribe)
{
lobby.OnMemberJoined += OnMemberJoined;
lobby.OnMemberLeft += OnMemberLeft;
lobby.OnRoomCreated += OnRoomCreated;
lobby.OnRoomDeleted += OnRoomDeleted;
lobby.OnRoomStarted += OnRoomStarted;
}
else
{
lobby.OnMemberJoined -= OnMemberJoined;
lobby.OnMemberLeft -= OnMemberLeft;
lobby.OnRoomCreated -= OnRoomCreated;
lobby.OnRoomDeleted -= OnRoomDeleted;
lobby.OnRoomStarted -= OnRoomStarted;
}
}
private void OnRoomStarted(Room room)
{
UpdateRoomUI(room.name);
}
private void OnRoomDeleted(Room room)
{
RemoveRoomUI(room.name);
}
private void OnRoomCreated(Room room)
{
AddRoomUI(room.name);
}
private void OnMemberLeft(NetworkObject target)
{
string username = target.Owner.FirstObject.GetComponent<ClientInstance>().Username;
RemoveRoomPlayerUI(username);
}
private void OnMemberJoined(NetworkObject target)
{
string username = target.Owner.FirstObject.GetComponent<ClientInstance>().Username;
AddRoomPlayerUI(username);
}
#endregion
#region Navigation
public void ChangeCanvas(Canvas canvas)
{
if (previousCanvas != null)
previousCanvas.gameObject.SetActive(false);
if (canvas == previousCanvas)
{
Log.Info("This canvas is already active");
return;
}
canvas.gameObject.SetActive(true);
previousCanvas = canvas;
}
public void EnterGame()
{
SubscribeToRoomAndPlayerEvents(false);
}
public void EnterLobby()
{
ChangeCanvas(lobbyCanvas);
}
public void SignInSuccess(string username)
{
Log.Debug($"User: {username} just signed in with the server.");
usernameLabel.text = username;
SubscribeToRoomAndPlayerEvents(true);
EnterLobby();
}
public void SignInFailed(string failedReason)
{
Log.Warn($"User wasn't signed in because: {failedReason}");
}
public void OnCreateRoom(Room r)
{
ChangeCanvas(roomCanvas);
roomNameLabel.text = r.name;
}
public void OnJoinRoom(Room r)
{
ChangeCanvas(roomCanvas);
roomNameLabel.text = r.name;
}
public void OnLeaveRoom()
{
ChangeCanvas(lobbyCanvas);
}
#endregion
#region UI
// Room
public void AddRoomUI(string roomName)
{
if (roomItems.ContainsKey(roomName))
return;
GameObject go = Instantiate(roomItemPrefab);
go.transform.SetParent(roomItemContainer, false);
go.GetComponentsInChildren<TextMeshProUGUI>()[0].text = roomName;
go.GetComponentInChildren<Button>().onClick.AddListener(() => OnJoinRoomClick(roomName));
roomItems.Add(roomName, go);
}
public void RemoveRoomUI(string roomName)
{
Destroy(roomItems[roomName]);
roomItems.Remove(roomName);
}
public void UpdateRoomUI(string roomName)
{
roomItems[roomName].GetComponent<Button>().interactable = false;
}
// Player
public void ResetRoomPlayerUI()
{
foreach (Transform t in roomItemContainer)
Destroy(t.gameObject);
playerRoomItems.Clear();
}
public void AddRoomPlayerUI(string username)
{
if (roomItems.ContainsKey(username))
return;
GameObject go = Instantiate(playerItemPrefab);
go.transform.SetParent(playerItemContainer, false);
go.GetComponentsInChildren<TextMeshProUGUI>()[0].text = username;
playerRoomItems.Add(username, go);
}
public void RemoveRoomPlayerUI(string username)
{
Destroy(playerRoomItems[username]);
playerRoomItems.Remove(username);
}
#endregion
#region Buttons
public void OnCreateRoomClick()
{
lobby.CreateRoom();
}
public void OnJoinRoomClick(string roomName)
{
lobby.JoinRoom(roomName);
}
public void OnLeaveRoomClick()
{
lobby.LeaveRoom();
}
public void OnStartGameClick()
{
}
public void OnRefreshLobbyClick()
{
}
public void OnLeaveLobbyClick()
{
GameObject menuCam = GameObject.Find("Main Menu Camera");
menuCam.TryGetComponent(out Animator camAnimator);
if (!camAnimator)
{
Log.Error("Can't go back to main menu, camera animator not found.");
}
camAnimator.SetTrigger("BackToIdleTrigger");
// TODO Disconnect the client from the server
}
#endregion
}