当前位置:   article > 正文

让数字变化炫酷起来,数字滚动Text组件[Unity]_unity dotween 制作数字进位的动画

unity dotween 制作数字进位的动画

让数字滚动起来

上周我的策划又提了样需求,当玩家评分发生变动时,屏幕出现人物评分浮层UI,播放评分数字滚动动画。这类数字滚动需求非常常见,我就按一般思路,将startvalue与endvalue每隔一点时间做插值变化并显示,从而实现数字滚动的效果,这也是大部分app及游戏采取的实现,效果如下:

几行代码写完给策划看效果,策划说不是这样的效果,跟XX游戏做得不一样,得像lao虎机数字一样,有真实的数字滚动效果,好吧,此滚动非彼滚动,期望效果应该是下面这样,看起来更确实炫酷:

代码实现

这样的效果也不难实现,但要注意一些细节,让动画看起来更真实:

  1. 仍然每隔一点时间做插值变化,算出插值后,不再是简单地修改Text内容了,而是准备用另一个Text显示新值,2个Text都自底向上做缓动,造成像lao虎机一样,新值顶掉旧值的动画效果,要注意每一位数字都单独使用Text组件显示。我们游戏里的战力固定6位数显示,所以总共设置了12个Text组件。
  2. 错开每一位数字的滚动时间点,让滚动效果看起来更自然。设置一个Delay变量,从个位起,后面的每一位都增加一倍Delay再滚动。

  1. /* ==============================================================================
  2. * 功能描述:数字动态变化Text
  3. * 创 建 者:shuchangliu
  4. * ==============================================================================*/
  5. using System;
  6. using System.Collections;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using DG.Tweening;
  10. using UnityEngine;
  11. using UnityEngine.UI;
  12. public class JumpingNumberTextComponent : MonoBehaviour
  13. {
  14. [SerializeField]
  15. [Tooltip("按最高位起始顺序设置每位数字Text(显示组)")]
  16. private List<Text> _numbers;
  17. [SerializeField]
  18. [Tooltip("按最高位起始顺序设置每位数字Text(替换组)")]
  19. private List<Text> _unactiveNumbers;
  20. /// <summary>
  21. /// 动画时长
  22. /// </summary>
  23. [SerializeField]
  24. private float _duration = 1.5f;
  25. /// <summary>
  26. /// 数字每次滚动时长
  27. /// </summary>
  28. [SerializeField]
  29. private float _rollingDuration = 0.05f;
  30. /// <summary>
  31. /// 数字每次变动数值
  32. /// </summary>
  33. private int _speed;
  34. /// <summary>
  35. /// 滚动延迟(每进一位增加一倍延迟,让滚动看起来更随机自然)
  36. /// </summary>
  37. [SerializeField]
  38. private float _delay = 0.008f;
  39. /// <summary>
  40. /// Text文字宽高
  41. /// </summary>
  42. private Vector2 _numberSize;
  43. /// <summary>
  44. /// 当前数字
  45. /// </summary>
  46. private int _curNumber;
  47. /// <summary>
  48. /// 起始数字
  49. /// </summary>
  50. private int _fromNumber;
  51. /// <summary>
  52. /// 最终数字
  53. /// </summary>
  54. private int _toNumber;
  55. /// <summary>
  56. /// 各位数字的缓动实例
  57. /// </summary>
  58. private List<Tweener> _tweener = new List<Tweener>();
  59. /// <summary>
  60. /// 是否处于数字滚动中
  61. /// </summary>
  62. private bool _isJumping;
  63. /// <summary>
  64. /// 滚动完毕回调
  65. /// </summary>
  66. public Action OnComplete;
  67. private void Awake()
  68. {
  69. if (_numbers.Count == 0 || _unactiveNumbers.Count == 0)
  70. {
  71. MediaUnity.Debugger.LogError("[JumpingNumberTextComponent] 还未设置Text组件!");
  72. return;
  73. }
  74. _numberSize = _numbers[0].rectTransform.sizeDelta;
  75. }
  76. public float duration
  77. {
  78. get { return _duration; }
  79. set
  80. {
  81. _duration = value;
  82. }
  83. }
  84. private float _different;
  85. public float different
  86. {
  87. get { return _different; }
  88. }
  89. public void Change(int from, int to)
  90. {
  91. bool isRepeatCall = _isJumping && _fromNumber == from && _toNumber == to;
  92. if (isRepeatCall) return;
  93. bool isContinuousChange = (_toNumber == from) && ((to - from > 0 && _different > 0) || (to - from < 0 && _different < 0));
  94. if (_isJumping && isContinuousChange)
  95. {
  96. }
  97. else
  98. {
  99. _fromNumber = from;
  100. _curNumber = _fromNumber;
  101. }
  102. _toNumber = to;
  103. _different = _toNumber - _fromNumber;
  104. _speed = (int)Math.Ceiling(_different / (_duration * (1 / _rollingDuration)));
  105. _speed = _speed == 0 ? (_different > 0 ? 1 : -1) : _speed;
  106. SetNumber(_curNumber, false);
  107. _isJumping = true;
  108. StopCoroutine("DoJumpNumber");
  109. StartCoroutine("DoJumpNumber");
  110. }
  111. public int number
  112. {
  113. get { return _toNumber; }
  114. set
  115. {
  116. if (_toNumber == value) return;
  117. Change(_curNumber, _toNumber);
  118. }
  119. }
  120. IEnumerator DoJumpNumber()
  121. {
  122. while (true)
  123. {
  124. if (_speed > 0)//增加
  125. {
  126. _curNumber = Math.Min(_curNumber + _speed, _toNumber);
  127. }
  128. else if (_speed < 0) //减少
  129. {
  130. _curNumber = Math.Max(_curNumber + _speed, _toNumber);
  131. }
  132. SetNumber(_curNumber, true);
  133. if (_curNumber == _toNumber)
  134. {
  135. StopCoroutine("DoJumpNumber");
  136. _isJumping = false;
  137. if (OnComplete != null) OnComplete();
  138. yield return null;
  139. }
  140. yield return new WaitForSeconds(_rollingDuration);
  141. }
  142. }
  143. /// <summary>
  144. /// 设置战力数字
  145. /// </summary>
  146. /// <param name="v"></param>
  147. /// <param name="isTween"></param>
  148. public void SetNumber(int v, bool isTween)
  149. {
  150. char[] c = v.ToString().ToCharArray();
  151. Array.Reverse(c);
  152. string s = new string(c);
  153. if (!isTween)
  154. {
  155. for (int i = 0; i < _numbers.Count; i++)
  156. {
  157. if (i < s.Count())
  158. _numbers[i].text = s[i] + "";
  159. else
  160. _numbers[i].text = "0";
  161. }
  162. }
  163. else
  164. {
  165. while (_tweener.Count > 0)
  166. {
  167. _tweener[0].Complete();
  168. _tweener.RemoveAt(0);
  169. }
  170. for (int i = 0; i < _numbers.Count; i++)
  171. {
  172. if (i < s.Count())
  173. {
  174. _unactiveNumbers[i].text = s[i] + "";
  175. }
  176. else
  177. {
  178. _unactiveNumbers[i].text = "0";
  179. }
  180. _unactiveNumbers[i].rectTransform.anchoredPosition = new Vector2(_unactiveNumbers[i].rectTransform.anchoredPosition.x, (_speed > 0 ? -1 : 1) * _numberSize.y);
  181. _numbers[i].rectTransform.anchoredPosition = new Vector2(_unactiveNumbers[i].rectTransform.anchoredPosition.x, 0);
  182. if (_unactiveNumbers[i].text != _numbers[i].text)
  183. {
  184. DoTween(_numbers[i], (_speed > 0 ? 1 : -1) * _numberSize.y, _delay * i);
  185. DoTween(_unactiveNumbers[i], 0, _delay * i);
  186. Text tmp = _numbers[i];
  187. _numbers[i] = _unactiveNumbers[i];
  188. _unactiveNumbers[i] = tmp;
  189. }
  190. }
  191. }
  192. }
  193. public void DoTween(Text text, float endValue, float delay)
  194. {
  195. Tweener t = DOTween.To(() => text.rectTransform.anchoredPosition, (x) =>
  196. {
  197. text.rectTransform.anchoredPosition = x;
  198. }, new Vector2(text.rectTransform.anchoredPosition.x, endValue), _rollingDuration - delay).SetDelay(delay);
  199. _tweener.Add(t);
  200. }
  201. [ContextMenu("测试数字变化")]
  202. public void TestChange()
  203. {
  204. Change(UnityEngine.Random.Range(1, 1), UnityEngine.Random.Range(1, 100000));
  205. }
  206. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/496867
推荐阅读
相关标签
  

闽ICP备14008679号