165 lines
3.2 KiB
C#
165 lines
3.2 KiB
C#
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;
|
|
}
|
|
|
|
}
|
|
}
|