using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using MegaKoop.Steam; using MegaKoop.Networking; using TMPro; namespace MegaKoop.UI { /// /// UGUI Multiplayer Lobby Controller integrated with SteamLobbyService. /// Builds players list dynamically, handles host/join/invite/kick/ready/start. /// public class UGUIMultiplayerLobbyController : MonoBehaviour { // Panels [Header("Optional Root Ref (assigned by builder)")] [SerializeField] private GameObject panelLobbyRef; private GameObject panelLobby; private GameObject groupJoin; private GameObject groupHost; // Header & Code private TMP_Text textStatus; private TMP_Text textLobbyCodeValue; private Button btnCopyCode; // Tabs private Button btnHostTab; private Button btnJoinTab; // Join private TMP_InputField inputLobbyCode; private Button btnConnect; // Host private TMP_Dropdown ddMaxPlayers; private Toggle tgPublicLobby; private Button btnCreateLobby; // Players private TMP_Text textPlayerCount; private ScrollRect scrollPlayers; private Transform contentPlayers; private GameObject playerItemTemplate; private GameObject emptyPlayers; // Friends picker (fallback when overlay unavailable) private GameObject panelFriends; private Transform contentFriends; private GameObject emptyFriends; private Button btnBackFromFriends; private Button btnCloseFriendsOverlay; // Host controls private Button btnInviteFriends; private Button btnKickSelected; // Ready & footer private Button btnToggleReady; private Button btnStartGame; private Button btnLeaveLobby; private Button btnBackFromLobby; // Selection private string selectedPlayerSteamId = string.Empty; // Steam service private SteamLobbyService steam; // Local state cache private bool IsInLobby => steam != null && steam.IsInLobby; private bool IsHost => steam != null && steam.IsHost; private string LobbyCode => steam != null ? steam.LobbyCode : string.Empty; private bool clientStartedFromSignal = false; private bool leftDueToKick = false; private void Awake() { // Find UI (including inactive) panelLobby = FindAnyGO("Panel_Lobby"); groupJoin = FindAnyGO("Group_Join"); groupHost = FindAnyGO("Group_Host"); textStatus = FindText("Text_Status"); textLobbyCodeValue = FindText("Text_LobbyCodeValue"); btnCopyCode = FindButton("Button_CopyCode"); btnHostTab = FindButton("Button_HostTab"); btnJoinTab = FindButton("Button_JoinTab"); inputLobbyCode = FindInput("Input_LobbyCode"); btnConnect = FindButton("Button_Connect"); ddMaxPlayers = FindDropdown("Dropdown_MaxPlayers"); tgPublicLobby = FindToggle("Toggle_PublicLobby"); btnCreateLobby = FindButton("Button_CreateLobby"); textPlayerCount = FindText("Text_PlayerCount"); scrollPlayers = FindScroll("Scroll_Players"); contentPlayers = FindAnyGO("Content_PlayersList")?.transform; emptyPlayers = FindAnyGO("Empty_Players"); playerItemTemplate = FindAnyGO("PlayerItemTemplate"); btnInviteFriends = FindButton("Button_InviteFriends"); btnKickSelected = FindButton("Button_KickSelected"); btnToggleReady = FindButton("Button_ToggleReady"); btnStartGame = FindButton("Button_StartGame"); btnLeaveLobby = FindButton("Button_LeaveLobby"); btnBackFromLobby = FindButton("Button_BackFromLobby"); // Friends picker panelFriends = FindAnyGO("Panel_Friends"); contentFriends = FindAnyGO("Content_FriendsList")?.transform; emptyFriends = FindAnyGO("Empty_Friends"); btnBackFromFriends = FindButton("Button_BackFromFriends"); btnCloseFriendsOverlay = FindButton("Button_CloseFriendsOverlay"); EnsureSteamServices(); RegisterSteamEvents(); WireButtonEvents(); ValidateUI(); // Initial view: Host tab ShowHostTab(); UpdateUI(); } private void ShowFriendsPanel() { if (panelFriends) panelFriends.SetActive(true); EnsureFriendsGridSetup(); RebuildFriendsList(); } private void HideFriendsPanel() { if (panelFriends) panelFriends.SetActive(false); } private void RebuildFriendsList() { if (contentFriends == null || steam == null) return; // Clear existing var toDestroy = new List(); foreach (Transform child in contentFriends) toDestroy.Add(child.gameObject); foreach (var go in toDestroy) DestroyImmediate(go); var friends = steam.GetFriends(); if (friends.Count == 0) { if (emptyFriends) emptyFriends.SetActive(true); return; } if (emptyFriends) emptyFriends.SetActive(false); foreach (var f in friends) { // Icon button cell only var cell = new GameObject($"Friend_{f.steamId}", typeof(RectTransform), typeof(Image), typeof(Button)); cell.transform.SetParent(contentFriends, false); var img = cell.GetComponent(); if (steam.TryGetAvatarSprite(f.steamId, out var spr, false)) { img.sprite = spr; img.color = Color.white; img.preserveAspect = true; } else { img.sprite = null; img.color = new Color(0.3f,0.6f,0.3f,1f); } var rt = (RectTransform)cell.transform; rt.sizeDelta = new Vector2(72,72); var btn = cell.GetComponent