236 lines
7.0 KiB
C#
236 lines
7.0 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using DG.Tweening;
|
|
using System.Collections.Generic;
|
|
|
|
public class sliderProgressSc : MonoBehaviour
|
|
{
|
|
[Header("Slider Reference")]
|
|
[SerializeField] private Slider targetSlider;
|
|
|
|
[Header("Dots Configuration")]
|
|
[SerializeField] private List<Transform> dots = new List<Transform>();
|
|
[SerializeField] private List<Image> dotImages = new List<Image>();
|
|
|
|
[Header("Animation Settings")]
|
|
[SerializeField] private float scaleDuration = 0.3f;
|
|
[SerializeField] private float colorDuration = 0.2f;
|
|
[SerializeField] private Vector3 activeScale = Vector3.one * 1.2f;
|
|
[SerializeField] private Vector3 inactiveScale = Vector3.one;
|
|
[SerializeField] private Ease scaleEase = Ease.OutBack;
|
|
|
|
[Header("Colors")]
|
|
[SerializeField] private Color inactiveColor = new Color(0.3f, 0.3f, 0.3f, 0.6f);
|
|
[SerializeField] private Color activeColor = new Color(0f, 1f, 0.4f, 1f); // Bright green
|
|
|
|
private float previousSliderValue;
|
|
private int lastActivatedDot = -1;
|
|
|
|
void Start()
|
|
{
|
|
InitializeSlider();
|
|
SetupInitialState();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// Check if slider value changed
|
|
if (Mathf.Abs(targetSlider.value - previousSliderValue) > 0.001f)
|
|
{
|
|
CheckAndAnimateDots(targetSlider.value);
|
|
previousSliderValue = targetSlider.value;
|
|
}
|
|
}
|
|
|
|
void InitializeSlider()
|
|
{
|
|
if (targetSlider == null)
|
|
targetSlider = GetComponent<Slider>();
|
|
|
|
if (targetSlider == null)
|
|
{
|
|
Debug.LogError("No slider found! Please assign a slider reference.");
|
|
return;
|
|
}
|
|
|
|
// Auto-populate dots if empty
|
|
if (dots.Count == 0)
|
|
{
|
|
Debug.Log("No dots found! Please assign dot transforms manually.");
|
|
}
|
|
|
|
previousSliderValue = targetSlider.value;
|
|
}
|
|
|
|
void SetupInitialState()
|
|
{
|
|
// Set all dots to inactive state
|
|
for (int i = 0; i < dots.Count; i++)
|
|
{
|
|
if (dots[i] != null)
|
|
{
|
|
dots[i].localScale = inactiveScale;
|
|
|
|
if (i < dotImages.Count && dotImages[i] != null)
|
|
{
|
|
dotImages[i].color = inactiveColor;
|
|
}
|
|
}
|
|
}
|
|
lastActivatedDot = -1;
|
|
}
|
|
|
|
void CheckAndAnimateDots(float sliderValue)
|
|
{
|
|
// Calculate how many dots should be active based on slider value
|
|
// For 10 dots: dot 0 at 0.1, dot 1 at 0.2, ..., dot 9 at 1.0
|
|
int dotsToActivate = Mathf.FloorToInt(sliderValue * dots.Count);
|
|
|
|
// Clamp to valid range
|
|
dotsToActivate = Mathf.Clamp(dotsToActivate, 0, dots.Count);
|
|
|
|
// The actual active dot index (0-based, -1 means no dots active)
|
|
int targetActiveDot = dotsToActivate - 1;
|
|
|
|
// Check if we've moved forward to activate more dots
|
|
if (targetActiveDot > lastActivatedDot)
|
|
{
|
|
// Activate dots from lastActivatedDot+1 to targetActiveDot
|
|
for (int i = lastActivatedDot + 1; i <= targetActiveDot; i++)
|
|
{
|
|
if (i < dots.Count && i >= 0)
|
|
{
|
|
ActivateDot(i);
|
|
}
|
|
}
|
|
lastActivatedDot = targetActiveDot;
|
|
}
|
|
// Check if we've moved backward (deactivate dots)
|
|
else if (targetActiveDot < lastActivatedDot)
|
|
{
|
|
// Deactivate dots from lastActivatedDot down to targetActiveDot+1
|
|
for (int i = lastActivatedDot; i > targetActiveDot; i--)
|
|
{
|
|
if (i < dots.Count && i >= 0)
|
|
{
|
|
DeactivateDot(i);
|
|
}
|
|
}
|
|
lastActivatedDot = targetActiveDot;
|
|
}
|
|
}
|
|
|
|
void ActivateDot(int dotIndex)
|
|
{
|
|
if (dotIndex >= dots.Count || dotIndex < 0 || dots[dotIndex] == null) return;
|
|
|
|
Transform dot = dots[dotIndex];
|
|
|
|
// Scale up animation
|
|
dot.DOScale(activeScale, scaleDuration).SetEase(scaleEase);
|
|
|
|
// Color change to active
|
|
if (dotIndex < dotImages.Count && dotImages[dotIndex] != null)
|
|
{
|
|
dotImages[dotIndex].DOColor(activeColor, colorDuration);
|
|
}
|
|
}
|
|
|
|
void DeactivateDot(int dotIndex)
|
|
{
|
|
if (dotIndex >= dots.Count || dotIndex < 0 || dots[dotIndex] == null) return;
|
|
|
|
Transform dot = dots[dotIndex];
|
|
|
|
// Scale down animation
|
|
dot.DOScale(inactiveScale, scaleDuration * 0.7f).SetEase(Ease.OutQuad);
|
|
|
|
// Color change to inactive
|
|
if (dotIndex < dotImages.Count && dotImages[dotIndex] != null)
|
|
{
|
|
dotImages[dotIndex].DOColor(inactiveColor, colorDuration * 0.7f);
|
|
}
|
|
}
|
|
|
|
// Public methods for external control
|
|
public void SetSliderValue(float value)
|
|
{
|
|
if (targetSlider != null)
|
|
{
|
|
targetSlider.value = value;
|
|
}
|
|
}
|
|
|
|
public void ResetDots()
|
|
{
|
|
// Kill any running animations
|
|
for (int i = 0; i < dots.Count; i++)
|
|
{
|
|
if (dots[i] != null)
|
|
{
|
|
dots[i].DOKill();
|
|
}
|
|
if (i < dotImages.Count && dotImages[i] != null)
|
|
{
|
|
dotImages[i].DOKill();
|
|
}
|
|
}
|
|
|
|
// Reset state
|
|
lastActivatedDot = -1;
|
|
SetupInitialState();
|
|
}
|
|
|
|
// Get current progress (0-10)
|
|
public int GetCurrentProgress()
|
|
{
|
|
return lastActivatedDot + 1;
|
|
}
|
|
|
|
// Check if specific dot is active
|
|
public bool IsDotActive(int dotIndex)
|
|
{
|
|
return dotIndex <= lastActivatedDot;
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
// Clean up any running tweens
|
|
for (int i = 0; i < dots.Count; i++)
|
|
{
|
|
if (dots[i] != null)
|
|
{
|
|
dots[i].DOKill();
|
|
}
|
|
if (i < dotImages.Count && dotImages[i] != null)
|
|
{
|
|
dotImages[i].DOKill();
|
|
}
|
|
}
|
|
}
|
|
|
|
// // Debug helper - shows current calculation values in inspector
|
|
// [System.Serializable]
|
|
// public class DebugInfo
|
|
// {
|
|
// [SerializeField] public float currentSliderValue;
|
|
// [SerializeField] public int dotsToActivate;
|
|
// [SerializeField] public int targetActiveDot;
|
|
// [SerializeField] public int lastActivatedDot;
|
|
// }
|
|
|
|
// [Header("Debug Info (Runtime Only)")]
|
|
// [SerializeField] private DebugInfo debugInfo = new DebugInfo();
|
|
|
|
// void LateUpdate()
|
|
// {
|
|
// // Update debug info for inspector visibility
|
|
// if (targetSlider != null)
|
|
// {
|
|
// debugInfo.currentSliderValue = targetSlider.value;
|
|
// debugInfo.dotsToActivate = Mathf.FloorToInt(targetSlider.value * dots.Count);
|
|
// debugInfo.targetActiveDot = debugInfo.dotsToActivate - 1;
|
|
// debugInfo.lastActivatedDot = lastActivatedDot;
|
|
// }
|
|
// }
|
|
} |