针对第一版的优化,自动适配文字大小,TextMeshPro可以拓展各种语言。第一版字母类语言效果更好。
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();}
}