mirror of
https://github.com/ConjureETS/Unity_Utils.git
synced 2026-03-23 20:40:58 +00:00
151 lines
4.1 KiB
C#
151 lines
4.1 KiB
C#
using System;
|
|
using System.Collections;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
namespace Canvases.Components
|
|
{
|
|
// ReSharper disable once InconsistentNaming Reason: UI should be capitalized
|
|
public class SliderUIComponent : UISelectableComponentBase
|
|
{
|
|
public event Action<float> OnValueChanged;
|
|
|
|
[Header("Association"), SerializeField, Required]
|
|
private Slider slider;
|
|
|
|
[SerializeField] private Image backgroundImage;
|
|
[SerializeField] private Image fillImage;
|
|
[SerializeField] private Image frame;
|
|
|
|
[Header("Animation"), SerializeField] private bool isChangeValueAnimated;
|
|
[SerializeField] [Range(0f, 1f)] private float animationSpeed = 0.05f;
|
|
[SerializeField] private Color valueIncreaseColor = Color.green;
|
|
[SerializeField] private Color valueDecreaseColor = Color.red;
|
|
|
|
private float targetValue;
|
|
private float currentValue;
|
|
|
|
private Coroutine animationRoutine;
|
|
private Color initialColor = Color.black;
|
|
|
|
public float Value
|
|
{
|
|
get => currentValue;
|
|
set
|
|
{
|
|
if (isChangeValueAnimated)
|
|
{
|
|
targetValue = value;
|
|
StartAnimation();
|
|
}
|
|
else
|
|
{
|
|
currentValue = value;
|
|
slider.value = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public float MaxValue
|
|
{
|
|
get => slider.maxValue;
|
|
set => slider.maxValue = value;
|
|
}
|
|
|
|
public Color BackgroundColor
|
|
{
|
|
set
|
|
{
|
|
if (backgroundImage != null)
|
|
{
|
|
backgroundImage.color = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Color FillColor
|
|
{
|
|
set
|
|
{
|
|
if (fillImage != null)
|
|
{
|
|
initialColor = value;
|
|
fillImage.color = initialColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Color FrameColor
|
|
{
|
|
set
|
|
{
|
|
if (frame != null)
|
|
{
|
|
frame.color = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
Debug.Assert(slider, $"A {nameof(slider)} must be assigned to a {nameof(SliderUIComponent)}");
|
|
slider.onValueChanged.AddListener(OnSliderChanged);
|
|
}
|
|
|
|
protected override void SetSelectableGameObject() => Selectable = slider;
|
|
|
|
protected override void OnDestroy()
|
|
{
|
|
slider.onValueChanged.RemoveListener(OnSliderChanged);
|
|
|
|
base.OnDestroy();
|
|
}
|
|
|
|
private void StartAnimation()
|
|
{
|
|
if (animationRoutine != null)
|
|
StopCoroutine(animationRoutine);
|
|
|
|
animationRoutine = StartCoroutine(AnimateValueChange(targetValue > currentValue));
|
|
}
|
|
|
|
private IEnumerator AnimateValueChange(bool isValueChangePositive)
|
|
{
|
|
if (isValueChangePositive)
|
|
{
|
|
fillImage.color = valueIncreaseColor;
|
|
|
|
while (currentValue < targetValue)
|
|
{
|
|
currentValue += animationSpeed * Time.deltaTime;
|
|
slider.value = currentValue;
|
|
yield return null;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fillImage.color = valueDecreaseColor;
|
|
|
|
while (currentValue > targetValue)
|
|
{
|
|
currentValue -= animationSpeed * Time.deltaTime;
|
|
slider.value = currentValue;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
currentValue = targetValue;
|
|
slider.value = currentValue;
|
|
fillImage.color = initialColor;
|
|
}
|
|
|
|
private void OnSliderChanged(float value) => OnValueChanged?.Invoke(value);
|
|
|
|
private void OnValidate()
|
|
{
|
|
if (!slider)
|
|
slider = GetComponent<Slider>();
|
|
}
|
|
}
|
|
} |