Newer
Older
TheVengeance-Project-IADE-Unity2D / Assets / Scripts / Player / PlayerHUD.cs
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
    }
}