using System; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; public class PlayerHUD : MonoBehaviour { //HUD Bars [Header("Health Bar References")] [SerializeField] private Image healthBar; [SerializeField] private TextMeshProUGUI healthAmountTMP; [Header("Mana Bar References")] [SerializeField] private Image manaBar; [SerializeField] private TextMeshProUGUI manaAmountTMP; [Header("XP Bar References")] [SerializeField] private Image xpBarImage; [SerializeField] private TextMeshProUGUI currentXpAmountTMP; [SerializeField] private TextMeshProUGUI currentLevelMaxXpAmountTMP; [SerializeField] private TextMeshProUGUI lvlAmountTMP; [Header("Currency")] [SerializeField] private TextMeshProUGUI goldAmount; [SerializeField] private float barSpeed = 0.5f; //Player Controller PlayerController controller; //GameManager GameManager gameManager; private void Awake() { } // Start is called before the first frame update void Start() { controller = PlayerController.Instance; gameManager = GameManager.Instance; goldAmount.text = gameManager.PlayerGold.ToString(); lvlAmountTMP.text = gameManager.PlayerLevel.ToString(); currentXpAmountTMP.text = gameManager.PlayerCurrentXP.ToString() + " XP "; currentLevelMaxXpAmountTMP.text = gameManager.TargetLevelXP.ToString() + " XP "; controller.OnHealthChanged += UpdateHealthBar; controller.OnManaChanged += UpdateManaBar; gameManager.OnXpGained += UpdateXPBar; gameManager.OnLevelUp += UpdateLvlNumber; gameManager.OnGoldAdded += UpdateGoldAmount; } private void OnDestroy() { controller.OnHealthChanged -= UpdateHealthBar; controller.OnManaChanged -= UpdateManaBar; } // Update is called once per frame void Update() { } private void UpdateHealthBar(int newHealth) { // Start coroutine for smooth health bar animation StartCoroutine(SmoothHealthBarUpdate(newHealth)); } public void UpdateManaBar(float newMana) { // Clamp the newMana to avoid exceeding MaxMana newMana = Mathf.Clamp(newMana, 0, controller.MaxMana); // Update the mana bar's fill amount directly manaBar.fillAmount = newMana / controller.MaxMana; // Update the text to reflect the current mana manaAmountTMP.text = $"{(int)newMana} / {controller.MaxMana}"; manaAmountTMP.color = Color.Lerp(Color.red, Color.white, manaBar.fillAmount); } public void UpdateXPBar(int newXp) { StartCoroutine(SmoothUpdateXPBar(newXp)); } private IEnumerator SmoothUpdateXPBar(int newXp) { float targetFillAmount = (float)newXp / gameManager.TargetLevelXP; while (Mathf.Abs(xpBarImage.fillAmount - targetFillAmount) > 0.01f) { xpBarImage.fillAmount = Mathf.Lerp(xpBarImage.fillAmount, targetFillAmount, Time.deltaTime * barSpeed); currentXpAmountTMP.text = $"{(int)(xpBarImage.fillAmount * gameManager.TargetLevelXP)} XP"; yield return null; } // Ensure the final value is accurate after the loop xpBarImage.fillAmount = targetFillAmount; currentXpAmountTMP.text = $"{newXp} XP"; } public void UpdateLvlNumber(int lvl) { lvlAmountTMP.text = lvl.ToString(); //Updates the level currentLevelMaxXpAmountTMP.text = gameManager.TargetLevelXP.ToString() + " XP "; //Updates the current level xp amount } private void UpdateGoldAmount(int amount) { int targetAmount = amount; int currentAmount = gameManager.PlayerGold; StartCoroutine(SmoothGoldTransition(targetAmount, currentAmount)); } //Smoothly interpolates the new amount of gold private IEnumerator SmoothGoldTransition(int targetAmount, int currentAmount) { currentAmount = int.Parse(goldAmount.text); // Smooth transition over time float duration = 1f; // Duration for the transition float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; int result = (int)Mathf.Lerp(currentAmount, targetAmount, elapsed / duration); goldAmount.text = result.ToString(); yield return null; } // Ensure the final value is set goldAmount.text = targetAmount.ToString(); } // Coroutine for smooth health bar animation private IEnumerator SmoothHealthBarUpdate(int newHealth) { float targetFillAmount = (float)newHealth / 100; // Normalize new health value (0 to 1) while (Mathf.Abs(healthBar.fillAmount - targetFillAmount) > 0.01f) { healthBar.fillAmount = Mathf.Lerp(healthBar.fillAmount, targetFillAmount, Time.deltaTime * barSpeed); healthAmountTMP.text = $"{(int)(healthBar.fillAmount * 100)} / {controller.MaxHealth}"; // Update text to match normalized value yield return null; } // Ensure the fill amount is set exactly to the target at the end healthBar.fillAmount = targetFillAmount; healthAmountTMP.text = $"{newHealth} / {controller.MaxHealth}"; // Ensure final text update matches target health } }