From e486ea0e15cd928b11179f3d773c50c88ebf3f3e Mon Sep 17 00:00:00 2001 From: Nik Jovanovski <73746991+Slygone@users.noreply.github.com> Date: Sat, 3 Jan 2026 03:13:05 +0100 Subject: [PATCH 1/7] UI layout new --- Assets/Scripts/Core/Combat/CombatManager.cs | 13 + Assets/Scripts/Core/Combat/CombatUI.cs | 528 ++++++++++++++++---- 2 files changed, 450 insertions(+), 91 deletions(-) diff --git a/Assets/Scripts/Core/Combat/CombatManager.cs b/Assets/Scripts/Core/Combat/CombatManager.cs index 36d36d1..bff7bce 100644 --- a/Assets/Scripts/Core/Combat/CombatManager.cs +++ b/Assets/Scripts/Core/Combat/CombatManager.cs @@ -165,6 +165,19 @@ public void OnPlayerAttack() OnPlayerAttackTarget(target); } } + + /// + /// End the player's turn manually (called by End Turn button). + /// + public void EndPlayerTurn() + { + if (!combatActive || !isPlayerTurn) return; + + GameLog.Combat(GameLog.Join("EndTurnClicked")); + + isPlayerTurn = false; + StartCoroutine(DelayedEnemyTurn()); + } public void OnPlayerAttackTarget(CombatEnemy target) { diff --git a/Assets/Scripts/Core/Combat/CombatUI.cs b/Assets/Scripts/Core/Combat/CombatUI.cs index ea6c604..7ab8f63 100644 --- a/Assets/Scripts/Core/Combat/CombatUI.cs +++ b/Assets/Scripts/Core/Combat/CombatUI.cs @@ -57,6 +57,19 @@ public class CombatUI : MonoBehaviour private GameObject potionTooltipPanel; private TextMeshProUGUI potionTooltipText; + + // New UI components for Slay the Spire style layout + private TextMeshProUGUI playerNameText; + private TextMeshProUGUI playerGoldText; + private TextMeshProUGUI floorText; + private TextMeshProUGUI floorSubtitleText; + private TextMeshProUGUI energyText; + private GameObject energyCircle; + private Button endTurnButton; + private GameObject topBar; + private GameObject bottomBar; + private GameObject relicsPanel; + private Player currentPlayer; void Awake() { @@ -123,69 +136,141 @@ private GameObject CreateCombatPanel(Transform parent) rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; + // Semi-transparent dark overlay (less opaque than before for gameplay visibility) var bg = panel.AddComponent(); - bg.color = new Color(0, 0, 0, 0.85f); - - var titleObj = new GameObject("CombatTitle"); - titleObj.transform.SetParent(panel.transform, false); - var titleRect = titleObj.AddComponent(); - titleRect.anchorMin = new Vector2(0.3f, 0.88f); - titleRect.anchorMax = new Vector2(0.7f, 0.95f); - titleRect.offsetMin = Vector2.zero; - titleRect.offsetMax = Vector2.zero; - combatTitleText = titleObj.AddComponent(); - combatTitleText.text = "COMBAT"; - combatTitleText.alignment = TextAlignmentOptions.Center; - combatTitleText.fontSize = 28; - combatTitleText.color = Color.white; + bg.color = new Color(0.05f, 0.05f, 0.1f, 0.75f); - CreatePlayerHealthBar(panel.transform); + // Create UI sections + CreateTopBar(panel.transform); CreateEnemyContainer(panel.transform); - CreateSkillButtons(panel.transform); + CreateBottomActionBar(panel.transform); return panel; } + + private void CreateTopBar(Transform parent) + { + // Top bar container + topBar = new GameObject("TopBar"); + topBar.transform.SetParent(parent, false); + var topBarRect = topBar.AddComponent(); + topBarRect.anchorMin = new Vector2(0, 0.92f); + topBarRect.anchorMax = new Vector2(1, 1); + topBarRect.offsetMin = new Vector2(15, 0); + topBarRect.offsetMax = new Vector2(-15, -8); + + // Left section: Player info + var leftSection = new GameObject("LeftSection"); + leftSection.transform.SetParent(topBar.transform, false); + var leftRect = leftSection.AddComponent(); + leftRect.anchorMin = new Vector2(0, 0); + leftRect.anchorMax = new Vector2(0.35f, 1); + leftRect.offsetMin = Vector2.zero; + leftRect.offsetMax = Vector2.zero; + + var leftLayout = leftSection.AddComponent(); + leftLayout.spacing = 20; + leftLayout.childAlignment = TextAnchor.MiddleLeft; + leftLayout.childControlWidth = false; + leftLayout.childControlHeight = true; + leftLayout.childForceExpandWidth = false; + leftLayout.padding = new RectOffset(10, 0, 0, 0); + + // Player name + var nameObj = new GameObject("PlayerName"); + nameObj.transform.SetParent(leftSection.transform, false); + playerNameText = nameObj.AddComponent(); + playerNameText.text = "THE WARRIOR"; + playerNameText.fontSize = 22; + playerNameText.fontStyle = FontStyles.Bold; + playerNameText.color = new Color(0.9f, 0.85f, 0.7f); + var nameLayout = nameObj.AddComponent(); + nameLayout.preferredWidth = 180; + + // HP display (heart icon + HP) + var hpObj = new GameObject("HPDisplay"); + hpObj.transform.SetParent(leftSection.transform, false); + var hpText = hpObj.AddComponent(); + hpText.text = "♥ 72/80"; + hpText.fontSize = 18; + hpText.color = Color.white; + playerHealthText = hpText; + var hpLayout = hpObj.AddComponent(); + hpLayout.preferredWidth = 90; + + // Gold display + var goldObj = new GameObject("GoldDisplay"); + goldObj.transform.SetParent(leftSection.transform, false); + playerGoldText = goldObj.AddComponent(); + playerGoldText.text = "⚙ 100"; + playerGoldText.fontSize = 18; + playerGoldText.color = Color.white; + var goldLayout = goldObj.AddComponent(); + goldLayout.preferredWidth = 80; + + // Center section: Floor indicator + var centerSection = new GameObject("CenterSection"); + centerSection.transform.SetParent(topBar.transform, false); + var centerRect = centerSection.AddComponent(); + centerRect.anchorMin = new Vector2(0.35f, 0); + centerRect.anchorMax = new Vector2(0.65f, 1); + centerRect.offsetMin = Vector2.zero; + centerRect.offsetMax = Vector2.zero; + + var centerLayout = centerSection.AddComponent(); + centerLayout.childAlignment = TextAnchor.MiddleCenter; + centerLayout.childControlWidth = true; + centerLayout.childControlHeight = true; + centerLayout.spacing = -2; + + var floorObj = new GameObject("FloorText"); + floorObj.transform.SetParent(centerSection.transform, false); + floorText = floorObj.AddComponent(); + floorText.text = "FLOOR 1"; + floorText.fontSize = 24; + floorText.fontStyle = FontStyles.Bold; + floorText.alignment = TextAlignmentOptions.Center; + floorText.color = Color.white; + + var subtitleObj = new GameObject("FloorSubtitle"); + subtitleObj.transform.SetParent(centerSection.transform, false); + floorSubtitleText = subtitleObj.AddComponent(); + floorSubtitleText.text = ""; + floorSubtitleText.fontSize = 12; + floorSubtitleText.alignment = TextAlignmentOptions.Center; + floorSubtitleText.color = new Color(0.7f, 0.7f, 0.7f); + + // Keep combatTitleText reference for special titles (Boss Fight, etc.) + combatTitleText = floorText; + + // Right section: Potions and settings (placeholder for now) + var rightSection = new GameObject("RightSection"); + rightSection.transform.SetParent(topBar.transform, false); + var rightRect = rightSection.AddComponent(); + rightRect.anchorMin = new Vector2(0.65f, 0); + rightRect.anchorMax = new Vector2(1, 1); + rightRect.offsetMin = Vector2.zero; + rightRect.offsetMax = Vector2.zero; + + // Potions will be added here later + CreatePotionContainer(rightSection.transform); + } private void CreatePlayerHealthBar(Transform parent) { - var container = new GameObject("PlayerHealth"); + // HP is now displayed in the top bar, but we still need a reference for floating text + var container = new GameObject("PlayerHealthRef"); container.transform.SetParent(parent, false); var rect = container.AddComponent(); - // Raise HP bar to avoid any overlap with the skill bar - rect.anchorMin = new Vector2(0.1f, 0.16f); - rect.anchorMax = new Vector2(0.4f, 0.20f); + rect.anchorMin = new Vector2(0.02f, 0.92f); + rect.anchorMax = new Vector2(0.15f, 0.98f); rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; - var bgImage = container.AddComponent(); - bgImage.color = new Color(0.2f, 0.2f, 0.2f, 1f); - - var fill = new GameObject("Fill"); - fill.transform.SetParent(container.transform, false); - - var fillRect = fill.AddComponent(); - fillRect.anchorMin = Vector2.zero; - fillRect.anchorMax = Vector2.one; - fillRect.offsetMin = new Vector2(2, 2); - fillRect.offsetMax = new Vector2(-2, -2); - - playerHealthFill = fill.AddComponent(); - playerHealthFill.color = Color.green; - - var textObj = new GameObject("Text"); - textObj.transform.SetParent(container.transform, false); - - var textRect = textObj.AddComponent(); - textRect.anchorMin = Vector2.zero; - textRect.anchorMax = Vector2.one; - textRect.offsetMin = Vector2.zero; - textRect.offsetMax = Vector2.zero; - - playerHealthText = textObj.AddComponent(); - playerHealthText.alignment = TextAlignmentOptions.Center; - playerHealthText.fontSize = 18; - playerHealthText.color = Color.white; + // Hidden fill for compatibility + playerHealthFill = container.AddComponent(); + playerHealthFill.color = Color.clear; playerHealthBar = container; } @@ -196,13 +281,14 @@ private void CreateEnemyContainer(Transform parent) container.transform.SetParent(parent, false); var rect = container.AddComponent(); - rect.anchorMin = new Vector2(0.1f, 0.4f); - rect.anchorMax = new Vector2(0.9f, 0.85f); + // Positioned in center area, leaving room for top bar and bottom action bar + rect.anchorMin = new Vector2(0.1f, 0.25f); + rect.anchorMax = new Vector2(0.9f, 0.88f); rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; var layout = container.AddComponent(); - layout.spacing = 20; + layout.spacing = 30; layout.childAlignment = TextAnchor.MiddleCenter; layout.childControlWidth = true; layout.childControlHeight = true; @@ -212,35 +298,245 @@ private void CreateEnemyContainer(Transform parent) enemyContainer = container.transform; } - private void CreateSkillButtons(Transform parent) - { - var container = new GameObject("ActionButtons"); - container.transform.SetParent(parent, false); - actionButtonContainer = container; - var containerRect = container.AddComponent(); - containerRect.anchorMin = new Vector2(0.10f, 0.03f); - containerRect.anchorMax = new Vector2(0.90f, 0.13f); - containerRect.offsetMin = Vector2.zero; - containerRect.offsetMax = Vector2.zero; + private void CreateBottomActionBar(Transform parent) + { + // Bottom bar container with rounded dark background + bottomBar = new GameObject("BottomBar"); + bottomBar.transform.SetParent(parent, false); + var bottomRect = bottomBar.AddComponent(); + bottomRect.anchorMin = new Vector2(0.05f, 0.02f); + bottomRect.anchorMax = new Vector2(0.95f, 0.20f); + bottomRect.offsetMin = Vector2.zero; + bottomRect.offsetMax = Vector2.zero; + + var bottomBg = bottomBar.AddComponent(); + bottomBg.color = new Color(0.12f, 0.10f, 0.08f, 0.95f); + + // Energy Circle (left side) + CreateEnergyCircle(bottomBar.transform); + + // Skill Cards Container (center) + var skillsContainer = new GameObject("SkillsContainer"); + skillsContainer.transform.SetParent(bottomBar.transform, false); + actionButtonContainer = skillsContainer; + var skillsRect = skillsContainer.AddComponent(); + skillsRect.anchorMin = new Vector2(0.12f, 0.1f); + skillsRect.anchorMax = new Vector2(0.78f, 0.9f); + skillsRect.offsetMin = Vector2.zero; + skillsRect.offsetMax = Vector2.zero; + + // Dark rounded background for skill cards + var skillsBg = skillsContainer.AddComponent(); + skillsBg.color = new Color(0.08f, 0.07f, 0.06f, 0.9f); + + var skillsLayout = skillsContainer.AddComponent(); + skillsLayout.spacing = 8; + skillsLayout.padding = new RectOffset(10, 10, 8, 8); + skillsLayout.childAlignment = TextAnchor.MiddleCenter; + skillsLayout.childControlWidth = true; + skillsLayout.childControlHeight = true; + skillsLayout.childForceExpandWidth = true; + skillsLayout.childForceExpandHeight = true; + + // Create skill cards with hotkey indicators + skill1Button = CreateSkillCard(skillsContainer.transform, "Skill1", "1", new Color(0.6f, 0.2f, 0.2f, 1f), OnSkill1Clicked, out skill1Text, out skill1Tooltip); + skill2Button = CreateSkillCard(skillsContainer.transform, "Skill2", "2", new Color(0.2f, 0.4f, 0.7f, 1f), OnSkill2Clicked, out skill2Text, out skill2Tooltip); + skill3Button = CreateSkillCard(skillsContainer.transform, "Skill3", "3", new Color(0.5f, 0.4f, 0.3f, 1f), OnSkill3Clicked, out skill3Text, out skill3Tooltip); + skill4Button = CreateSkillCard(skillsContainer.transform, "Skill4", "Q", new Color(0.3f, 0.3f, 0.4f, 1f), OnSkill4Clicked, out skill4Text, out skill4Tooltip); + skill5Button = CreateSkillCard(skillsContainer.transform, "Skill5", "R", new Color(0.7f, 0.5f, 0.2f, 1f), OnSkill5Clicked, out skill5Text, out skill5Tooltip); + + // Back button (hidden by default, shown during targeting) + backButton = CreateSkillCard(skillsContainer.transform, "Back", "ESC", new Color(0.4f, 0.4f, 0.4f, 1f), OnBackClicked, out _, out _); + backButton.gameObject.SetActive(false); - var layout = container.AddComponent(); - layout.spacing = 6; - layout.childControlWidth = true; - layout.childControlHeight = true; - layout.childForceExpandWidth = true; - layout.childForceExpandHeight = true; + // End Turn Button (right side) + CreateEndTurnButton(bottomBar.transform); + } + + private void CreateEnergyCircle(Transform parent) + { + energyCircle = new GameObject("EnergyCircle"); + energyCircle.transform.SetParent(parent, false); + var circleRect = energyCircle.AddComponent(); + circleRect.anchorMin = new Vector2(0.01f, 0.15f); + circleRect.anchorMax = new Vector2(0.11f, 0.85f); + circleRect.offsetMin = Vector2.zero; + circleRect.offsetMax = Vector2.zero; + + // Background circle + var circleBg = energyCircle.AddComponent(); + circleBg.color = new Color(0.15f, 0.25f, 0.4f, 1f); + + // Energy number + var energyNumObj = new GameObject("EnergyNumber"); + energyNumObj.transform.SetParent(energyCircle.transform, false); + var energyNumRect = energyNumObj.AddComponent(); + energyNumRect.anchorMin = new Vector2(0, 0.3f); + energyNumRect.anchorMax = new Vector2(1, 0.9f); + energyNumRect.offsetMin = Vector2.zero; + energyNumRect.offsetMax = Vector2.zero; + + energyText = energyNumObj.AddComponent(); + energyText.text = "0"; + energyText.fontSize = 36; + energyText.fontStyle = FontStyles.Bold; + energyText.alignment = TextAlignmentOptions.Center; + energyText.color = new Color(0.4f, 0.7f, 1f); + + // "ENERGY" label + var labelObj = new GameObject("EnergyLabel"); + labelObj.transform.SetParent(energyCircle.transform, false); + var labelRect = labelObj.AddComponent(); + labelRect.anchorMin = new Vector2(0, 0); + labelRect.anchorMax = new Vector2(1, 0.3f); + labelRect.offsetMin = Vector2.zero; + labelRect.offsetMax = Vector2.zero; + + var labelText = labelObj.AddComponent(); + labelText.text = "ENERGY"; + labelText.fontSize = 10; + labelText.alignment = TextAlignmentOptions.Center; + labelText.color = new Color(0.6f, 0.8f, 1f); + } + + private void CreateEndTurnButton(Transform parent) + { + var endTurnObj = new GameObject("EndTurnButton"); + endTurnObj.transform.SetParent(parent, false); + var btnRect = endTurnObj.AddComponent(); + btnRect.anchorMin = new Vector2(0.80f, 0.1f); + btnRect.anchorMax = new Vector2(0.98f, 0.9f); + btnRect.offsetMin = Vector2.zero; + btnRect.offsetMax = Vector2.zero; - // 5 skill buttons (no attack button) - skill1Button = CreateActionButton(container.transform, "Skill1", "Skill 1", new Color(0.2f, 0.5f, 0.7f, 1f), OnSkill1Clicked, out skill1Text, out skill1Tooltip); - skill2Button = CreateActionButton(container.transform, "Skill2", "Skill 2", new Color(0.2f, 0.5f, 0.7f, 1f), OnSkill2Clicked, out skill2Text, out skill2Tooltip); - skill3Button = CreateActionButton(container.transform, "Skill3", "Skill 3", new Color(0.2f, 0.5f, 0.7f, 1f), OnSkill3Clicked, out skill3Text, out skill3Tooltip); - skill4Button = CreateActionButton(container.transform, "Skill4", "Skill 4", new Color(0.2f, 0.5f, 0.7f, 1f), OnSkill4Clicked, out skill4Text, out skill4Tooltip); - skill5Button = CreateActionButton(container.transform, "Skill5", "Ultimate", new Color(0.7f, 0.4f, 0.2f, 1f), OnSkill5Clicked, out skill5Text, out skill5Tooltip); - - backButton = CreateActionButton(container.transform, "Back", "BACK", new Color(0.5f, 0.5f, 0.5f, 1f), OnBackClicked, out _, out _); - backButton.gameObject.SetActive(false); - - CreatePotionContainer(parent); + var btnBg = endTurnObj.AddComponent(); + btnBg.color = new Color(0.85f, 0.55f, 0.15f, 1f); + + endTurnButton = endTurnObj.AddComponent