using UnityEngine; using UnityEngine.Events; using TMPro; using System; using UnityUtils; public class HealthComponent : MonoBehaviour, ISquezeDamageReceiver { [SerializeField] float maxHealth = 100; [SerializeField] float damageTickDelay = 0.25f; private float currentDamageTick = 0f; private float accumulatedDamageInTick = 0f; public float currentHealth { get; private set; } public static event Action OnHealthChangeAtPos; public UnityEvent OnHealthZero; public UnityEvent OnHealthChange; [Header("Squeze Damage")] [SerializeField] float minThreshold = 1f; [SerializeField] float squezeDamageScalor = 1f; void Awake() { currentHealth = maxHealth; } void Update() { if (currentDamageTick < Time.time) { if (accumulatedDamageInTick < 1f) return; OnHealthChangeAtPos?.Invoke(transform.position.Add(y: 2f), accumulatedDamageInTick); currentDamageTick = Time.time + damageTickDelay; accumulatedDamageInTick = 0f; } } public float getMaxHealth() { return maxHealth; } public void setMaxHealth(float amount, bool heal = false) { maxHealth = amount; if (heal) currentHealth = amount; } public void TakeDamage(float damage) { currentHealth -= damage; OnHealthChange?.Invoke(currentHealth + damage, currentHealth); accumulatedDamageInTick += damage; if (currentHealth <= 0) { // Make sure to flush accumulated when dying if (accumulatedDamageInTick > 1f) OnHealthChangeAtPos?.Invoke(transform.position.Add(y: 2f), accumulatedDamageInTick); OnHealthZero?.Invoke(); BloodComputeShader.Instance.createBlood(transform.position, (int)(maxHealth *maxHealth * BloodComputeShader.Instance.scoreMult), maxHealth / 8.0f); } } public void TakeSquezeDamage(float squezeDamage) { if (squezeDamage < minThreshold) return; TakeDamage((int) Mathf.Round(squezeDamage * squezeDamageScalor)); } public void EnemyKill() { Destroy(gameObject); } }