sliderProgressSc.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using DG.Tweening;
  4. using System.Collections.Generic;
  5. public class sliderProgressSc : MonoBehaviour
  6. {
  7. [Header("Slider Reference")]
  8. [SerializeField] private Slider targetSlider;
  9. [Header("Dots Configuration")]
  10. [SerializeField] private List<Transform> dots = new List<Transform>();
  11. [SerializeField] private List<Image> dotImages = new List<Image>();
  12. [Header("Animation Settings")]
  13. [SerializeField] private float scaleDuration = 0.3f;
  14. [SerializeField] private float colorDuration = 0.2f;
  15. [SerializeField] private Vector3 activeScale = Vector3.one * 1.2f;
  16. [SerializeField] private Vector3 inactiveScale = Vector3.one;
  17. [SerializeField] private Ease scaleEase = Ease.OutBack;
  18. [Header("Colors")]
  19. [SerializeField] private Color inactiveColor = new Color(0.3f, 0.3f, 0.3f, 0.6f);
  20. [SerializeField] private Color activeColor = new Color(0f, 1f, 0.4f, 1f); // Bright green
  21. private float previousSliderValue;
  22. private int lastActivatedDot = -1;
  23. void Start()
  24. {
  25. InitializeSlider();
  26. SetupInitialState();
  27. }
  28. void Update()
  29. {
  30. // Check if slider value changed
  31. if (Mathf.Abs(targetSlider.value - previousSliderValue) > 0.001f)
  32. {
  33. CheckAndAnimateDots(targetSlider.value);
  34. previousSliderValue = targetSlider.value;
  35. }
  36. }
  37. void InitializeSlider()
  38. {
  39. if (targetSlider == null)
  40. targetSlider = GetComponent<Slider>();
  41. if (targetSlider == null)
  42. {
  43. Debug.LogError("No slider found! Please assign a slider reference.");
  44. return;
  45. }
  46. // Auto-populate dots if empty
  47. if (dots.Count == 0)
  48. {
  49. Debug.Log("No dots found! Please assign dot transforms manually.");
  50. }
  51. previousSliderValue = targetSlider.value;
  52. }
  53. void SetupInitialState()
  54. {
  55. // Set all dots to inactive state
  56. for (int i = 0; i < dots.Count; i++)
  57. {
  58. if (dots[i] != null)
  59. {
  60. dots[i].localScale = inactiveScale;
  61. if (i < dotImages.Count && dotImages[i] != null)
  62. {
  63. dotImages[i].color = inactiveColor;
  64. }
  65. }
  66. }
  67. lastActivatedDot = -1;
  68. }
  69. void CheckAndAnimateDots(float sliderValue)
  70. {
  71. // Calculate how many dots should be active based on slider value
  72. // For 10 dots: dot 0 at 0.1, dot 1 at 0.2, ..., dot 9 at 1.0
  73. int dotsToActivate = Mathf.FloorToInt(sliderValue * dots.Count);
  74. // Clamp to valid range
  75. dotsToActivate = Mathf.Clamp(dotsToActivate, 0, dots.Count);
  76. // The actual active dot index (0-based, -1 means no dots active)
  77. int targetActiveDot = dotsToActivate - 1;
  78. // Check if we've moved forward to activate more dots
  79. if (targetActiveDot > lastActivatedDot)
  80. {
  81. // Activate dots from lastActivatedDot+1 to targetActiveDot
  82. for (int i = lastActivatedDot + 1; i <= targetActiveDot; i++)
  83. {
  84. if (i < dots.Count && i >= 0)
  85. {
  86. ActivateDot(i);
  87. }
  88. }
  89. lastActivatedDot = targetActiveDot;
  90. }
  91. // Check if we've moved backward (deactivate dots)
  92. else if (targetActiveDot < lastActivatedDot)
  93. {
  94. // Deactivate dots from lastActivatedDot down to targetActiveDot+1
  95. for (int i = lastActivatedDot; i > targetActiveDot; i--)
  96. {
  97. if (i < dots.Count && i >= 0)
  98. {
  99. DeactivateDot(i);
  100. }
  101. }
  102. lastActivatedDot = targetActiveDot;
  103. }
  104. }
  105. void ActivateDot(int dotIndex)
  106. {
  107. if (dotIndex >= dots.Count || dotIndex < 0 || dots[dotIndex] == null) return;
  108. Transform dot = dots[dotIndex];
  109. // Scale up animation
  110. dot.DOScale(activeScale, scaleDuration).SetEase(scaleEase);
  111. // Color change to active
  112. if (dotIndex < dotImages.Count && dotImages[dotIndex] != null)
  113. {
  114. dotImages[dotIndex].DOColor(activeColor, colorDuration);
  115. }
  116. }
  117. void DeactivateDot(int dotIndex)
  118. {
  119. if (dotIndex >= dots.Count || dotIndex < 0 || dots[dotIndex] == null) return;
  120. Transform dot = dots[dotIndex];
  121. // Scale down animation
  122. dot.DOScale(inactiveScale, scaleDuration * 0.7f).SetEase(Ease.OutQuad);
  123. // Color change to inactive
  124. if (dotIndex < dotImages.Count && dotImages[dotIndex] != null)
  125. {
  126. dotImages[dotIndex].DOColor(inactiveColor, colorDuration * 0.7f);
  127. }
  128. }
  129. // Public methods for external control
  130. public void SetSliderValue(float value)
  131. {
  132. if (targetSlider != null)
  133. {
  134. targetSlider.value = value;
  135. }
  136. }
  137. public void ResetDots()
  138. {
  139. // Kill any running animations
  140. for (int i = 0; i < dots.Count; i++)
  141. {
  142. if (dots[i] != null)
  143. {
  144. dots[i].DOKill();
  145. }
  146. if (i < dotImages.Count && dotImages[i] != null)
  147. {
  148. dotImages[i].DOKill();
  149. }
  150. }
  151. // Reset state
  152. lastActivatedDot = -1;
  153. SetupInitialState();
  154. }
  155. // Get current progress (0-10)
  156. public int GetCurrentProgress()
  157. {
  158. return lastActivatedDot + 1;
  159. }
  160. // Check if specific dot is active
  161. public bool IsDotActive(int dotIndex)
  162. {
  163. return dotIndex <= lastActivatedDot;
  164. }
  165. void OnDestroy()
  166. {
  167. // Clean up any running tweens
  168. for (int i = 0; i < dots.Count; i++)
  169. {
  170. if (dots[i] != null)
  171. {
  172. dots[i].DOKill();
  173. }
  174. if (i < dotImages.Count && dotImages[i] != null)
  175. {
  176. dotImages[i].DOKill();
  177. }
  178. }
  179. }
  180. // // Debug helper - shows current calculation values in inspector
  181. // [System.Serializable]
  182. // public class DebugInfo
  183. // {
  184. // [SerializeField] public float currentSliderValue;
  185. // [SerializeField] public int dotsToActivate;
  186. // [SerializeField] public int targetActiveDot;
  187. // [SerializeField] public int lastActivatedDot;
  188. // }
  189. // [Header("Debug Info (Runtime Only)")]
  190. // [SerializeField] private DebugInfo debugInfo = new DebugInfo();
  191. // void LateUpdate()
  192. // {
  193. // // Update debug info for inspector visibility
  194. // if (targetSlider != null)
  195. // {
  196. // debugInfo.currentSliderValue = targetSlider.value;
  197. // debugInfo.dotsToActivate = Mathf.FloorToInt(targetSlider.value * dots.Count);
  198. // debugInfo.targetActiveDot = debugInfo.dotsToActivate - 1;
  199. // debugInfo.lastActivatedDot = lastActivatedDot;
  200. // }
  201. // }
  202. }