讓數字變化炫酷起來,數字滾動Text組件[Unity]

來源:互聯網
上載者:User
讓數字滾動起來

上周我的策劃又提了樣需求,當玩家評分發生變動時,螢幕出現人物評分浮層UI,播放評分數字滾動動畫。這類數字滾動需求非常常見,我就按一般思路,將startvalue與endvalue每隔一點時間做插值變化並顯示,從而實現數字滾動的效果,這也是大部分app及遊戲採取的實現,效果如下:

幾行代碼寫完給策劃看效果,策劃說不是這樣的效果,跟XX遊戲做得不一樣,得像lao虎機數字一樣,有真實的數字滾動效果,好吧,此滾動非彼滾動,期望效果應該是下面這樣,看起來更確實炫酷:
代碼實現

這樣的效果也不難實現,但要注意一些細節,讓動畫看起來更真實: 仍然每隔一點時間做插值變化,算出插值後,不再是簡單地修改Text內容了,而是準備用另一個Text顯示新值,2個Text都自底向上做緩動,造成像lao虎機一樣,新值頂掉舊值的動畫效果,要注意每一位元字都單獨使用Text組件顯示。我們遊戲裡的戰力固定6位元顯示,所以總共設定了12個Text組件。 錯開每一位元字的滾動時間點,讓滾動效果看起來更自然。設定一個Delay變數,從個位起,後面的每一位都增加一倍Delay再滾動。

/* ============================================================================== * 功能描述:數字動態變化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;        _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) * _numberSize.y);                _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(() => text.rectTransform.anchoredPosition, (x) =>        {            text.rectTransform.anchoredPosition = x;        }, new Vector2(text.rectTransform.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));    }}
標籤:  遊戲開發,  Unity

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.