using UnityEngine; using UnityEngine.UI; using UnityEngine.Serialization; namespace OHM.UnityToolkit.UI { public class UIIncrementableGauge : MonoBehaviour { [SerializeField] private float incSpeed = 1f; [SerializeField] private float decSpeed = 1f; [SerializeField] private float levelincSpeed = 1f; [SerializeField] public RectTransform gaugeRect; [SerializeField] [FormerlySerializedAs("gaugeImage")] private Image _gaugeImage; [SerializeField] [FormerlySerializedAs("imageMaxFillRatio")] private float _imageMaxFillRatio = 1f; [SerializeField] [FormerlySerializedAs("x")] private bool _x; [SerializeField] [FormerlySerializedAs("y")] private bool _y; [SerializeField] [FormerlySerializedAs("smoothLevelUp")] private bool _smoothLevelUp; [SerializeField] [FormerlySerializedAs("smoothLevelDown")] private bool _smoothLevelDown; private int currentLevel; private int _targetLevel; private float _targetValue; public float CurrentValue { get; set; } private void Awake() { currentLevel = 0; CurrentValue = 0f; _targetValue = 0f; SetRawValue(0f); } public void SetTargetValue(float value, int level) { if (_targetValue == value && _targetLevel == level) { return; } _targetValue = Mathf.Clamp01(value); _targetLevel = level; } public void QuickResetToLevel(int level, float value = 0, bool force = false) { _targetValue = value; currentLevel = level; _targetLevel = level; if (force) { CurrentValue = value; } SetRawValue(value); } private bool IncValueToTarget(float target, float speed) { float current = CurrentValue; bool rising = target - current >= 0f; float next = current + (rising ? Time.deltaTime : (0f - Time.deltaTime)) * speed; bool reached; if (rising) { reached = next >= target; if (reached) { next = target; } } else { reached = next <= target; if (reached) { next = target; } } SetRawValue(next); return reached; } private void LevelTransition(bool smooth, int deltaLevel, float target, float afterValue) { if (!smooth) { currentLevel += deltaLevel; SetRawValue(_targetValue); return; } if (IncValueToTarget(target, levelincSpeed)) { currentLevel += deltaLevel; SetRawValue(afterValue); } } private void Update() { if (_targetLevel == currentLevel) { if (_targetValue > CurrentValue) { IncValueToTarget(_targetValue, incSpeed); } else if (_targetValue <= CurrentValue) { IncValueToTarget(_targetValue, decSpeed); } } else if (_targetLevel > currentLevel) { LevelTransition(_smoothLevelUp, 1, 1f, 0f); } else { LevelTransition(_smoothLevelDown, -1, 0f, 1f); } } private void SetRawValue(float value) { CurrentValue = value; float ratio = Mathf.Clamp01(value); if (gaugeRect != null) { Vector2 anchorMax = gaugeRect.anchorMax; gaugeRect.anchorMax = new Vector2(_x ? ratio : anchorMax.x, _y ? ratio : anchorMax.y); } if (_gaugeImage != null) { _gaugeImage.fillAmount = ratio * _imageMaxFillRatio; } } public void changeGaugeColor(Color color) { _gaugeImage.color = color; } } }