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 dots = new List(); [SerializeField] private List dotImages = new List(); [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(); 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; // } // } }