103 lines
2.4 KiB
C#

using System.Collections;
using Polyart;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening; // DOTween
public class HealthManager : MonoBehaviour, IDamageable
{
[Header("Health")]
public float maxHealth = 100f;
public float health = 100f;
[Header("Regen")]
public bool enableRegen = true;
public float regenPerSecond = 1.5f;
public float regenDelayAfterDamage = 4f;
[Header("UI")]
public Image healthFillImage; // optional fillAmount
bool isDead = false;
float regenResumeTime = 0f;
void Awake()
{
health = Mathf.Clamp(health, 0, maxHealth);
InitUI();
}
void Update()
{
if (!enableRegen || isDead) return;
if (Time.time < regenResumeTime) return;
if (health >= maxHealth) return;
SetHealth(Mathf.Min(maxHealth, health + regenPerSecond * Time.deltaTime));
}
public void ApplyDamage(float amount) => TakeDamage(amount);
public bool IsDead() => isDead;
public void TakeDamage(float damage)
{
if (isDead || damage <= 0f) return;
SetHealth(Mathf.Max(0f, health - damage));
regenResumeTime = Time.time + Mathf.Max(0f, regenDelayAfterDamage);
if (health <= 0f) Die();
}
public void Heal(float amount)
{
if (amount <= 0f || isDead) return;
SetHealth(Mathf.Min(maxHealth, health + amount));
}
void SetHealth(float newValue)
{
health = newValue;
UpdateUI();
}
void Die()
{
if (isDead) return;
isDead = true;
var anim = GetComponent<Animator>();
if (anim) anim.SetTrigger("die");
var cc = GetComponent<CharacterController>();
if (cc) cc.enabled = false;
var fps = GetComponent<FirstPersonController_Polyart>();
if (fps) fps.enabled = false;
}
void InitUI()
{
if (healthFillImage)
healthFillImage.fillAmount = health / maxHealth;
}
void UpdateUI()
{
if (healthFillImage)
{
healthFillImage.DOFillAmount(health / maxHealth, 0.25f).SetEase(Ease.OutCubic);
}
}
// ===== Debug Menu =====
[ContextMenu("Debug/Take 10 Damage")]
void DebugTakeDamage() => TakeDamage(10f);
[ContextMenu("Debug/Heal 10")]
void DebugHeal() => Heal(10f);
[ContextMenu("Debug/Kill")]
void DebugKill() => TakeDamage(maxHealth);
}