Unity 文字显示动画(2)

针对第一版的优化,自动适配文字大小,TextMeshPro可以拓展各种语言。第一版字母类语言效果更好。
Unity 文字显示动画(2)_第1张图片

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

public partial class TextBeatCom
{
    List<RectTransform> m_showList = new List<RectTransform>();
    List<Animator> m_aniList = new List<Animator>();
    string m_text = string.Empty;
    int m_space = 50;
    float m_textSize = 1;

    public void Init(string text, int space = 50)
    {
        if (string.IsNullOrEmpty(text)) return;

        m_text = text;
        m_space = space;
        m_textSize = 1;
        ResetContent();
        ShowText();
    }

    void ShowText()
    {
        CreateTextItem();
        StartCoroutine(PlayAnimation());
    }

    void CreateTextItem()
    {
        float last = 0, move = 0, textLength = 0;
        int length = m_text.Length;

        for (int index = 0; index < length; index++)
        {
            var sChar = m_text[index].ToString();
            if (sChar != " ")//排除空格
            {
                float sx = 80;
                var obj = InstantiateChild(sChar, out sx);
                if (obj != null)
                {
                    textLength += sx;
                    var rt = obj.GetComponent<RectTransform>();
                    m_showList.Add(rt);
                }
            }
            else
            {
                textLength += m_space;
                m_showList.Add(null);
            }
        }

        m_textSize = (float)Screen.width / textLength;
        m_textSize = m_textSize > 1 ? 1 : m_textSize;

        for (int index = 0; index < m_showList.Count; index++)
        {
            var rt = m_showList[index];
            if (rt != null)//排除空格
            {
                //设置字体尺寸和缩放
                Vector2 size = rt.sizeDelta;
                size.x *= m_textSize;
                rt.sizeDelta = size;
                rt.localScale = Vector3.one * m_textSize;

                //设置字体间距
                move += rt.rect.width / 2 + last / 2;
                rt.anchoredPosition = new Vector2(move, 0);
                last = rt.rect.width;

                m_aniList.Add(rt.GetComponent<Animator>());
            }
            else
            {
                move += m_space;//空格
            }
        }

        if (m_showList.Count > 0 && m_showList[0] != null) move += (int)m_showList[0].rect.width >> 1;
        move = (int)move >> 1;
        for (int index = 0; index < m_showList.Count; index++)
        {
            var obj = m_showList[index];
            if (obj != null) 
            {
                var pos = obj.anchoredPosition;
                pos.x -= move;
                obj.anchoredPosition = pos;
            }
        }
    }

    Transform InstantiateChild(string sChar, out float outSX)
    {
        var child = m_xxx.transform;

        var childText = child.Find("Text");
        TextMeshProUGUI textMeshProUGUI = childText.GetComponent<TextMeshProUGUI>();
        textMeshProUGUI.text = sChar;

        childText = childText.Find("Text");
        textMeshProUGUI = childText.GetComponent<TextMeshProUGUI>();
        textMeshProUGUI.text = sChar;

        var rt = child.GetComponent<RectTransform>();
        rt.SetActive(true);

        Vector2 size = rt.sizeDelta;
        float sx = size.x;
        TMP_Text m_TextComponent = textMeshProUGUI.GetComponent<TMP_Text>();
        m_TextComponent.havePropertiesChanged = true;
        m_TextComponent.ForceMeshUpdate();

        TMP_TextInfo textInfo = m_TextComponent.textInfo;
        int characterCount = textInfo.characterInfo.Length;
        if (characterCount > 0)
        {
            //sx = textInfo.characterInfo[0].ascender * textInfo.characterInfo[0].aspectRatio - textInfo.characterInfo[0].baseLine;
            sx = textInfo.characterInfo[0].bottomRight.x - textInfo.characterInfo[0].bottomLeft.x;
        }
        size.x = sx;
        rt.sizeDelta = size;
        rt.SetActive(false);

        outSX = size.x * 1.3f;
        return GameObject.Instantiate(child, m_scroll.content.transform);
    }

    IEnumerator PlayAnimation()
    {
        yield return PlayShow();
        PlayBeat();
    }

    IEnumerator PlayShow()
    {
        int playFinishNum = 0;
        for (int i = 0; i < m_aniList.Count; i++)
        {
            var obj = m_aniList[i];
            obj.SetActive(true);
            obj.OnPlay("Show").OnComplete(() => { playFinishNum++; });
            yield return new WaitForSecondsRealtime(0.05f);
        }

        yield return new WaitUntil(() => playFinishNum >= m_aniList.Count);
    }

    void PlayBeat()
    {
        for (int index = 0; index < m_aniList.Count; index++)
        {
            var obj = m_aniList[index];
            obj.Play("Beat");
        }
    }

    void ResetContent()
    {
        for (int index = 0; index < m_scroll.content.childCount; index++)
        {
            m_scroll.content.GetChild(index).SetActive(false);
        }
    }

    public void OnClear()
    {
        for (int index = 0; index < m_showList.Count; index++)
        {
            var tran = m_showList[index];
            m_showList.Remove(tran);
            index--;
            if(tran != null) GameObject.Destroy(tran.gameObject);
        }
        m_showList.Clear();
        m_aniList.Clear();
    }
}

你可能感兴趣的:(unity)