using UnityEngine; using System; using Code.Gameplay.Enemies; using UnityEngine.UI; namespace Code.Gameplay.Player { public class PlayerHealth : MonoBehaviour { [SerializeField] private int _maxHealth = 100; [SerializeField] private int _damageFromEnemy = 25; [SerializeField] private float _invincibilityDuration = 2f; [SerializeField] private float _attackCooldown = 0.5f; [SerializeField] private float _attackRange = 2f; [SerializeField] private LayerMask _enemyLayer; [SerializeField] private Slider _healthBar; [SerializeField] private AudioSource audioSource; private int _currentHealth; private bool _isInvincible; private float _invincibilityTimer; private float _lastAttackTime; public float nextAttackTime => _lastAttackTime + _attackCooldown; private AudioClip _attackClip; public event Action OnHealthChanged; public event Action OnDied; public event Action OnTookDamage; public event Action OnAttacked; public bool IsAlive => _currentHealth > 0; public bool CanTakeDamage => !_isInvincible && IsAlive; private void Start() { _attackClip = Resources.Load("Audio/SFX/AttackSFX"); _currentHealth = _maxHealth; OnHealthChanged?.Invoke(_currentHealth); } private void Update() { UpdateInvincibility(); _healthBar.value = (float)_currentHealth / _maxHealth; } public void TakeDamage(bool fatal = false) { if (!CanTakeDamage) return; if (fatal) _currentHealth = 0; else _currentHealth -= _damageFromEnemy; OnHealthChanged?.Invoke(_currentHealth); OnTookDamage?.Invoke(); if (_currentHealth <= 0) { Die(); return; } StartInvincibility(); } public void TryAttack() { if (Time.time < nextAttackTime) return; _lastAttackTime = Time.time; OnAttacked?.Invoke(); audioSource.PlayOneShot(_attackClip); var hits = Physics2D.OverlapCircleAll(transform.position, _attackRange, _enemyLayer); foreach (var hit in hits) { if (hit.TryGetComponent(out IEnemy enemy)) { enemy.TakeDamage(); } } } private void StartInvincibility() { _isInvincible = true; _invincibilityTimer = _invincibilityDuration; } private void UpdateInvincibility() { if (!_isInvincible) return; _invincibilityTimer -= Time.deltaTime; if (_invincibilityTimer <= 0f) { _isInvincible = false; } } private void Die() { _healthBar.value = 0; OnDied?.Invoke(); enabled = false; } private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position, _attackRange); } } }