using UnityEngine; using UnityEngine.UI; public class PlayerUIManager : MonoBehaviour { [Header("References")] [Tooltip("Drag the Player (or the GameObject with PlayerStats) here")] public PlayerStats playerStats; [Header("UI Bars (Sliders)")] [Tooltip("Assign if you are using Unity UI Sliders for your bars")] public Slider healthBar; public Slider manaBar; public Slider staminaBar; [Header("UI Bars (Images - Fill Method)")] [Tooltip("Assign if you are using UI Images with Image Type set to 'Filled'")] public Image healthFill; public Image manaFill; public Image staminaFill; [Header("Combat UI")] public BowAimLayerController bowAimLayerController; [Tooltip("A Slider that fills up from 0 to 1 as the bow is drawn.")] public Slider bowDrawBar; [Header("Quest UI")] [Tooltip("The parent GameObject that holds all the Quest UI elements (allows us to hide the whole window when empty)")] public GameObject questUIPanel; [Tooltip("The TextMeshPro text for the name of the Quest")] public TMPro.TextMeshProUGUI questNameText; [Tooltip("The container transform where the Objective prefabs will be spawned (e.g., a Vertical Layout Group)")] public Transform objectivesContainer; [Tooltip("The prefab for a single objective row (Should have the QuestObjectiveUI script on it)")] public QuestObjectiveUI objectivePrefab; [Header("Interaction UI")] [Tooltip("The parent GameObject for the interaction popup")] public GameObject interactionPanel; [Tooltip("The TMPro Text that shows the primary interaction prompt (e.g., 'Collect')")] public TMPro.TextMeshProUGUI interactionText; [Tooltip("The secondary TMPro Text for the interaction prompt (e.g., 'Press E' or the Item Name)")] public TMPro.TextMeshProUGUI interactionSecondaryText; [Header("Crosshair UI")] [Tooltip("The crosshair image in the center of the screen")] public GameObject crosshairImage; private void Start() { if (playerStats == null) { Debug.LogWarning("PlayerUIManager: PlayerStats reference is missing! Please assign it in the Inspector."); } // Initialize Slider max values if they are being used if (healthBar != null) healthBar.maxValue = playerStats.maxHealth; if (manaBar != null) manaBar.maxValue = playerStats.maxMana; if (staminaBar != null) staminaBar.maxValue = playerStats.maxStamina; if (bowDrawBar != null) { bowDrawBar.minValue = 0f; bowDrawBar.maxValue = 1f; bowDrawBar.value = 0f; } // Try to connect to the Quest Manager to listen for updates if (QuestManager.Instance != null) { QuestManager.Instance.onQuestUpdated += DrawQuestUI; DrawQuestUI(); // Draw initial state } } private void OnDestroy() { // Unsubscribe to prevent memory leaks if (QuestManager.Instance != null) { QuestManager.Instance.onQuestUpdated -= DrawQuestUI; } } private void DrawQuestUI() { // If there's no Quest Manager or no active quest, hide the UI completely if (QuestManager.Instance == null || QuestManager.Instance.activeQuest == null || string.IsNullOrEmpty(QuestManager.Instance.activeQuest.questName)) { if (questUIPanel != null) questUIPanel.SetActive(false); return; } Quest activeQuest = QuestManager.Instance.activeQuest; // 1. Show the panel and update the Name if (questUIPanel != null) questUIPanel.SetActive(true); if (questNameText != null) questNameText.text = activeQuest.questName; // 2. Clear existing objectives in the container if (objectivesContainer != null) { foreach (Transform child in objectivesContainer) { Destroy(child.gameObject); } // 3. Spawn a prefab for each objective if (objectivePrefab != null) { bool foundActive = false; foreach (var objective in activeQuest.objectives) { QuestObjectiveUI newObjUI = Instantiate(objectivePrefab, objectivesContainer); // Determine if THIS objective is the active one // (The first incomplete objective in the list) bool isThisActive = false; if (!objective.isCompleted && !foundActive) { isThisActive = true; foundActive = true; } string countText = ""; if (objective.requiresCount) { countText = $" ({objective.currentCount}/{objective.targetCount})"; } newObjUI.Setup(objective.description, isThisActive, objective.isCompleted, countText); } } } } private void Update() { UpdateBars(); UpdateCombatUI(); UpdateCrosshair(); } private void UpdateCrosshair() { if (crosshairImage != null) { // Only show crosshair if we have a bow equipped and are currently holding aim/draw bool shouldShow = bowAimLayerController != null && bowAimLayerController.IsAiming && bowAimLayerController.IsDrawing; crosshairImage.SetActive(shouldShow); } } private void UpdateBars() { if (playerStats == null) return; // 1. Update Sliders (if assigned) if (healthBar != null) healthBar.value = playerStats.currentHealth; if (manaBar != null) manaBar.value = playerStats.currentMana; if (staminaBar != null) staminaBar.value = playerStats.currentStamina; // 2. Update Image Fills (if assigned) if (healthFill != null) healthFill.fillAmount = playerStats.currentHealth / playerStats.maxHealth; if (manaFill != null) manaFill.fillAmount = playerStats.currentMana / playerStats.maxMana; if (staminaFill != null) staminaFill.fillAmount = playerStats.currentStamina / playerStats.maxStamina; } private void UpdateCombatUI() { if (bowDrawBar != null && bowAimLayerController != null) { float drawPercentage = bowAimLayerController.CurrentDrawPercentage; bowDrawBar.value = drawPercentage; // Optional: Hide the bar completely if we aren't drawing the bow bowDrawBar.gameObject.SetActive(drawPercentage > 0f); } } }