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

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>();
}
}