using UnityEngine; public class HpBar : MonoBehaviour { [SerializeField] private Health _health; [SerializeField] private Transform _fill; [SerializeField] private bool _autoFindHealthInParent = true; [SerializeField] private bool _hideWhenFull = true; [SerializeField] private float _smoothSpeed = 0f; [Header("Color Thresholds")] [SerializeField] private Color _highColor = new Color(0.2f, 0.9f, 0.3f, 1f); [SerializeField] private Color _midColor = new Color(1f, 0.85f, 0.2f, 1f); [SerializeField] private Color _lowColor = new Color(0.95f, 0.25f, 0.25f, 1f); [SerializeField, Range(0f, 1f)] private float _midThreshold = 0.5f; [SerializeField, Range(0f, 1f)] private float _lowThreshold = 0.2f; private Vector3 _baseFillScale; private SpriteRenderer _fillRenderer; private float _currentRatio = 1f; private float _targetRatio = 1f; private void Awake() { if (_health == null && _autoFindHealthInParent) _health = GetComponentInParent(); if (_fill != null) { _baseFillScale = _fill.localScale; _fillRenderer = _fill.GetComponent(); } } private void OnEnable() { if (_health == null) return; _health.OnHealthChanged += HandleHealthChanged; HandleHealthChanged(_health.CurrentHealth, _health.MaxHealth); } private void OnDisable() { if (_health != null) _health.OnHealthChanged -= HandleHealthChanged; } private void Update() { if (_smoothSpeed <= 0f) return; if (Mathf.Approximately(_currentRatio, _targetRatio)) return; _currentRatio = Mathf.MoveTowards(_currentRatio, _targetRatio, _smoothSpeed * Time.deltaTime); ApplyScale(); } private void HandleHealthChanged(int current, int max) { _targetRatio = max > 0 ? (float)current / max : 0f; if (_smoothSpeed <= 0f) { _currentRatio = _targetRatio; ApplyScale(); } ApplyColor(_targetRatio); if (_hideWhenFull && _fill != null) { bool shouldShow = _targetRatio < 1f && _targetRatio > 0f; if (gameObject.activeSelf != shouldShow) gameObject.SetActive(shouldShow); } } private void ApplyScale() { if (_fill == null) return; Vector3 scale = _baseFillScale; scale.x = _baseFillScale.x * Mathf.Clamp01(_currentRatio); _fill.localScale = scale; } private void ApplyColor(float ratio) { if (_fillRenderer == null) return; Color color; if (ratio <= _lowThreshold) color = _lowColor; else if (ratio <= _midThreshold) color = _midColor; else color = _highColor; _fillRenderer.color = color; } }