using UnityEngine; using UnityEngine.UI; using System.Linq; using System.Collections; using System.Collections.Generic; public class LineInfo { public int EndIndex; public int StartIndex; public LineInfo(int startIndex, int endIndex) { EndIndex = endIndex; StartIndex = startIndex; } } public class RenderInfo { public LineInfo LineInfo; public SpriteInfo SpriteInfo; public RenderInfo(LineInfo lineInfo, SpriteInfo spriteInfo) { LineInfo = lineInfo; SpriteInfo = spriteInfo; } } public class TestText : Text { #region 变量 public int LeftIndex; public int RightIndex; public bool Draw; public float Width; public float Height; public string SpriteName; public SpriteInfo SpriteInfo; public List LineInfoList; public List VertexImage; public List VertexStream; public List RenderInfoList; public ImagePlus ImagePlus { get { if (_ImagePlus == null) { _ImagePlus = GetComponentInChildren(); if (_ImagePlus == null) { GameObject go = new GameObject("ImagePlus", typeof(ImagePlus)); RectTransform rectTra = go.GetComponent(); rectTra.SetParent(rectTransform); } } return _ImagePlus; } set { _ImagePlus = value; } } private ImagePlus _ImagePlus; #endregion protected override void Awake() { base.Awake(); verticalOverflow = VerticalWrapMode.Overflow; horizontalOverflow = HorizontalWrapMode.Wrap; } protected override void OnPopulateMesh(VertexHelper toFill) { base.OnPopulateMesh(toFill); if (ImagePlus == null) { Debug.LogWarning("There is no ImagePlus"); return; } LeftIndex = text.IndexOf("<("); RightIndex = text.IndexOf(")>"); if (LeftIndex == -1 || RightIndex == -1) { Draw = false; } else { SpriteName = text.Between(LeftIndex + 2, RightIndex - 1); if (SpriteAsset.SpriteInfoDic.TryGetValue(SpriteName, out SpriteInfo)) { Draw = true; } else { Draw = false; } } if (Draw) { Draw = false; VertexImage = new List(); VertexStream = new List(); toFill.GetUIVertexStream(VertexStream); Height = preferredHeight / cachedTextGenerator.lineCount; Width = (Height / SpriteInfo.Height) * SpriteInfo.Width; LineInfoList = GetLineInfo(); RenderInfoList = GetRenderInfo(); RenderLine(RenderInfoList[0], VertexImage, VertexStream, toFill); ImagePlus.UpdateStatus(true, new VertexHelper(), VertexImage); } else { ImagePlus.UpdateStatus(false, new VertexHelper(), null); } } protected void RenderLine(RenderInfo renderInfo, List vertexImage, List vertexStream, VertexHelper toFill) { Vector3 centerLeft = new Vector3(); if (LeftIndex == renderInfo.LineInfo.StartIndex) { centerLeft = (vertexStream[LeftIndex * 6 + 4].position + vertexStream[LeftIndex * 6 + 5].position) / 2; } else { centerLeft = (vertexStream[(LeftIndex - 1) * 6 + 1].position + vertexStream[(LeftIndex - 1) * 6 + 2].position) / 2; } UIVertex[] vertices = new UIVertex[4]; vertices[0].position = centerLeft + new Vector3(0, -Height / 2, 0); vertices[1].position = centerLeft + new Vector3(0, Height / 2, 0); vertices[2].position = centerLeft + new Vector3(Width, Height / 2, 0); vertices[3].position = centerLeft + new Vector3(Width, -Height / 2, 0); vertices[0].color = Color.white; vertices[1].color = Color.white; vertices[2].color = Color.white; vertices[3].color = Color.white; vertices[0].uv0 = SpriteAsset.SpriteInfoDic[SpriteName].UvList[0]; vertices[1].uv0 = SpriteAsset.SpriteInfoDic[SpriteName].UvList[1]; vertices[2].uv0 = SpriteAsset.SpriteInfoDic[SpriteName].UvList[2]; vertices[3].uv0 = SpriteAsset.SpriteInfoDic[SpriteName].UvList[3]; UIVertex vertex = new UIVertex(); for (int i = LeftIndex; i < RightIndex + 2; i++) { toFill.SetUIVertex(vertex, i * 4); toFill.SetUIVertex(vertex, i * 4 + 1); toFill.SetUIVertex(vertex, i * 4 + 2); toFill.SetUIVertex(vertex, i * 4 + 3); } if (LeftIndex == renderInfo.LineInfo.StartIndex) { float offsetX1 = VertexStream[(RightIndex + 2) * 6].position.x - vertices[3].position.x; float offsetX2 = (VertexStream[(BreakIndex - 1) * 6 + 1].position.x + vertices[0].position.x - offsetX1) / 2; for (int i = RightIndex + 2; i < BreakIndex; i++) { vertex = VertexStream[i * 6]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4); vertex = VertexStream[i * 6 + 1]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4 + 1); vertex = VertexStream[i * 6 + 2]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4 + 2); vertex = VertexStream[i * 6 + 4]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4 + 3); } vertices[0].position.x -= offsetX2; vertices[1].position.x -= offsetX2; vertices[2].position.x -= offsetX2; vertices[3].position.x -= offsetX2; } else { float offsetX1 = VertexStream[(RightIndex + 2) * 6].position.x - vertices[3].position.x; float offsetX2 = (VertexStream[(BreakIndex - 1) * 6 + 1].position.x + VertexStream[0].position.x - offsetX1) / 2; for (int i = 0; i < LeftIndex; i++) { vertex = VertexStream[i * 6]; vertex.position.x -= offsetX2; toFill.SetUIVertex(vertex, i * 4); vertex = VertexStream[i * 6 + 1]; vertex.position.x -= offsetX2; toFill.SetUIVertex(vertex, i * 4 + 1); vertex = VertexStream[i * 6 + 2]; vertex.position.x -= offsetX2; toFill.SetUIVertex(vertex, i * 4 + 2); vertex = VertexStream[i * 6 + 4]; vertex.position.x -= offsetX2; toFill.SetUIVertex(vertex, i * 4 + 3); } for (int i = RightIndex + 2; i < BreakIndex; i++) { vertex = VertexStream[i * 6]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4); vertex = VertexStream[i * 6 + 1]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4 + 1); vertex = VertexStream[i * 6 + 2]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4 + 2); vertex = VertexStream[i * 6 + 4]; vertex.position.x -= offsetX1 + offsetX2; toFill.SetUIVertex(vertex, i * 4 + 3); } vertices[0].position.x -= offsetX2; vertices[1].position.x -= offsetX2; vertices[2].position.x -= offsetX2; vertices[3].position.x -= offsetX2; } } protected List GetLineInfo() { int startIndex = 0; List lineInfoList = new List(); if (cachedTextGenerator.lineCount > 1) { for (int i = 0; i < text.Length; i++) { if (text[i] == '\n') { if (text[startIndex] != '\n') { lineInfoList.Add(new LineInfo(startIndex, i)); } if (i + 1 == text.Length) { return lineInfoList; } else { startIndex = i + 1; } } } } lineInfoList.Add(new LineInfo(startIndex, text.Length - 1)); return lineInfoList; } protected List GetRenderInfo() { List renderInfoList = new List(); for (int i = 0; i < LineInfoList.Count; i++) { if (LeftIndex >= LineInfoList[i].StartIndex && LeftIndex < LineInfoList[i].EndIndex) { renderInfoList.Add(new RenderInfo(LineInfoList[i], SpriteInfo)); break; } } return renderInfoList; } }