fgm24/Assets/Scripts/Player/HealthComponent.cs

97 lines
2.5 KiB
C#

using UnityEngine;
using UnityEngine.Events;
using TMPro;
using System;
using UnityUtils;
public class HealthComponent : MonoBehaviour, ISquezeDamageReceiver
{
[SerializeField] private bool onlyCallZeroHealthOnce = true;
[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<Vector3, float> OnHealthChangeAtPos;
public UnityEvent OnHealthZero;
public UnityEvent<float, float> OnHealthChange;
[Header("Squeze Damage")]
[SerializeField]
float minThreshold = 1f;
[SerializeField]
float squezeDamageScalor = 1f;
bool alreadyReachedZero = false;
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) {
if (alreadyReachedZero && onlyCallZeroHealthOnce) return;
alreadyReachedZero = true;
// Make sure to flush accumulated when dying
if (accumulatedDamageInTick > 1f)
OnHealthChangeAtPos?.Invoke(transform.position.Add(y: 2f), accumulatedDamageInTick);
OnHealthZero?.Invoke();
int blood = (int)(maxHealth * 100.0f * BloodComputeShader.Instance.scoreMult);
BloodComputeShader.Instance.createBlood(transform.position, blood/2, maxHealth / 8.0f);
BloodComputeShader.Instance.createBlood(transform.position, blood / 2, maxHealth / 8.0f);
}
}
public void TakeSquezeDamage(float squezeDamage)
{
if (squezeDamage < minThreshold) return;
TakeDamage((int) Mathf.Round(squezeDamage * squezeDamageScalor));
}
public void EnemyKill()
{
Destroy(gameObject);
}
}