Unity实现Text逐字显示

Unity实现Text逐字显示

不说废话直接上代码

[RequireComponent(typeof(Text))]
    public class TrendsText : MonoBehaviour
    {
        public uint m_TextIndent;       //首行缩进--字符数
        [TextArea(4, 10)]
        public string m_Text;           //显示的文本内容
        public bool m_Enable;           //是否在OnEnable中初始化Play
        private Text m_Conetnt;         //用于显示的文本
        [Header("字/每秒")]
        public float m_ShowSpeed = 1;   //动态文字的速度
        //与文字播放同时播放的音频
        public AudioClip m_AudioClip;
        //文字播完回调
        public CallBack m_CallBack = new CallBack();

        public ScrollRect m_ScrollRect;


        private char[] m_Text_Char;
        private bool suspend = false;
        private AudioSource m_AudioSource;


        private void Awake()
        {
            m_Conetnt = this.GetComponent<Text>();
        }
        private void OnEnable()
        {
            if (m_Enable)
                Play();
        }
        /// <summary>
        /// 重新播放
        /// </summary>
        public void Play()
        {
            suspend = false;
            //\u3000为中文空格英文空格会引起unity中Text的自动换行因此将内容中的英文空格换成中文空格
            string str = m_Text.Replace(" ", "\u3000");
            string LineHead = "";
            //设置段落的首行缩进的字符数
            if (m_TextIndent != 0)
            {
                for (int i = 0; i < m_TextIndent; i++)
                {
                    LineHead += "\u3000";
                }
                str = str.Replace("\n", "\n" + LineHead);
                str = LineHead + str;
            }
            //将转换好的文本转换成Char数组以便于逐字读写
            m_Text_Char = str.ToCharArray();
            //当音频不为空时,处理音频的播放
            if (m_AudioClip != null)
            {
                if (m_AudioSource == null)
                    m_AudioSource = this.GetComponent<AudioSource>();
                if (m_AudioSource == null)
                    m_AudioSource = this.gameObject.AddComponent<AudioSource>();
                m_AudioSource.clip = m_AudioClip;
                //读写速度根据音频长度平均计算
                m_ShowSpeed = str.Length / m_AudioClip.length;
            }
            StartCoroutine("Player");
        }
        /// <summary>
        /// 播放无语音
        /// </summary>
        /// <param name="varCentent">播放的内容</param>
        public void Play(string varCentent)
        {
            m_Text = varCentent;
            m_AudioClip = null;
            Play();
        }
        /// <summary>
        /// 播放有语音
        /// </summary>
        /// <param name="varCentent">播放的内容</param>
        /// <param name="audio">跟踪的语言</param>
        public void Play(string varCentent, AudioClip audio)
        {
            m_Text = varCentent;
            m_AudioClip = audio;

            Play();
        }

        /// <summary>
        /// 暂停播放
        /// </summary>
        public void Pause()
        {
            suspend = true;
        }
        /// <summary>
        /// 恢复播放
        /// </summary>
        public void Recovery()
        {
            suspend = false;
        }

        /// <summary>
        /// 停止播放(无法继续)
        /// </summary>
        public void Stop()
        {
            StopCoroutine("Player");
        }


        IEnumerator Player()
        {
            float idx = 0;
            m_Conetnt.text = "";
            yield return 0;
            if (m_AudioSource != null)
                m_AudioSource.Play();
            RectTransform TempCententRect = null;
            RectTransform TempScrollRect = null;
            if (m_ScrollRect != null)
            {
                TempCententRect = m_ScrollRect.content.GetComponent<RectTransform>();
                TempScrollRect = m_ScrollRect.GetComponent<RectTransform>();
            }
            while (idx <= m_Text_Char.Length)
            {
            //暂停处理
                if (suspend)
                {
                    yield return new WaitForFixedUpdate();
                    continue;
                }
                float TempTimes = Time.fixedDeltaTime;
                float currfont = TempTimes * m_ShowSpeed;
                //更新应显示的字的数量
                idx += currfont;
                string currcentent = "";
                //获取显示的字的内容
                for (int i = 0; i < m_Text_Char.Length; i++)
                {
                    if (i <= idx)
                        currcentent += m_Text_Char[i];
                        //过滤换行字符
                    else if (m_Text_Char[i] == '\n')
                        idx += 1;
                        //过滤空格
                    else if (m_Text_Char[i] == ' ' || m_Text_Char[i] == '\u3000')
                        idx += 1;
                    else
                        break;
                }
                m_Conetnt.text = currcentent;
                //当有ScrollRect时让文字始终显示刷新文字的地方
                if (m_ScrollRect != null)
                {
                //更新滑动区域大小使之与文本框大小相同(仅高度相同)
                    TempCententRect.sizeDelta = new Vector2(TempCententRect.sizeDelta.x, m_Conetnt.preferredHeight);
                    //当滑动高度大于ScrollRect的显示高度时保证滑动区域始终在最下方
                    if (TempCententRect.sizeDelta.y > TempScrollRect.sizeDelta.y)
                    {
                        if (m_ScrollRect.verticalScrollbar != null)
                            m_ScrollRect.verticalScrollbar.value = 0;
                    }
                }
                //与FixedUpdate同步避免程序卡死
                yield return new WaitForFixedUpdate();
            }
            //当音频不为空时处理音频
            if (m_AudioSource != null)
            {
            //当音频未播放完成时不结束进程
                while (m_AudioSource.isPlaying)
                {
                //与FixedUpdate同步避免程序卡死
                    yield return new WaitForFixedUpdate();
                }
            }
            //音频播放完成清理音频信息
            if (m_AudioSource != null)
                Destroy(m_AudioSource);
            //等待一帧以便以上信息运行完成
            yield return 0;
            m_AudioSource = null;
            //执行播放完成回调
            m_CallBack.Invoke();
        }
        public class CallBack : UnityEvent
        {
            public CallBack()
            {
            }
        }
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值