using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; [AddComponentMenu("UI/Extensions/TextPro")] /// /// 扩展Text 这几个标签不要在同一行使用多个 /// 1.增强RichText 支持Right Center Left /// public class TextPro : Text { protected override void OnPopulateMesh(VertexHelper toFill) { RichTextAlignDataSupport(toFill); } private void RemoveSameAlignData(List alignDatas) { IList lines = cachedTextGenerator.lines; List removeAlignDatas = new List(); for (int i = 0; i < alignDatas.Count; i++) { AlignData alignData = alignDatas[i]; for (int j = 0; j < lines.Count; j++) { UILineInfo lInfo = lines[j]; if (lInfo.startCharIdx <= alignData.startCharIndex) { alignData.lineIndex = j; alignData.lineStartCharIndex = lInfo.startCharIdx; if (j == lines.Count - 1) { if (alignData.startCharIndex > cachedTextGenerator.characterCountVisible) { removeAlignDatas.Add(alignData); } else alignData.lineEndCharIndex = cachedTextGenerator.characterCountVisible; } } else { alignData.lineEndCharIndex = lInfo.startCharIdx - 1; break; } } alignDatas[i] = alignData; } List lineList = new List(); for (int i = 0; i < alignDatas.Count; i++) { AlignData alignData = alignDatas[i]; //Debug.Log("alignData.lineIndex :" + alignData.lineIndex); if (lineList.Contains(alignData.lineIndex)) { removeAlignDatas.Add(alignData); continue; } else { lineList.Add(alignData.lineIndex); } } for (int i = 0; i < removeAlignDatas.Count; i++) { alignDatas.Remove(removeAlignDatas[i]); } } private void RichTextAlignDataSupport(VertexHelper toFill) { if (!supportRichText) { base.OnPopulateMesh(toFill); return; } List alignDatas=new List(); //string changedText = ""; var orignText = m_Text; m_Text = DealWithTextContent(m_Text,ref alignDatas); //changedText = m_Text; base.OnPopulateMesh(toFill); m_Text = orignText; RectTransform rectTransform = GetComponent(); float rangeWith =rectTransform.sizeDelta.x; IList characters = cachedTextGenerator.characters; Rect rectExtents = cachedTextGenerator.rectExtents; List stream = new List(); toFill.GetUIVertexStream(stream); toFill.Clear(); RemoveSameAlignData(alignDatas); for (int i = 0; i < alignDatas.Count; i++) { AlignData alignData = alignDatas[i]; //Debug.Log("characters.Count :" + characters.Count + " stream.Count:" + stream.Count + " alignData.lineEndCharIndex:" + alignData.lineEndCharIndex); if (alignData.lineEndCharIndex >= characters.Count) continue; if (alignData.lineStartCharIndex >= characters.Count) continue; if ((alignData.lineEndCharIndex * 6) > stream.Count) continue; if (alignData.lineStartCharIndex * 6 >= stream.Count) continue; int indexEnd = alignData.lineEndCharIndex * 6 - 3; int indexStart = alignData.lineStartCharIndex * 6; if (alignData.alignType == AlignType.Right) { float detaMove = rangeWith / 2 - stream[indexEnd].position.x; for (int v = alignData.lineStartCharIndex * 6; v < alignData.lineEndCharIndex * 6; v++) { UIVertex ver = stream[v]; //if (v >= ((alignData.lineEndCharIndex - 1) * 6) && v <= (alignData.lineEndCharIndex * 6)) //Debug.Log("Pos :" + ver.position); ver.position += new Vector3(detaMove, 0, 0); // ver.color = Color.red; stream[v] = ver; } } else if (alignData.alignType == AlignType.Left) { float detaMove = (-rangeWith / 2) - stream[indexStart].position.x; //Debug.Log("LLeft alignData.lineStartCharIndex:" + alignData.lineStartCharIndex + " alignData.lineEndCharIndex:" + alignData.lineEndCharIndex); for (int v = alignData.lineStartCharIndex * 6; v < alignData.lineEndCharIndex * 6; v++) { UIVertex ver = stream[v]; ver.position += new Vector3(detaMove, 0, 0); //if(v== (alignData.lineEndCharIndex * 6-1)) //ver.color = Color.green; stream[v] = ver; } } else if (alignData.alignType == AlignType.Center) { float lineCharLenth = Mathf.Abs(stream[indexEnd].position.x) + Mathf.Abs(stream[indexStart].position.x); float detaMove = (lineCharLenth) / 2 - stream[indexEnd].position.x; for (int v = alignData.lineStartCharIndex * 6; v < alignData.lineEndCharIndex * 6; v++) { UIVertex ver = stream[v]; ver.position += new Vector3(detaMove, 0, 0); //ver.color = Color.blue; stream[v] = ver; } } } toFill.AddUIVertexTriangleStream(stream); } private string DealWithTextContent(string content,ref List alignDatas) { if (alignDatas == null) alignDatas = new List(); alignDatas.Clear(); var temp = content; while (true) { for (int i = 0; i < temp.Length; i++) { if (temp[i] == '<') { int surplusLenth = temp.Length - i - 1; string testStr = ""; bool isResult = false; if (surplusLenth >= alignRightString.Length) { testStr = temp.Substring(i, alignRightString.Length); if (testStr == alignRightString) { isResult = true; AlignData align = new AlignData(); align.alignType = AlignType.Right; align.startCharIndex = i; alignDatas.Add(align); } } if (!isResult) { if (surplusLenth >= alignLeftString.Length) { testStr = temp.Substring(i, alignLeftString.Length); if (testStr == alignLeftString) { isResult = true; AlignData align = new AlignData(); align.alignType = AlignType.Left; align.startCharIndex = i; alignDatas.Add(align); } } } if (!isResult) { if (surplusLenth >= alignCenterString.Length) { testStr = temp.Substring(i, alignCenterString.Length); if (testStr == alignCenterString) { isResult = true; AlignData align = new AlignData(); align.alignType = AlignType.Center; align.startCharIndex = i; alignDatas.Add(align); } } } if (isResult) { temp = temp.Remove(i, testStr.Length); i = 0; } } } break; } //Debug.Log("alignDatas :" + alignDatas.Count); return temp; } private const string alignRightString = ""; private const string alignLeftString = ""; private const string alignCenterString = ""; } public struct AlignData { public AlignType alignType; public int startCharIndex; public int lineEndCharIndex; public int lineStartCharIndex; public int lineIndex; } public enum AlignType { Right, Left, Center, }