using UnityEngine; using UnityEngine.UI; using TMPro; /// /// Attach to any manager GameObject in the create-lobby scene. /// On Start it nukes all Art placeholder children from the Canvas and builds /// a complete mobile-portrait lobby-configuration screen entirely in code. /// public class HostLobbyUI : MonoBehaviour { // ── Colours ─────────────────────────────────────────────────────────────── static Color H(string hex) { ColorUtility.TryParseHtmlString(hex, out var c); return c; } static readonly Color C_BG = H("#0D0F1A"); static readonly Color C_HDR = H("#141927"); static readonly Color C_CARD = H("#111525"); static readonly Color C_BORDER = H("#1E2540"); static readonly Color C_ACCENT = H("#3399FF"); static readonly Color C_GREEN = H("#2DB84B"); static readonly Color C_MUTED = new Color(0.47f, 0.53f, 0.67f); static readonly Color C_WHITE = Color.white; static readonly Color C_INPUT = H("#0A0D1A"); // ── Live values ─────────────────────────────────────────────────────────── private float _radius = 500f; private int _impostors = 1; private int _tasks = 5; private string _playerName = ""; // ── UI refs ─────────────────────────────────────────────────────────────── private TMP_Text _radiusValueLabel; private TMP_Text _impostorValueLabel; private TMP_Text _taskValueLabel; private TMP_Text _statusText; void Start() { // Pre-populate from GameManager defaults var gm = GameManager.Instance; if (gm != null) { _radius = (float)gm.pendingRadius; _impostors = gm.pendingImpostorCount; _tasks = gm.pendingTaskCount; _playerName = gm.displayName ?? ""; } var canvasGO = GameObject.Find("Canvas"); if (canvasGO == null) { Debug.LogError("[HostLobbyUI] No Canvas found!"); return; } // Nuke all Art placeholder children var kill = new System.Collections.Generic.List(); foreach (Transform child in canvasGO.transform) kill.Add(child.gameObject); foreach (var go in kill) DestroyImmediate(go); // Disable scene-changer components that bypass our logic foreach (var sc in canvasGO.GetComponentsInChildren(true)) sc.enabled = false; Build(canvasGO.GetComponent() ?? canvasGO.AddComponent()); } // ── Builder ─────────────────────────────────────────────────────────────── void Build(RectTransform root) { // Full-screen background var bg = MakeRT("BG", root); Stretch(bg); bg.gameObject.AddComponent(); Img(bg, C_BG); // ── Header bar ─────────────────────────────────────────────────────── var hdr = MakeRT("Header", root); Anchor(hdr, new Vector2(0,1), new Vector2(1,1), new Vector2(0,-80), new Vector2(0,0)); Img(hdr, C_HDR); var hdrTxt = Txt("Create Lobby", hdr, 28, C_WHITE, TextAlignmentOptions.Center, bold: true); Stretch(hdrTxt.rectTransform); // ── Scroll body ─────────────────────────────────────────────────────── var scroll = MakeRT("Scroll", root); Anchor(scroll, new Vector2(0,0), new Vector2(1,1), new Vector2(0,80), new Vector2(0,-80)); var sf = scroll.gameObject.AddComponent(); sf.horizontal = false; Img(scroll, new Color(0,0,0,0)); var content = MakeRT("Content", scroll); content.anchorMin = new Vector2(0,1); content.anchorMax = new Vector2(1,1); content.pivot = new Vector2(0.5f, 1); content.offsetMin = Vector2.zero; content.offsetMax = Vector2.zero; var vlg = content.gameObject.AddComponent(); vlg.padding = new RectOffset(16, 16, 12, 12); vlg.spacing = 12; vlg.childForceExpandWidth = true; vlg.childForceExpandHeight = false; var csf = content.gameObject.AddComponent(); csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize; sf.content = content; sf.viewport = scroll; // ── Player name card ───────────────────────────────────────────────── AddSectionLabel("PLAYER NAME", content); var nameCard = AddCard(content, 70); var nameInput = MakeInputField("Your name", nameCard, _playerName); Stretch(nameInput.GetComponent()); nameInput.onEndEdit.AddListener(v => { _playerName = v.Trim(); var gm2 = GameManager.Instance; if (gm2 != null) gm2.displayName = _playerName; PlayerPrefs.SetString("PlayerName", _playerName); }); // ── Radius card ─────────────────────────────────────────────────────── AddSectionLabel("PLAY AREA RADIUS", content); var radCard = AddCard(content, 110); var radRT = radCard.GetComponent(); var radLbl = MakeRT("RadLbl", radRT); Anchor(radLbl, new Vector2(0,1), new Vector2(1,1), new Vector2(12,-40), new Vector2(-12,-4)); var rt = radLbl.gameObject; var radTmp = rt.AddComponent(); radTmp.text = RadiusLabel(_radius); radTmp.fontSize = 20; radTmp.color = C_ACCENT; radTmp.alignment = TextAlignmentOptions.Center; _radiusValueLabel = radTmp; var slider = MakeRT("RadSlider", radRT).gameObject.AddComponent(); var srt = slider.GetComponent(); Anchor(srt, new Vector2(0,0), new Vector2(1,0), new Vector2(16, 14), new Vector2(-16, 44)); slider.minValue = 100; slider.maxValue = 2000; slider.value = _radius; BuildSliderVisuals(slider, C_ACCENT); slider.onValueChanged.AddListener(v => { _radius = v; _radiusValueLabel.text = RadiusLabel(v); var gm2 = GameManager.Instance; if (gm2 != null) gm2.pendingRadius = v; }); // ── Impostor count card ─────────────────────────────────────────────── AddSectionLabel("IMPOSTORS", content); var impCard = AddCard(content, 80); BuildStepper(impCard.GetComponent(), ref _impostors, 1, 4, v => { var gm2 = GameManager.Instance; if (gm2 != null) gm2.pendingImpostorCount = v; }, out _impostorValueLabel); // ── Task count card ─────────────────────────────────────────────────── AddSectionLabel("TASKS PER PLAYER", content); var taskCard = AddCard(content, 80); BuildStepper(taskCard.GetComponent(), ref _tasks, 1, 15, v => { var gm2 = GameManager.Instance; if (gm2 != null) gm2.pendingTaskCount = v; }, out _taskValueLabel); // ── Status text ─────────────────────────────────────────────────────── var statusCard = AddCard(content, 40); _statusText = Txt("", statusCard.GetComponent(), 16, C_MUTED, TextAlignmentOptions.Center); Stretch(_statusText.rectTransform); // ── Footer create button ────────────────────────────────────────────── var footer = MakeRT("Footer", root); Anchor(footer, new Vector2(0,0), new Vector2(1,0), new Vector2(0,0), new Vector2(0,80)); Img(footer, C_HDR); var btnRT = MakeRT("CreateBtn", footer); Anchor(btnRT, new Vector2(0.1f,0.15f), new Vector2(0.9f,0.85f), Vector2.zero, Vector2.zero); var btn = btnRT.gameObject.AddComponent