using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; public class HealthBar : MonoBehaviour { public float ScalingFactor; private RectTransform rectTransform; private RectTransform mainBar; private TextMeshProUGUI text; private List bars; private RectTransform border; private RawImage border1img, border2img; private PlayerController player; private void Awake() { rectTransform = GetComponent(); mainBar = transform.Find("Range").GetComponent(); bars = new List(); for (int i = 0; i < transform.childCount; i++) { Transform child = transform.GetChild(i); if (child.name.StartsWith("Overheal ")) bars.Add(child.GetComponent()); } bars.Sort((a, b) => int.Parse(a.name.Substring(9)).CompareTo(int.Parse(b.name.Substring(9)))); bars.Insert(0, mainBar); player = FindObjectOfType(); text = mainBar.Find("Display").GetComponent(); border = transform.Find("Border").GetComponent(); border1img = border.GetChild(0).GetComponent(); border2img = border.GetChild(1).GetComponent(); Tick(true); } private int currentHealthBefore; private float prevHealth; private void Update() => Tick(false); private void Tick(bool instant) { float size = Mathf.Log10(player.BaseStats.MaxHealth) * ScalingFactor; float desiredHealth = player.CurrentHealth; float ratio = desiredHealth / player.BaseStats.MaxHealth; float borderSize = 16 + 8 * Mathf.Max(0, Mathf.Ceil(ratio - 1)); float curAlpha = border1img.color.r; if (player.CurrentHealth < currentHealthBefore) { // Calculate difference and add white flash. float addAlpha = (float)(currentHealthBefore - player.CurrentHealth) / player.BaseStats.MaxHealth; addAlpha = Mathf.Pow(addAlpha, 0.5f); curAlpha = 1 - (1 - addAlpha) * (1 - curAlpha); } curAlpha = Mathf.Lerp(curAlpha, 0, Time.deltaTime * 5); border1img.color = new Color(curAlpha, curAlpha, curAlpha, 1); border2img.color = new Color(curAlpha, curAlpha, curAlpha, 1); if (!instant) { desiredHealth = Mathf.Lerp(prevHealth, desiredHealth, Time.deltaTime * 5); ratio = desiredHealth / player.BaseStats.MaxHealth; borderSize = Mathf.Lerp(border.sizeDelta.y, 16 + 8 * Mathf.Max(0, Mathf.Ceil(ratio * 0.999f - 1)), Time.deltaTime * 20); } for (int i = 0; i < bars.Count; i++) { float thisPart = Mathf.Clamp01(ratio); RectTransform bar = bars[i]; rectTransform.sizeDelta = new Vector2(size, rectTransform.sizeDelta.y); bar.sizeDelta = new Vector2((thisPart - 1) * size, 0); bar.localPosition = new Vector2(0.5f * size * thisPart, bar.localPosition.y); ratio--; } text.text = Mathf.RoundToInt(desiredHealth).ToString(); border.sizeDelta = new Vector2(border.sizeDelta.x, borderSize); border.localPosition = new Vector2(border.localPosition.x, -8 - borderSize / 2); prevHealth = desiredHealth; currentHealthBefore = player.CurrentHealth; } public void DecreaseCurrentHealthBefore() => currentHealthBefore--; // Goofy ahh hack. }