using System.Collections; using UnityEngine; using UnityEngine.UI; namespace EmeraldAI.Utility { public class EmeraldHealthBar : MonoBehaviour { #region Health Bar Variables Camera m_Camera; Canvas canvas; Image HealthBar; Image HealthBarDamage; CanvasGroup CG; Text AINameUI; Text AILevelUI; Coroutine C; EmeraldSystem EmeraldComponent; EmeraldUI EmeraldUI; EmeraldHealth EmeraldHealth; Coroutine CoroutineTransitionDamage; #endregion void Start() { InitializeHealthBar(); } /// /// Initialize the health bar. /// void InitializeHealthBar () { //Since the transform order of the health bar is always the same, get the parent's parent to get all need Emerald AI Components. canvas = GetComponent(); EmeraldUI = transform.parent.parent.GetComponent(); EmeraldHealth = transform.parent.parent.GetComponent(); EmeraldComponent = transform.parent.parent.GetComponent(); if (m_Camera == null) m_Camera = GameObject.FindGameObjectWithTag(EmeraldUI.CameraTag).GetComponent(); //Get a reference to the camera via the EmeraldUI.CameraTag. CG = GetComponent(); HealthBar = transform.Find("AI Health Bar Background/AI Health Bar").GetComponent(); HealthBarDamage = transform.Find("AI Health Bar Background/AI Health Bar (Damage)").GetComponent(); AINameUI = transform.Find("AI Name Text").GetComponent(); AILevelUI = transform.Find("AI Level Text").GetComponent(); EmeraldHealth.OnDeath += FadeOutUI; //Subscribe FadeOutUI to the OnDeath delegate. EmeraldHealth.OnTakeDamage += TransitionDamage; //Subscribe TransitionDamage to the OnTakeDamage delegate. EmeraldHealth.OnTakeCritDamage += TransitionDamage; //Subscribe TransitionDamage to the OnTakeCritDamage delegate. EmeraldHealth.OnHealRateTick += TransitionHealing; //Subscribe TransitionHealing to the OnHealRateTick delegate. EmeraldHealth.OnHealthChange += UpdateHealthUI; //Subscribe UpdateHealthUI to the OnHealthChange delegate. } void Update() { CalculateUI(); } public void CalculateUI() { if (m_Camera != null) { if (HealthBar != null) { canvas.transform.parent.LookAt(canvas.transform.parent.position + m_Camera.transform.rotation * Vector3.forward, m_Camera.transform.rotation * Vector3.up); float dist = Vector3.Distance(m_Camera.transform.position, transform.position); if (dist < EmeraldUI.MaxUIScaleSize) { canvas.transform.localScale = new Vector3(dist * 0.085f, dist * 0.085f, dist * 0.085f); } else { canvas.transform.localScale = new Vector3(EmeraldUI.MaxUIScaleSize * 0.085f, EmeraldUI.MaxUIScaleSize * 0.085f, EmeraldUI.MaxUIScaleSize * 0.085f); } } } } /// /// Fades out the UI when called. (This is handled automatically through the EmeraldHeath.OnDeath delegate). /// void FadeOutUI() { if (gameObject.activeSelf) { if (C != null) { StopCoroutine(C); } C = StartCoroutine(FadeOutUIInternal(0.0f, 1.5f)); } } void OnDisable() { if (EmeraldComponent != null && !EmeraldComponent.CombatComponent.CombatState) ResetValues(); //Resets the UI values back to their defaults. } IEnumerator FadeOutUIInternal(float DesiredValue, float TransitionTime) { HealthBar.fillAmount = ((float)EmeraldHealth.Health / (float)EmeraldHealth.StartHealth); float alpha = CG.alpha; float t = 0; while ((t / TransitionTime) < 1) { t += Time.deltaTime; Color newColor1 = new Color(1, 1, 1, Mathf.Lerp(alpha, DesiredValue, t)); CG.alpha = newColor1.a; AINameUI.color = new Color(AINameUI.color.r, AINameUI.color.g, AINameUI.color.b, newColor1.a); AILevelUI.color = new Color(AILevelUI.color.r, AILevelUI.color.g, AILevelUI.color.b, newColor1.a); yield return null; } gameObject.SetActive(false); } void TransitionDamage () { if (gameObject.activeSelf) { if (CoroutineTransitionDamage != null) StopCoroutine(CoroutineTransitionDamage); CoroutineTransitionDamage = StartCoroutine(TransitionDamageInternal()); } else { HealthBar.fillAmount = ((float)EmeraldHealth.Health / (float)EmeraldHealth.StartHealth); HealthBarDamage.fillAmount = HealthBar.fillAmount; } } IEnumerator TransitionDamageInternal () { HealthBar.fillAmount = ((float)EmeraldHealth.Health / (float)EmeraldHealth.StartHealth); float Start = HealthBarDamage.fillAmount; float t = 0; yield return new WaitForSeconds(0.75f); while ((t / 1f) < 1) { t += Time.deltaTime; HealthBarDamage.fillAmount = Mathf.Lerp(Start, HealthBar.fillAmount, t); yield return null; } } void TransitionHealing () { if (gameObject.activeSelf) { StartCoroutine(TransitionHealingInternal()); } else { HealthBar.fillAmount = ((float)EmeraldHealth.Health / (float)EmeraldHealth.StartHealth); HealthBarDamage.fillAmount = HealthBar.fillAmount; } } /// /// Updates the AI's health bar based on its current health. /// void UpdateHealthUI () { HealthBar.fillAmount = ((float)EmeraldHealth.Health / (float)EmeraldHealth.StartHealth); HealthBarDamage.fillAmount = HealthBar.fillAmount; } IEnumerator TransitionHealingInternal() { float HealAmount = ((float)EmeraldHealth.Health / (float)EmeraldHealth.StartHealth); float Start = HealthBar.fillAmount; float t = 0; while ((t / 1f) < 1) { t += Time.deltaTime; HealthBar.fillAmount = Mathf.Lerp(Start, HealAmount, t); HealthBarDamage.fillAmount = Mathf.Lerp(Start, HealAmount, t); yield return null; } } /// /// Resets the UI values back to their defaults. /// void ResetValues () { if (CG != null) { Color newColor1 = new Color(1, 1, 1, 1); CG.alpha = newColor1.a; AINameUI.color = new Color(AINameUI.color.r, AINameUI.color.g, AINameUI.color.b, newColor1.a); AILevelUI.color = new Color(AILevelUI.color.r, AILevelUI.color.g, AILevelUI.color.b, newColor1.a); HealthBar.fillAmount = 1; HealthBarDamage.fillAmount = 1; } } } }