RollingNumberText.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using DG.Tweening;
  6. using LuaInterface;
  7. using UnityEngine;
  8. using UnityEngine.UI;
  9. public class RollingNumberText : MonoBehaviour
  10. {
  11. [SerializeField]
  12. [Tooltip("按最高位起始顺序设置每位数字Text(显示组)")]
  13. private List<Text> _numbers;
  14. [SerializeField]
  15. [Tooltip("按最高位起始顺序设置每位数字Text(替换组)")]
  16. private List<Text> _unactiveNumbers;
  17. /// <summary>
  18. /// 动画时长
  19. /// </summary>
  20. [SerializeField]
  21. private float _duration = 1.5f;
  22. [SerializeField]
  23. private float stayTime = 0.5f;
  24. /// <summary>
  25. /// 数字每次滚动时长
  26. /// </summary>
  27. [SerializeField]
  28. private float _rollingDuration = 0.05f;
  29. /// <summary>
  30. /// 数字每次变动数值
  31. /// </summary>
  32. private int _speed;
  33. /// <summary>
  34. /// 滚动延迟(每进一位增加一倍延迟,让滚动看起来更随机自然)
  35. /// </summary>
  36. [SerializeField]
  37. private float _delay = 0.008f;
  38. /// <summary>
  39. /// Text文字宽高
  40. /// </summary>
  41. private Vector2 _numberSize;
  42. /// <summary>
  43. /// 当前数字
  44. /// </summary>
  45. private int _curNumber;
  46. /// <summary>
  47. /// 起始数字
  48. /// </summary>
  49. private int _fromNumber;
  50. /// <summary>
  51. /// 最终数字
  52. /// </summary>
  53. private int _toNumber;
  54. /// <summary>
  55. /// 各位数字的缓动实例
  56. /// </summary>
  57. private List<DG.Tweening.Tweener> _tweener = new List<DG.Tweening.Tweener>();
  58. /// <summary>
  59. /// 是否处于数字滚动中
  60. /// </summary>
  61. private bool _isJumping;
  62. /// <summary>
  63. /// 滚动完毕回调
  64. /// </summary>
  65. public Action OnComplete;
  66. public bool needOver = true;
  67. [NoToLua]
  68. private void Awake()
  69. {
  70. if (_numbers.Count == 0 || _unactiveNumbers.Count == 0)
  71. {
  72. DebugHelper.LogError("[RollingNumberText] 还未设置Text组件!");
  73. return;
  74. }
  75. _numberSize = _numbers[0].rectTransform.sizeDelta;
  76. }
  77. [NoToLua]
  78. public float duration
  79. {
  80. get { return _duration; }
  81. set
  82. {
  83. _duration = value;
  84. }
  85. }
  86. private float _different;
  87. [NoToLua]
  88. public float different
  89. {
  90. get { return _different; }
  91. }
  92. public void Change(int from, int to)
  93. {
  94. Debug.Log(from + " " + to);
  95. bool isRepeatCall = _isJumping && _fromNumber == from && _toNumber == to;
  96. if (isRepeatCall) return;
  97. bool isContinuousChange = (_toNumber == from) && ((to - from > 0 && _different > 0) || (to - from < 0 && _different < 0));
  98. if (_isJumping && isContinuousChange)
  99. {
  100. }
  101. else
  102. {
  103. _fromNumber = from;
  104. _curNumber = _fromNumber;
  105. }
  106. _toNumber = to;
  107. _different = _toNumber - _fromNumber;
  108. _speed = (int)Math.Ceiling(_different / (_duration * (1 / _rollingDuration)));
  109. _speed = _speed == 0 ? (_different > 0 ? 1 : -1) : _speed;
  110. SetNumber(_curNumber, false);
  111. _isJumping = true;
  112. needOver = true;
  113. StopCoroutine("DoJumpNumber");
  114. StartCoroutine("DoJumpNumber");
  115. }
  116. [NoToLua]
  117. public int number
  118. {
  119. get { return _toNumber; }
  120. set
  121. {
  122. if (_toNumber == value) return;
  123. Change(_curNumber, _toNumber);
  124. }
  125. }
  126. [NoToLua]
  127. IEnumerator DoJumpNumber()
  128. {
  129. while (needOver)
  130. {
  131. if (_speed > 0)//增加
  132. {
  133. _curNumber = Math.Min(_curNumber + _speed, _toNumber);
  134. }
  135. else if (_speed < 0) //减少
  136. {
  137. _curNumber = Math.Max(_curNumber + _speed, _toNumber);
  138. }
  139. SetNumber(_curNumber, true);
  140. if (_curNumber == _toNumber)
  141. {
  142. yield return new WaitForSeconds(stayTime);
  143. StopCoroutine("DoJumpNumber");
  144. _isJumping = false;
  145. needOver = false;
  146. if (OnComplete != null) OnComplete();
  147. yield return null;
  148. }
  149. yield return new WaitForSeconds(_rollingDuration);
  150. }
  151. }
  152. [NoToLua]
  153. /// <summary>
  154. /// 设置战力数字
  155. /// </summary>
  156. /// <param name="v"></param>
  157. /// <param name="isTween"></param>
  158. public void SetNumber(int v, bool isTween)
  159. {
  160. char[] c = v.ToString().ToCharArray();
  161. Array.Reverse(c);
  162. string s = new string(c);
  163. if (!isTween)
  164. {
  165. for (int i = 0; i < _numbers.Count; i++)
  166. {
  167. if (i < s.Count())
  168. _numbers[i].text = s[i] + "";
  169. else
  170. _numbers[i].text = "0";
  171. _numbers[i].gameObject.SetActive(i < s.Count());
  172. }
  173. }
  174. else
  175. {
  176. while (_tweener.Count > 0)
  177. {
  178. _tweener[0].Complete();
  179. _tweener.RemoveAt(0);
  180. }
  181. for (int i = 0; i < _numbers.Count; i++)
  182. {
  183. if (i < s.Count())
  184. {
  185. _unactiveNumbers[i].text = s[i] + "";
  186. }
  187. else
  188. {
  189. _unactiveNumbers[i].text = "0";
  190. }
  191. _unactiveNumbers[i].gameObject.SetActive(i < s.Count());
  192. _unactiveNumbers[i].rectTransform.anchoredPosition = new Vector2(_unactiveNumbers[i].rectTransform.anchoredPosition.x, (_speed > 0 ? -1 : 1) * _numberSize.y);
  193. _numbers[i].rectTransform.anchoredPosition = new Vector2(_unactiveNumbers[i].rectTransform.anchoredPosition.x, 0);
  194. if (_unactiveNumbers[i].text != _numbers[i].text)
  195. {
  196. DoTween(_numbers[i], (_speed > 0 ? 1 : -1) * _numberSize.y, _delay * i);
  197. DoTween(_unactiveNumbers[i], 0, _delay * i);
  198. Text tmp = _numbers[i];
  199. _numbers[i] = _unactiveNumbers[i];
  200. _unactiveNumbers[i] = tmp;
  201. }
  202. }
  203. }
  204. }
  205. [NoToLua]
  206. public void DoTween(Text text, float endValue, float delay)
  207. {
  208. DG.Tweening.Tweener t = DOTween.To(() => text.rectTransform.anchoredPosition, (x) =>
  209. {
  210. text.rectTransform.anchoredPosition = x;
  211. }, new Vector2(text.rectTransform.anchoredPosition.x, endValue), _rollingDuration - delay).SetDelay(delay);
  212. _tweener.Add(t);
  213. }
  214. [NoToLua]
  215. [ContextMenu("测试数字变化")]
  216. public void TestChange()
  217. {
  218. Change(UnityEngine.Random.Range(1, 1), UnityEngine.Random.Range(1, 100000));
  219. }
  220. public void RollingNumberOver(int from, int to)
  221. {
  222. //bool isRepeatCall = _isJumping && _fromNumber == from && _toNumber == to;
  223. //if (isRepeatCall) return;
  224. StopCoroutine("DoJumpNumber");
  225. _isJumping = false;
  226. needOver = false;
  227. }
  228. }