102 lines
2.8 KiB
C#
102 lines
2.8 KiB
C#
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<Health>();
|
|
|
|
if (_fill != null)
|
|
{
|
|
_baseFillScale = _fill.localScale;
|
|
_fillRenderer = _fill.GetComponent<SpriteRenderer>();
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|