86 lines
2.7 KiB
C#
86 lines
2.7 KiB
C#
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// Êîìïîíåíò äëÿ ïëàâíîãî èçìåíåíèÿ çíà÷åíèÿ Slider.
|
|
/// Âûçûâàé ìåòîä AnimateTo() íàïðÿìóþ äëÿ àíèìàöèè.
|
|
/// </summary>
|
|
[RequireComponent(typeof(Slider))]
|
|
public class SmoothSlider : MonoBehaviour
|
|
{
|
|
[Header("Íàñòðîéêè ïëàâíîñòè")]
|
|
[Tooltip("Äëèòåëüíîñòü àíèìàöèè â ñåêóíäàõ")]
|
|
[SerializeField] private float duration = 0.3f;
|
|
|
|
[Tooltip("Êðèâàÿ àíèìàöèè (ïî óìîë÷àíèþ - ïëàâíàÿ)")]
|
|
[SerializeField] private AnimationCurve curve = AnimationCurve.EaseInOut(0, 0, 1, 1);
|
|
|
|
private Slider slider;
|
|
private Coroutine animationCoroutine;
|
|
private float targetValue;
|
|
private System.Action<float> pendingCallback;
|
|
private int animationId; // Óíèêàëüíûé ID äëÿ îòñëåæèâàíèÿ îòìåíåííûõ àíèìàöèé
|
|
|
|
private void Awake()
|
|
{
|
|
slider = GetComponent<Slider>();
|
|
targetValue = slider.value;
|
|
animationId = 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ïëàâíî àíèìèðóåò ñëàéäåð ê íîâîìó çíà÷åíèþ.
|
|
/// Â êîíöå àíèìàöèè âûçîâåò callback onComplete.
|
|
/// </summary>
|
|
public void AnimateTo(float endValue, System.Action<float> onComplete = null)
|
|
{
|
|
if (animationCoroutine != null)
|
|
{
|
|
StopCoroutine(animationCoroutine);
|
|
|
|
// ÂÀÆÍÎ: Ñîõðàíÿåì ÑÒÀÐÎÅ öåëåâîå çíà÷åíèå è callback ÏÅÐÅÄ îáíîâëåíèåì
|
|
float previousTarget = targetValue;
|
|
System.Action<float> previousCallback = pendingCallback;
|
|
|
|
// Óñòàíàâëèâàåì ôèíàëüíîå çíà÷åíèå ïðåäûäóùåé àíèìàöèè
|
|
slider.value = previousTarget;
|
|
|
|
// Âûçûâàåì callback ñ ïðàâèëüíûì ôèíàëüíûì çíà÷åíèåì
|
|
previousCallback?.Invoke(previousTarget);
|
|
}
|
|
|
|
// Òåïåðü îáíîâëÿåì íà íîâûå çíà÷åíèÿ
|
|
targetValue = endValue;
|
|
pendingCallback = onComplete;
|
|
animationId++; // Íîâûé ID äëÿ íîâîé àíèìàöèè
|
|
animationCoroutine = StartCoroutine(AnimateToValue(endValue, onComplete, animationId));
|
|
}
|
|
|
|
private IEnumerator AnimateToValue(float endValue, System.Action<float> onComplete, int myAnimationId)
|
|
{
|
|
float startValue = slider.value;
|
|
float elapsed = 0f;
|
|
|
|
while (elapsed < duration)
|
|
{
|
|
elapsed += Time.unscaledDeltaTime;
|
|
float t = Mathf.Clamp01(elapsed / duration);
|
|
|
|
slider.value = Mathf.Lerp(startValue, endValue, curve.Evaluate(t));
|
|
yield return null;
|
|
}
|
|
|
|
// Ôèíàëüíîå çíà÷åíèå - òîëüêî åñëè àíèìàöèÿ íå áûëà îòìåíåíà
|
|
if (myAnimationId == animationId)
|
|
{
|
|
slider.value = endValue;
|
|
targetValue = endValue;
|
|
onComplete?.Invoke(endValue);
|
|
|
|
animationCoroutine = null;
|
|
}
|
|
}
|
|
}
|
|
|