using UnityEngine; using UnityEngine.UI; using System.Linq; using System.Collections; using System.Collections.Generic; public class LineInfo { public int Count; public int EndIndex; public int StartIndex; public LineInfo(int startIndex, int endIndex) { EndIndex = endIndex; StartIndex = startIndex; Count = EndIndex - StartIndex + 1; } } public class RenderInfo { public LineInfo LineInfo { get { return _LineInfo; } set { _LineInfo = value; EndIndex = _LineInfo.EndIndex; StartIndex = _LineInfo.StartIndex; LineCount = _LineInfo.Count; } } public SpriteInfo SpriteInfo { get { return _SpriteInfo; } set { _SpriteInfo = value; UvList = _SpriteInfo.UvList; RawWidth = _SpriteInfo.Width; RawHeight = _SpriteInfo.Height; RenderCount = RightIndex - LeftIndex + 1; } } private LineInfo _LineInfo; private SpriteInfo _SpriteInfo; public int LineCount; public int RenderCount; public int LeftIndex; public int RightIndex; public int EndIndex; public int StartIndex; public float Width; public float Height; public float RawWidth; public float RawHeight; public List UvList; } public class TextPlus : Text { #region 变量 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; public bool Draw; public RenderInfo RenderInfo; public List LineInfoList; #endregion protected override void OnPopulateMesh(VertexHelper toFill) { base.OnPopulateMesh(toFill); int leftIndex = text.IndexOf("<("); int rightIndex = text.IndexOf(")>"); if (leftIndex == -1 || rightIndex == -1) { Draw = false; } else { rightIndex++; string spriteName = text.Between(leftIndex + 2, rightIndex - 2); SpriteInfo spriteInfo; if (SpriteAsset.SpriteInfoDic.TryGetValue(spriteName, out spriteInfo)) { Draw = true; RenderInfo = new RenderInfo(); RenderInfo.LeftIndex = leftIndex; RenderInfo.RightIndex = rightIndex; RenderInfo.SpriteInfo = spriteInfo; } else { Draw = false; } } if (Draw) { Draw = false; List vertexImage = new List(); List vertexStream = new List(); toFill.GetUIVertexStream(vertexStream); RenderInfo.Height = preferredHeight / cachedTextGenerator.lineCount; RenderInfo.Width = (RenderInfo.Height / RenderInfo.RawHeight) * RenderInfo.RawWidth; GetRenderLine(); RenderLine(vertexImage, vertexStream, toFill); ImagePlus.UpdateStatus(true, new VertexHelper(), vertexImage); } else { ImagePlus.UpdateStatus(false, new VertexHelper(), null); } } protected void RenderLine(List vertexImage, List vertexStream, VertexHelper vertexHelper) { UIVertex[] vertices = new UIVertex[4]; vertices[0].color = Color.white; vertices[1].color = Color.white; vertices[2].color = Color.white; vertices[3].color = Color.white; vertices[0].uv0 = RenderInfo.UvList[0]; vertices[1].uv0 = RenderInfo.UvList[1]; vertices[2].uv0 = RenderInfo.UvList[2]; vertices[3].uv0 = RenderInfo.UvList[3]; if (RenderInfo.LineCount == RenderInfo.RenderCount) { #region MyRegion if (alignment == TextAnchor.LowerCenter || alignment == TextAnchor.MiddleCenter || alignment == TextAnchor.UpperCenter) { #region MyRegion Vector3 center = new Vector3(0, (vertexStream[RenderInfo.StartIndex * 6].position.y + vertexStream[RenderInfo.StartIndex * 6 + 4].position.y) / 2, 0); vertices[0].position = center + new Vector3(-RenderInfo.Width / 2, RenderInfo.Height / 2, 0); vertices[1].position = center + new Vector3(RenderInfo.Width / 2, RenderInfo.Height / 2, 0); vertices[2].position = center + new Vector3(RenderInfo.Width / 2, -RenderInfo.Height / 2, 0); vertices[3].position = center + new Vector3(-RenderInfo.Width / 2, -RenderInfo.Height / 2, 0); #endregion } else if (alignment == TextAnchor.LowerRight || alignment == TextAnchor.MiddleRight || alignment == TextAnchor.UpperRight) { #region MyRegion Vector3 centerRight = (vertexStream[RenderInfo.RightIndex * 6 + 1].position + vertexStream[RenderInfo.RightIndex * 6 + 2].position) / 2; vertices[0].position = centerRight + new Vector3(-RenderInfo.Width, RenderInfo.Height / 2, 0); vertices[1].position = centerRight + new Vector3(0, RenderInfo.Height / 2, 0); vertices[2].position = centerRight + new Vector3(0, -RenderInfo.Height / 2, 0); vertices[3].position = centerRight + new Vector3(-RenderInfo.Width, -RenderInfo.Height / 2, 0); #endregion } else if (alignment == TextAnchor.LowerLeft || alignment == TextAnchor.MiddleLeft || alignment == TextAnchor.UpperLeft) { #region MyRegion Vector3 centerLeft = (vertexStream[0].position + vertexStream[4].position) / 2; vertices[0].position = centerLeft + new Vector3(0, RenderInfo.Height / 2, 0); vertices[1].position = centerLeft + new Vector3(RenderInfo.Width, RenderInfo.Height / 2, 0); vertices[2].position = centerLeft + new Vector3(RenderInfo.Width, -RenderInfo.Height / 2, 0); vertices[3].position = centerLeft + new Vector3(0, -RenderInfo.Height / 2, 0); #endregion } #endregion } else { #region MyRegion if (alignment == TextAnchor.LowerCenter || alignment == TextAnchor.MiddleCenter || alignment == TextAnchor.UpperCenter) { #region MyRegion Vector3 centerLeft = new Vector3(); if (RenderInfo.LeftIndex == RenderInfo.StartIndex) { centerLeft = (vertexStream[RenderInfo.LeftIndex * 6].position + vertexStream[RenderInfo.LeftIndex * 6 + 4].position) / 2; } else { centerLeft = (vertexStream[(RenderInfo.LeftIndex - 1) * 6 + 1].position + vertexStream[(RenderInfo.LeftIndex - 1) * 6 + 2].position) / 2; } vertices[0].position = centerLeft + new Vector3(0, RenderInfo.Height / 2, 0); vertices[1].position = centerLeft + new Vector3(RenderInfo.Width, RenderInfo.Height / 2, 0); vertices[2].position = centerLeft + new Vector3(RenderInfo.Width, -RenderInfo.Height / 2, 0); vertices[3].position = centerLeft + new Vector3(0, -RenderInfo.Height / 2, 0); if ((RenderInfo.RightIndex) != RenderInfo.EndIndex) { float offsetX1 = vertexStream[(RenderInfo.RightIndex + 1) * 6].position.x - vertices[1].position.x; float offsetX2 = (vertexStream[RenderInfo.EndIndex * 6 + 1].position.x + vertexStream[RenderInfo.StartIndex * 6].position.x - offsetX1) / 2; UIVertex newVertex; for (int i = RenderInfo.RightIndex + 1; i < RenderInfo.EndIndex + 1; i++) { newVertex = vertexStream[i * 6]; newVertex.position.x -= offsetX1 + offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4); newVertex = vertexStream[i * 6 + 1]; newVertex.position.x -= offsetX1 + offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4 + 1); newVertex = vertexStream[i * 6 + 2]; newVertex.position.x -= offsetX1 + offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4 + 2); newVertex = vertexStream[i * 6 + 4]; newVertex.position.x -= offsetX1 + offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4 + 3); } for (int i = RenderInfo.StartIndex; i < RenderInfo.LeftIndex; i++) { newVertex = vertexStream[i * 6]; newVertex.position.x -= offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4); newVertex = vertexStream[i * 6 + 1]; newVertex.position.x -= offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4 + 1); newVertex = vertexStream[i * 6 + 2]; newVertex.position.x -= offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4 + 2); newVertex = vertexStream[i * 6 + 4]; newVertex.position.x -= offsetX2; vertexHelper.SetUIVertex(newVertex, i * 4 + 3); } vertices[0].position.x -= offsetX2; vertices[1].position.x -= offsetX2; vertices[2].position.x -= offsetX2; vertices[3].position.x -= offsetX2; } #endregion } else if (alignment == TextAnchor.LowerRight || alignment == TextAnchor.MiddleRight || alignment == TextAnchor.UpperRight) { #region MyRegion Vector3 centerRight = new Vector3(); if ((RenderInfo.RightIndex) == RenderInfo.EndIndex) { centerRight = (vertexStream[RenderInfo.EndIndex * 6 + 1].position + vertexStream[RenderInfo.EndIndex * 6 + 2].position) / 2; } else { centerRight = (vertexStream[(RenderInfo.RightIndex) * 6 + 1].position + vertexStream[(RenderInfo.RightIndex) * 6 + 2].position) / 2; } vertices[0].position = centerRight + new Vector3(-RenderInfo.Width, RenderInfo.Height / 2, 0); vertices[1].position = centerRight + new Vector3(0, RenderInfo.Height / 2, 0); vertices[2].position = centerRight + new Vector3(0, -RenderInfo.Height / 2, 0); vertices[3].position = centerRight + new Vector3(-RenderInfo.Width, -RenderInfo.Height / 2, 0); if (RenderInfo.LeftIndex != RenderInfo.StartIndex) { float offsetX1 = vertices[0].position.x - vertexStream[(RenderInfo.LeftIndex - 1) * 6 + 1].position.x; UIVertex newVertex; for (int i = RenderInfo.StartIndex; i < RenderInfo.LeftIndex; i++) { newVertex = vertexStream[i * 6]; newVertex.position.x += offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4); newVertex = vertexStream[i * 6 + 1]; newVertex.position.x += offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4 + 1); newVertex = vertexStream[i * 6 + 2]; newVertex.position.x += offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4 + 2); newVertex = vertexStream[i * 6 + 4]; newVertex.position.x += offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4 + 3); } } #endregion } else if (alignment == TextAnchor.LowerLeft || alignment == TextAnchor.MiddleLeft || alignment == TextAnchor.UpperLeft) { #region MyRegion Vector3 centerLeft = new Vector3(); if (RenderInfo.LeftIndex == RenderInfo.StartIndex) { centerLeft = (vertexStream[RenderInfo.LeftIndex * 6].position + vertexStream[RenderInfo.LeftIndex * 6 + 4].position) / 2; } else { centerLeft = (vertexStream[(RenderInfo.LeftIndex - 1) * 6 + 1].position + vertexStream[(RenderInfo.LeftIndex - 1) * 6 + 2].position) / 2; } vertices[0].position = centerLeft + new Vector3(0, RenderInfo.Height / 2, 0); vertices[1].position = centerLeft + new Vector3(RenderInfo.Width, RenderInfo.Height / 2, 0); vertices[2].position = centerLeft + new Vector3(RenderInfo.Width, -RenderInfo.Height / 2, 0); vertices[3].position = centerLeft + new Vector3(0, -RenderInfo.Height / 2, 0); if ((RenderInfo.RightIndex) != RenderInfo.EndIndex) { float offsetX1 = vertexStream[(RenderInfo.RightIndex + 1) * 6].position.x - vertices[1].position.x; UIVertex newVertex; for (int i = RenderInfo.RightIndex + 1; i < RenderInfo.EndIndex + 1; i++) { newVertex = vertexStream[i * 6]; newVertex.position.x -= offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4); newVertex = vertexStream[i * 6 + 1]; newVertex.position.x -= offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4 + 1); newVertex = vertexStream[i * 6 + 2]; newVertex.position.x -= offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4 + 2); newVertex = vertexStream[i * 6 + 4]; newVertex.position.x -= offsetX1; vertexHelper.SetUIVertex(newVertex, i * 4 + 3); } } #endregion } #endregion } vertexImage.AddRange(vertices); UIVertex vertex = new UIVertex(); for (int i = RenderInfo.LeftIndex; i < RenderInfo.RightIndex + 1; i++) { vertexHelper.SetUIVertex(vertex, i * 4); vertexHelper.SetUIVertex(vertex, i * 4 + 1); vertexHelper.SetUIVertex(vertex, i * 4 + 2); vertexHelper.SetUIVertex(vertex, i * 4 + 3); } } 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 void GetRenderLine() { List lineInfoList = GetLineInfo(); for (int i = 0; i < lineInfoList.Count; i++) { if (RenderInfo.LeftIndex >= lineInfoList[i].StartIndex && RenderInfo.LeftIndex < lineInfoList[i].EndIndex) { RenderInfo.LineInfo = lineInfoList[i]; break; } } } }