| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 | using System.Collections;using System.Collections.Generic;using UnityEngine;using FairyGUI;using System;namespace GFGGame{    public class TypingFadeEffect : TypingEffect    {        protected Color32[] _backupColor32s;        protected Color32[] _color32s;        protected float charFadeDuration = 0.1f;        private float _currentCharFadeTime;        public Action typeFinishedAction;        public float progressShowNextWord = 0.8f;        /// <summary>        ///         /// </summary>        /// <param name="textField"></param>        public TypingFadeEffect(TextField textField) : base(textField) { }        /// <summary>        ///         /// </summary>        /// <param name="textField"></param>        public TypingFadeEffect(GTextField textField) : base(textField) { }        /// <summary>        /// 开始打字效果。可以重复调用重复启动。        /// </summary>        public new void Start()        {            _textField.graphics.meshModifier -= OnMeshModified;            _textField.Redraw();            _textField.graphics.meshModifier += OnMeshModified;            _stroke = false;            _shadow = false;            _strokeDrawDirs = 4;            _mainLayerStart = 0;            _mainLayerVertCount = 0;            _printIndex = 0;            _vertIndex = 0;            _currentCharFadeTime = 0.0f;            _started = true;            int vertCount = _textField.graphics.mesh.vertexCount;            UpdateBackUp();            // Clear mesh info            if (_vertices == null || _vertices.Length != vertCount)                _vertices = new Vector3[vertCount];            if (_color32s == null || _color32s.Length != vertCount)            {                _color32s = new Color32[vertCount];            }            Vector3 zero = Vector3.zero;            for (int i = 0; i < vertCount; i++)                _vertices[i] = zero;            _textField.graphics.mesh.vertices = _vertices;            //隐藏所有混排的对象            if (_textField.richTextField != null)            {                int ec = _textField.richTextField.htmlElementCount;                for (int i = 0; i < ec; i++)                    _textField.richTextField.ShowHtmlObject(i, false);            }            int charCount = _textField.charPositions.Count;            for (int i = 0; i < charCount; i++)            {                TextField.CharPosition cp = _textField.charPositions[i];                _mainLayerVertCount += cp.vertCount;            }            if (_mainLayerVertCount < vertCount) //说明有描边或者阴影            {                int repeat = vertCount / _mainLayerVertCount;                _stroke = repeat > 2;                _shadow = repeat % 2 == 0;                _mainLayerStart = vertCount - vertCount / repeat;                _strokeLayerStart = _shadow ? (vertCount / repeat) : 0;                _strokeDrawDirs = repeat > 8 ? 8 : 4;            }            Timers.inst.StartCoroutine(UpdateFadeProgress());        }        public bool PrintFade(byte alpha)        {            if (!_started)                return false;            TextField.CharPosition cp;            List<TextField.CharPosition> charPositions = _textField.charPositions;            int listCnt = charPositions.Count;            while (_printIndex < listCnt - 1) //最后一个是占位的,无效的,所以-1            {                cp = charPositions[_printIndex];                if (cp.vertCount > 0)                    output(cp.vertCount, alpha);                if (cp.imgIndex > 0) //这是一个图片                {                    _textField.richTextField.ShowHtmlObject(cp.imgIndex - 1, true);                    return true;                }                else if (!char.IsWhiteSpace(_textField.parsedText[Mathf.Max(_printIndex - 1, 0)]))                    return true;            }            Cancel();            typeFinishedAction.Invoke();            return false;        }        private void output(int vertCount, byte alpha)        {            int start, end;            start = _mainLayerStart + _vertIndex;            end = start + vertCount;            for (int i = start; i < end; i++)            {                _vertices[i] = _backupVerts[i];                _color32s[i] = _backupColor32s[i];                _color32s[i].a = alpha;            }                            if (_stroke)            {                start = _strokeLayerStart + _vertIndex;                end = start + vertCount;                for (int i = start; i < end; i++)                {                    for (int j = 0; j < _strokeDrawDirs; j++)                    {                        int k = i + _mainLayerVertCount * j;                        _vertices[k] = _backupVerts[k];                    }                }            }            if (_shadow)            {                start = _vertIndex;                end = start + vertCount;                for (int i = start; i < end; i++)                {                    _vertices[i] = _backupVerts[i];                }            }            _textField.graphics.mesh.vertices = _vertices;            _textField.graphics.mesh.colors32 = _color32s;            if (alpha == 255)            {                _vertIndex += vertCount;            }        }        public new void Cancel()        {            if (!_started)                return;            _started = false;            _textField.graphics.meshModifier -= OnMeshModified;            _textField.graphics.SetMeshDirty();        }        /// <summary>        /// 当打字过程中,文本可能会由于字体纹理更改而发生字体重建,要处理这种情况。        /// 图片对象不需要处理,因为HtmlElement.status里设定的隐藏标志不会因为Mesh更新而被冲掉。        /// </summary>        void OnMeshModified()        {            if (_textField.graphics.mesh.vertexCount != _backupVerts.Length) //可能文字都改了            {                Cancel();                return;            }            UpdateBackUp();            int vertCount = _vertices.Length;            Vector3 zero = Vector3.zero;            for (int i = 0; i < vertCount; i++)            {                if (_vertices[i] != zero)                    _vertices[i] = _backupVerts[i];            }            _textField.graphics.mesh.vertices = _vertices;        }        IEnumerator UpdateFadeProgress()        {            while (true)            {                if (!_started)                    break;                _currentCharFadeTime += Time.deltaTime;                float progress = _currentCharFadeTime / charFadeDuration;                if(progress > progressShowNextWord)                {                    PrintFade(255);                    ++_printIndex;                    _currentCharFadeTime = 0.0f;                    int listCnt = _textField.charPositions.Count;                    if (_printIndex >= listCnt - 1)                    {                        typeFinishedAction.Invoke();                        break;                    }                }                else                 {                    byte alpha = (byte)(progress * 255);                    PrintFade(alpha);                }                yield return new WaitForEndOfFrame();            }        }        // Back up origin text info        protected void UpdateBackUp()        {            _backupVerts = _textField.graphics.mesh.vertices;            _backupColor32s = _textField.graphics.mesh.colors32;        }        public void SetSpeed(float speed)        {            charFadeDuration = speed;        }    }}
 |