using Invector; using Invector.vCharacterController; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; namespace Beyond { public class bSpriteHealth : MonoBehaviour { public vHealthController healthControl; public Camera specificCamera; [Tooltip("UI to show on receive damage")] [SerializeField] protected GameObject healthBar; public bool lookToCamera = true; [Header("UI properties")] [SerializeField] protected Slider _healthSlider; [SerializeField] protected Slider _damageDelay; //this is weird [SerializeField] protected float timeToHideDamageDelay; [SerializeField] protected float _smoothRegenDelay; [SerializeField] protected Text _damageCounter; [SerializeField] protected float _damageCounterTimer = 1.5f; [SerializeField] protected float _regenTimeCounter = 1.5f; [SerializeField] protected bool _showDamageType = true; private bool inDelay; private float damage; private float currentSmoothDamage; public Transform cameraMain; private bool isForced; public float damageDelaySpeed = 1f; public Transform healthCanvas; // Start is called before the first frame update private void Start() { if (specificCamera) { cameraMain = specificCamera.transform; } else { cameraMain = Camera.main ? Camera.main.transform : null; } healthControl.onReceiveDamage.AddListener(Damage); _healthSlider.maxValue = healthControl.maxHealth; _healthSlider.value = healthControl.currentHealth; _damageDelay.maxValue = healthControl.maxHealth; _damageDelay.value = healthControl.currentHealth; _damageCounter.text = string.Empty; if (healthBar) healthBar.SetActive(false); } private void OnEnable() { _damageDelay.value = _healthSlider.value; damage = 0; _damageCounter.text = string.Empty; inDelay = false; } private void SpriteBehaviour() { if (lookToCamera && cameraMain != null) { // transform.LookAt(cameraMain.position, Vector3.up); healthCanvas.LookAt(cameraMain.position, Vector3.up); } if (healthControl == null || healthControl.currentHealth <= 0) Destroy(gameObject); _healthSlider.value = healthControl.currentHealth; } private void Update() { if (!healthBar && !isForced) { SpriteBehaviour(); } } public void Damage(vDamage damage) { try { this.damage += damage.damageValue; _damageCounter.text = this.damage.ToString("00") + ((_showDamageType && !string.IsNullOrEmpty(damage.damageType)) ? (" : by " + damage.damageType) : ""); _healthSlider.value -= damage.damageValue; if (!inDelay && healthControl && gameObject.activeInHierarchy) StartCoroutine(DamageDelay()); } catch { Destroy(this); } } public void ForceShowHpBar() { if (healthBar) { isForced = true; healthBar.SetActive(true); } } public void ForceHideHpBar() { if (healthBar) { healthBar.SetActive(false); isForced = false; } } public void StartHealthRegen() { StartCoroutine(HealthDelay()); } private IEnumerator HealthDelay() { inDelay = true; ForceShowHpBar(); while (_healthSlider.value < _healthSlider.maxValue) { _healthSlider.value += _smoothRegenDelay; yield return null; } inDelay = false; yield return new WaitForSeconds(_regenTimeCounter); if (healthBar) { ForceHideHpBar(); } } private IEnumerator DamageDelay() { inDelay = true; if (healthBar) { SpriteBehaviour(); } if (healthBar) { healthBar.SetActive(true); } yield return new WaitForSeconds(timeToHideDamageDelay); while (_damageDelay.value > _healthSlider.value) { if (healthBar) { SpriteBehaviour(); } _damageDelay.value -= damageDelaySpeed * Time.deltaTime; yield return null; } inDelay = false; yield return new WaitForSeconds(_damageCounterTimer); damage = 0; _damageCounter.text = string.Empty; if (healthBar && !isForced) { healthBar.SetActive(false); } } } }