You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
4.2 KiB
161 lines
4.2 KiB
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using UnityEngine.UI;
|
|
|
|
public class ExtendSlider : MonoBehaviour
|
|
{
|
|
[SerializeField] Slider slider;
|
|
|
|
[SerializeField] Color[] colorLevelPerRate;
|
|
[SerializeField] MaskableGraphic currentColorIndicator;
|
|
[SerializeField] MaskableGraphic prevColorIndicator;
|
|
|
|
[Range(0f, 10f)]
|
|
[SerializeField] float animSpeed = 0f;
|
|
|
|
float currentRate;
|
|
float targetRate;
|
|
int prevColorIdx = -1;
|
|
|
|
bool HasColorLevel => colorLevelPerRate.Length > 0;
|
|
|
|
public UnityEvent<float> OnChangedColorLevel;
|
|
|
|
private void Update()
|
|
{
|
|
if (!HasColorLevel)
|
|
{
|
|
if (animSpeed > 0f)
|
|
{
|
|
float diff = targetRate - currentRate;
|
|
float delta = diff * animSpeed * Time.fixedDeltaTime;
|
|
|
|
if (Mathf.Abs(delta) >= Mathf.Abs(diff))
|
|
currentRate = targetRate;
|
|
else
|
|
currentRate += delta;
|
|
}
|
|
else
|
|
{
|
|
currentRate = targetRate;
|
|
}
|
|
|
|
slider.value = currentRate;
|
|
}
|
|
else
|
|
{
|
|
if (animSpeed > 0f)
|
|
{
|
|
float diff = targetRate - currentRate;
|
|
float delta = diff * animSpeed * Time.fixedDeltaTime;
|
|
|
|
if (Mathf.Abs(delta) >= Mathf.Abs(diff))
|
|
currentRate = targetRate;
|
|
else
|
|
currentRate += delta;
|
|
}
|
|
else
|
|
{
|
|
currentRate = targetRate;
|
|
}
|
|
|
|
GetColorIdxAndInnerRate(currentRate, out int colorIdx, out float innerRate);
|
|
|
|
slider.value = innerRate;
|
|
|
|
if (prevColorIdx != colorIdx)
|
|
{
|
|
if (currentColorIndicator != null)
|
|
currentColorIndicator.color = colorLevelPerRate[colorIdx];
|
|
|
|
if (prevColorIndicator != null)
|
|
prevColorIndicator.color = colorIdx > 0 ? colorLevelPerRate[colorIdx - 1] : new Color(1f, 1f, 1f, 0.5f);
|
|
|
|
OnChangedColorLevel?.Invoke(innerRate);
|
|
prevColorIdx = colorIdx;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void GetColorIdxAndInnerRate(float rate, out int colorIdx, out float innerRate)
|
|
{
|
|
colorIdx = Mathf.FloorToInt(rate);
|
|
innerRate = rate - colorIdx;
|
|
|
|
// 색의 경계선(마지막 레이트 값은 제외)에 있으면 이전 레벨로 색 표시.
|
|
if (rate > 0 && innerRate == 0)
|
|
{
|
|
--colorIdx;
|
|
innerRate = 1f;
|
|
}
|
|
}
|
|
|
|
public void SetRate(float rate)
|
|
{
|
|
rate = Mathf.Clamp01(rate);
|
|
|
|
if(HasColorLevel)
|
|
{
|
|
targetRate = rate * colorLevelPerRate.Length;
|
|
}
|
|
else
|
|
{
|
|
targetRate = rate;
|
|
}
|
|
}
|
|
|
|
public void SetRate(float currentValue, float maxValue)
|
|
{
|
|
if (maxValue == 0)
|
|
SetRate(0);
|
|
else
|
|
SetRate(currentValue / maxValue);
|
|
}
|
|
|
|
public void SetRateImmediate(float rate)
|
|
{
|
|
rate = Mathf.Clamp01(rate);
|
|
|
|
if (HasColorLevel)
|
|
{
|
|
targetRate = rate * colorLevelPerRate.Length;
|
|
currentRate = targetRate;
|
|
|
|
GetColorIdxAndInnerRate(currentRate, out int colorIdx, out float innerRate);
|
|
|
|
slider.value = innerRate;
|
|
|
|
if (prevColorIdx != colorIdx)
|
|
{
|
|
if (currentColorIndicator != null)
|
|
currentColorIndicator.color = colorLevelPerRate[colorIdx];
|
|
|
|
if (prevColorIndicator != null)
|
|
prevColorIndicator.color = colorIdx > 0 ? colorLevelPerRate[colorIdx - 1] : new Color(1f, 1f, 1f, 0.5f);
|
|
|
|
OnChangedColorLevel?.Invoke(innerRate);
|
|
prevColorIdx = colorIdx;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
targetRate = rate;
|
|
currentRate = rate;
|
|
slider.value = rate;
|
|
}
|
|
}
|
|
|
|
public void SetRateImmediate(float currentValue, float maxValue)
|
|
{
|
|
if (maxValue == 0)
|
|
SetRateImmediate(0);
|
|
else
|
|
SetRateImmediate(currentValue / maxValue);
|
|
}
|
|
|
|
private void OnValidate()
|
|
{
|
|
if (slider == null)
|
|
slider = GetComponent<Slider>();
|
|
}
|
|
}
|