Text组件数字动画[Unity]
1. 仍然每隔⼀点时间做插值变化,算出插值后,不再是简单地修改Text内容了,⽽是准备⽤另⼀个Text显⽰新值,2个Text都⾃底向上
做缓动,造成像lao虎机⼀样,新值顶掉旧值的动画效果,要注意每⼀位数字都单独使⽤Text组件显⽰。我们游戏⾥的战⼒固定6位数显⽰,所以总共设置了12个Text组件。
2. 错开每⼀位数字的滚动时间点,让滚动效果看起来更⾃然。设置⼀个Delay变量,从个位起,后⾯的每⼀位都增加⼀倍Delay再滚动。
/* ==============================================================================unity3d animation
* 功能描述:数字动态变化Text
* 创建者:shuchangliu
* ==============================================================================*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;
public class JumpingNumberTextComponent : MonoBehaviour
{
[SerializeField]
[Tooltip("按最⾼位起始顺序设置每位数字Text(显⽰组)")]
private List<Text> _numbers;
[SerializeField]
[Tooltip("按最⾼位起始顺序设置每位数字Text(替换组)")]
private List<Text> _unactiveNumbers;
/// <summary>
/// 动画时长
/// </summary>
[SerializeField]
private float _duration = 1.5f;
/
// <summary>
/// 数字每次滚动时长
/// </summary>
[SerializeField]
private float _rollingDuration = 0.05f;
/// <summary>
/// 数字每次变动数值
/// </summary>
private int _speed;
/// <summary>
/// 滚动延迟(每进⼀位增加⼀倍延迟,让滚动看起来更随机⾃然)
/
// </summary>
[SerializeField]
private float _delay = 0.008f;
/// <summary>
/// Text⽂字宽⾼
/// </summary>
private Vector2 _numberSize;
/// <summary>
/// 当前数字
/// 当前数字
/// </summary>
private int _curNumber;
/// <summary>
/// 起始数字
/// </summary>
private int _fromNumber;
/// <summary>
/// 最终数字
/// </summary>
private int _toNumber;
/// <summary>
/// 各位数字的缓动实例
/
// </summary>
private List<Tweener> _tweener = new List<Tweener>();
/// <summary>
/// 是否处于数字滚动中
/// </summary>
private bool _isJumping;
/// <summary>
/// 滚动完毕回调
/// </summary>
public Action OnComplete;
private void Awake()
{
if (_numbers.Count == 0 || _unactiveNumbers.Count == 0)
{
MediaUnity.Debugger.LogError("[JumpingNumberTextComponent] 还未设置Text组件!");
return;
}
_numberSize = _numbers[0].rectTransform.sizeDelta;
}
public float duration
{
get { return _duration; }
set
{
_duration = value;
}
}
private float _different;
public float different
{
get { return _different; }
}
public void Change(int from, int to)
{
bool isRepeatCall = _isJumping && _fromNumber == from && _toNumber == to;
if (isRepeatCall) return;
bool isContinuousChange = (_toNumber == from) && ((to - from > 0 && _different > 0) || (to - from < 0 && _different < 0));        if (_isJumping && isContinuousChange)
{
}
else
{
_fromNumber = from;
_curNumber = _fromNumber;
}
_toNumber = to;
_different = _toNumber - _fromNumber;
_different = _toNumber - _fromNumber;
_speed = (int)Math.Ceiling(_different / (_duration * (1 / _rollingDuration)));        _speed = _speed == 0 ? (_different > 0 ? 1 : -1) : _speed;
SetNumber(_curNumber, false);
_isJumping = true;
StopCoroutine("DoJumpNumber");
StartCoroutine("DoJumpNumber");
}
public int number
{
get { return _toNumber; }
set
{
if (_toNumber == value) return;
Change(_curNumber, _toNumber);
}
}
IEnumerator DoJumpNumber()
{
while (true)
{
if (_speed > 0)//增加
{
_curNumber = Math.Min(_curNumber + _speed, _toNumber);
}
else if (_speed < 0) //减少
{
_curNumber = Math.Max(_curNumber + _speed, _toNumber);
}
SetNumber(_curNumber, true);
if (_curNumber == _toNumber)
{
StopCoroutine("DoJumpNumber");
_isJumping = false;
if (OnComplete != null) OnComplete();
yield return null;
}
yield return new WaitForSeconds(_rollingDuration);
}
}
/// <summary>
/// 设置战⼒数字
/// </summary>
/
// <param name="v"></param>
/// <param name="isTween"></param>
public void SetNumber(int v, bool isTween)
{
char[] c = v.ToString().ToCharArray();
Array.Reverse(c);
string s = new string(c);
if (!isTween)
{
for (int i = 0; i < _numbers.Count; i++)
{
if (i < s.Count())
_numbers[i].text = s[i] + "";
else
_numbers[i].text = "0";
}
}
}
else
{
while (_tweener.Count > 0)
{
_tweener[0].Complete();
_tweener.RemoveAt(0);
}
for (int i = 0; i < _numbers.Count; i++)
{
if (i < s.Count())
{
_unactiveNumbers[i].text = s[i] + "";
}
else
{
_unactiveNumbers[i].text = "0";
}
_unactiveNumbers[i].rectTransform.anchoredPosition = new Vector2(_unactiveNumbers[i].rectTransform.anchoredPosition.x, (_speed > 0 ? -1 : 1) * _n                _numbers[i].rectTransform.anchoredPosition = new Vector2(_unactiveNumbers[i].rectTransform.anchoredPosition.x, 0);
if (_unactiveNumbers[i].text != _numbers[i].text)
{
DoTween(_numbers[i], (_speed > 0 ? 1 : -1) * _numberSize.y, _delay * i);
DoTween(_unactiveNumbers[i], 0, _delay * i);
Text tmp = _numbers[i];
_numbers[i] = _unactiveNumbers[i];
_unactiveNumbers[i] = tmp;
}
}
}
}
public void DoTween(Text text, float endValue, float delay)
{
Tweener t = DOTween.To(() => Transform.anchoredPosition, (x) =>
{
}, new Transform.anchoredPosition.x, endValue), _rollingDuration - delay).SetDelay(delay);
_tweener.Add(t);
}
[ContextMenu("测试数字变化")]
public void TestChange()
{
Change(UnityEngine.Random.Range(1, 1), UnityEngine.Random.Range(1, 100000));
}
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。