2026-05-19 hp바 추가
This commit is contained in:
101
Assets/02_Scripts/UI/HpBar.cs
Normal file
101
Assets/02_Scripts/UI/HpBar.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user