using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; using TMPro; public class MainMenu : MonoBehaviour { const string CurrentStageKey = "CurrentStage"; const string SelectedTowerKey = "SelectedTower"; const string TeslaTowerUnlockedKey = "TeslaTowerUnlocked"; const string CannonTowerId = "cannon"; const string TeslaTowerId = "tesla"; Canvas canvas; RectTransform contentRoot; TextMeshProUGUI homeTabLabel; TextMeshProUGUI towersTabLabel; TextMeshProUGUI deckTabLabel; void Start() { Time.timeScale = 1f; if (!PlayerPrefs.HasKey(CurrentStageKey)) PlayerPrefs.SetInt(CurrentStageKey, 1); if (!PlayerPrefs.HasKey(SelectedTowerKey)) PlayerPrefs.SetString(SelectedTowerKey, CannonTowerId); if (PlayerPrefs.GetInt(CurrentStageKey, 1) > 1) PlayerPrefs.SetInt(TeslaTowerUnlockedKey, 1); if (!IsTowerUnlocked(PlayerPrefs.GetString(SelectedTowerKey, CannonTowerId))) PlayerPrefs.SetString(SelectedTowerKey, CannonTowerId); BuildMenu(); ShowHome(); } public void StartGame() { if (!IsTowerUnlocked(PlayerPrefs.GetString(SelectedTowerKey, CannonTowerId))) PlayerPrefs.SetString(SelectedTowerKey, CannonTowerId); PlayerPrefs.Save(); SceneManager.LoadScene("SampleScene"); } public void QuitGame() { Debug.Log("Game Quit!"); Application.Quit(); } void BuildMenu() { Canvas[] existingCanvases = FindObjectsByType(); canvas = null; foreach (Canvas existingCanvas in existingCanvases) { if (existingCanvas.GetComponent() != null) { canvas = existingCanvas; continue; } Destroy(existingCanvas.gameObject); } if (canvas == null) { GameObject canvasObject = new GameObject("MainMenuCanvas", typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster)); canvas = canvasObject.GetComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; CanvasScaler scaler = canvasObject.GetComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(900f, 600f); scaler.matchWidthOrHeight = 0.5f; } for (int i = canvas.transform.childCount - 1; i >= 0; i--) Destroy(canvas.transform.GetChild(i).gameObject); UITheme.StyleCanvas(canvas, new Vector2(900f, 600f)); RectTransform root = CreatePanel("MainMenuRoot", canvas.transform, UITheme.Background); root.anchorMin = Vector2.zero; root.anchorMax = Vector2.one; root.offsetMin = Vector2.zero; root.offsetMax = Vector2.zero; UITheme.AddAccent(root, "TopGlow", new Color(0.12f, 0.54f, 0.76f, 0.9f), new Vector2(0f, 1f), Vector2.one, new Vector2(0f, -4f), Vector2.zero); UITheme.AddAccent(root, "LeftRail", new Color(0.08f, 0.3f, 0.44f, 0.55f), Vector2.zero, new Vector2(0f, 1f), Vector2.zero, new Vector2(4f, 0f)); UITheme.AddAccent(root, "RightRail", new Color(0.08f, 0.3f, 0.44f, 0.55f), new Vector2(1f, 0f), Vector2.one, new Vector2(-4f, 0f), Vector2.zero); TextMeshProUGUI title = CreateText("Title", root, "THE TOWER", 46f, FontStyles.Bold, TextAlignmentOptions.Center); RectTransform titleRect = title.rectTransform; titleRect.anchorMin = new Vector2(0f, 1f); titleRect.anchorMax = new Vector2(1f, 1f); titleRect.pivot = new Vector2(0.5f, 1f); titleRect.anchoredPosition = new Vector2(0f, -30f); titleRect.sizeDelta = new Vector2(0f, 58f); UITheme.StyleText(title, UITheme.Text, true); TextMeshProUGUI subtitle = CreateText("Subtitle", root, "Best Tower Defense Game ever 100%", 13f, FontStyles.Bold, TextAlignmentOptions.Center); subtitle.color = UITheme.Cyan; RectTransform subtitleRect = subtitle.rectTransform; subtitleRect.anchorMin = new Vector2(0f, 1f); subtitleRect.anchorMax = new Vector2(1f, 1f); subtitleRect.pivot = new Vector2(0.5f, 1f); subtitleRect.anchoredPosition = new Vector2(0f, -82f); subtitleRect.sizeDelta = new Vector2(0f, 24f); RectTransform nav = CreateRect("Nav", root); nav.anchorMin = new Vector2(0f, 0f); nav.anchorMax = new Vector2(1f, 0f); nav.pivot = new Vector2(0.5f, 0f); nav.anchoredPosition = Vector2.zero; nav.sizeDelta = new Vector2(0f, 58f); HorizontalLayoutGroup navLayout = nav.gameObject.AddComponent(); navLayout.spacing = 0f; navLayout.childAlignment = TextAnchor.MiddleCenter; navLayout.childControlWidth = true; navLayout.childControlHeight = true; navLayout.childForceExpandWidth = true; navLayout.childForceExpandHeight = true; Button homeButton = CreateButton("HomeButton", nav, "HOME", () => ShowHome()); homeTabLabel = homeButton.GetComponentInChildren(); Button towersButton = CreateButton("TowersButton", nav, "TOWERS", () => ShowTowers()); towersTabLabel = towersButton.GetComponentInChildren(); Button deckButton = CreateButton("DeckButton", nav, "DECK", () => ShowDeck()); deckTabLabel = deckButton.GetComponentInChildren(); contentRoot = CreatePanel("Content", root, UITheme.Panel); contentRoot.anchorMin = new Vector2(0.5f, 0.5f); contentRoot.anchorMax = new Vector2(0.5f, 0.5f); contentRoot.pivot = new Vector2(0.5f, 0.5f); contentRoot.anchoredPosition = new Vector2(0f, -12f); contentRoot.sizeDelta = new Vector2(640f, 350f); UITheme.AddTopAccent(contentRoot, UITheme.Cyan); Button quitButton = CreateButton("QuitButton", root, "QUIT", QuitGame); RectTransform quitRect = quitButton.GetComponent(); quitRect.anchorMin = new Vector2(1f, 1f); quitRect.anchorMax = new Vector2(1f, 1f); quitRect.pivot = new Vector2(1f, 1f); quitRect.anchoredPosition = new Vector2(-20f, -20f); quitRect.sizeDelta = new Vector2(112f, 40f); } void ShowHome() { SetTabState(homeTabLabel); ClearContent(); int stage = Mathf.Max(1, PlayerPrefs.GetInt(CurrentStageKey, 1)); TextMeshProUGUI heading = CreateText("Heading", contentRoot, "MISSION CONTROL", 24f, FontStyles.Bold, TextAlignmentOptions.Center); PlaceTop(heading.rectTransform, -34f, 36f); heading.color = UITheme.CyanBright; TextMeshProUGUI stageText = CreateText("Stage", contentRoot, $"STAGE {stage}", 42f, FontStyles.Bold, TextAlignmentOptions.Center); PlaceCenter(stageText.rectTransform, 0f, 76f, 320f, 60f); TextMeshProUGUI detail = CreateText("Detail", contentRoot, "15 WAVES // COMMANDERS AT 05, 10, 15", 15f, FontStyles.Bold, TextAlignmentOptions.Center); PlaceCenter(detail.rectTransform, 0f, 8f, 460f, 34f); detail.color = UITheme.TextMuted; Button playButton = CreateButton("PlayButton", contentRoot, "PLAY", StartGame); RectTransform playRect = playButton.GetComponent(); PlaceCenter(playRect, 0f, -104f, 240f, 58f); } void ShowTowers() { SetTabState(towersTabLabel); ClearContent(); TextMeshProUGUI heading = CreateText("Heading", contentRoot, "TOWERS", 26f, FontStyles.Bold, TextAlignmentOptions.Center); PlaceTop(heading.rectTransform, -34f, 36f); heading.color = UITheme.CyanBright; CreateTowerCard("CannonTowerCard", "CANNON TOWER", "Explosive shells with splash and heavy upgrade scaling.", CannonTowerId, true, -216f); CreateTowerCard("TeslaTowerCard", "TESLA TOWER", "Rapid arcs with longer range and steadier damage.", TeslaTowerId, IsTowerUnlocked(TeslaTowerId), 216f); } void ShowDeck() { SetTabState(deckTabLabel); ClearContent(); string selectedTower = PlayerPrefs.GetString(SelectedTowerKey, CannonTowerId); string towerName = selectedTower == TeslaTowerId ? "TESLA TOWER" : "CANNON TOWER"; TextMeshProUGUI heading = CreateText("Heading", contentRoot, $"{towerName} DECK", 24f, FontStyles.Bold, TextAlignmentOptions.Center); PlaceTop(heading.rectTransform, -22f, 32f); heading.color = UITheme.CyanBright; TextMeshProUGUI detail = CreateText("Detail", contentRoot, "CURRENTLY EQUIPPED TOWER // ALL CARDS", 12f, FontStyles.Bold, TextAlignmentOptions.Center); PlaceTop(detail.rectTransform, -52f, 20f); detail.color = UITheme.TextMuted; RectTransform scrollView = CreateRect("DeckScrollView", contentRoot); PlaceCenter(scrollView, 0f, -38f, 604f, 248f); ScrollRect scrollRect = scrollView.gameObject.AddComponent(); scrollRect.horizontal = false; scrollRect.vertical = true; scrollRect.movementType = ScrollRect.MovementType.Clamped; scrollRect.scrollSensitivity = 22f; RectTransform viewport = CreatePanel("Viewport", scrollView, new Color(0.025f, 0.04f, 0.06f, 0.72f)); viewport.anchorMin = Vector2.zero; viewport.anchorMax = Vector2.one; viewport.offsetMin = Vector2.zero; viewport.offsetMax = Vector2.zero; Mask mask = viewport.gameObject.AddComponent(); mask.showMaskGraphic = true; RectTransform grid = CreateRect("Cards", viewport); grid.anchorMin = new Vector2(0f, 1f); grid.anchorMax = new Vector2(1f, 1f); grid.pivot = new Vector2(0.5f, 1f); grid.anchoredPosition = Vector2.zero; grid.sizeDelta = Vector2.zero; GridLayoutGroup layout = grid.gameObject.AddComponent(); layout.padding = new RectOffset(12, 12, 12, 12); layout.cellSize = new Vector2(184f, 94f); layout.spacing = new Vector2(12f, 12f); layout.constraint = GridLayoutGroup.Constraint.FixedColumnCount; layout.constraintCount = 3; ContentSizeFitter fitter = grid.gameObject.AddComponent(); fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize; scrollRect.viewport = viewport; scrollRect.content = grid; foreach (UpgradeManager.CardDefinition card in UpgradeManager.GetCardsForTower(selectedTower)) CreateDeckCard(grid, card); } void CreateDeckCard(Transform parent, UpgradeManager.CardDefinition definition) { RectTransform card = CreatePanel(definition.title + "Card", parent, UITheme.PanelRaised); UITheme.AddTopAccent(card, GetRarityColor(definition.rarity), 3f); Button button = card.gameObject.AddComponent