123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601 |
- using UnityEngine;
- using UnityEngine.UI;
- using System.Linq;
- using System.Collections;
- using System.Collections.Generic;
- using System.Text;
- public class ImageInfo
- {
- public int Left;
- public int Right;
- public SpriteInfo SpriteInfo;
- }
- public class TextPlus : Text
- {
- #region 变量
- public ImagePlus ImagePlus
- {
- get
- {
- if (ImagePlus_ == null)
- {
- ImagePlus_ = GetComponentInChildren<ImagePlus>();
-
- if (ImagePlus_ == null)
- {
- GameObject go = new GameObject("ImagePlus", typeof(ImagePlus));
- RectTransform tra = go.GetComponent<RectTransform>();
- tra.SetParent(rectTransform);
- }
- }
- return ImagePlus_;
- }
- set { ImagePlus_ = value; }
- }
- private ImagePlus ImagePlus_;
- public bool Draw;
- public bool SetY = false;
- public float Y = 0;
- public float LineHeight;
- public float MaxLineHeight = Mathf.Infinity;
- public VertexHelper ToFill;
- public List<int> RemovePos = new List<int>();
- public List<int> ImageIndex = new List<int>();
- public List<int> RemoveIndex = new List<int>();
- public List<int> NewTextIndex = new List<int>();
- public List<Vector3> NewTextPos = new List<Vector3>();
- public List<UIVertex> TextVertex = new List<UIVertex>();
- public List<UIVertex> ImageVertex = new List<UIVertex>();
- #endregion
- protected override void OnPopulateMesh(VertexHelper toFill)
- {
- base.OnPopulateMesh(toFill);
- List<ImageInfo> imageList = GetImageList();
- if (imageList.Count == 0)
- {
- Draw = false;
- }
- else
- {
- Draw = true;
- }
-
- if (Draw)
- {
- Draw = false;
- ToFill = toFill;
- Initialize();
- for (int i = 0; i < imageList.Count; i++)
- {
- for (int j = imageList[i].Left; j <= imageList[i].Right; j++)
- {
- ClearChar(j);
- }
- RemoveChar(imageList[i]);
- CreateImage(imageList[i]);
- }
- for (int i = 0; i < RemovePos.Count; i++)
- {
- NewTextPos.RemoveAt(RemovePos[i] - i);
- }
- for (int i = 0; i < RemoveIndex.Count; i++)
- {
- NewTextIndex.RemoveAt(RemoveIndex[i] - i);
- }
- #region 调试
- //for (int i = 0; i < NewTextPos.Count; i+=6)
- //{
- // Debug.Log(NewTextPos[i] + " " + NewTextPos[i + 1] + " " + NewTextPos[i + 2] + " " + NewTextPos[i + 3] + " " + NewTextPos[i + 4] + " " + NewTextPos[i + 5]);
- //}
- //for (int i = 0; i < NewTextIndex.Count; i++)
- //{
- // Debug.Log(NewTextIndex[i]);
- //}
- //for (int i = 0; i < ImageIndex.Count; i++)
- //{
- // Debug.Log(ImageIndex[i]);
- //}
- #endregion
-
- Retract();
- for (int i = 0; i < ImageIndex.Count; i++)
- {
- UIVertex v0 = ImageVertex[0 + i*4];
- UIVertex v1 = ImageVertex[1 + i*4];
- UIVertex v2 = ImageVertex[2 + i*4];
- UIVertex v3 = ImageVertex[3 + i*4];
- v0.position = NewTextPos[0 + (ImageIndex[i] - i)*6];
- v1.position = NewTextPos[1 + (ImageIndex[i] - i)*6];
- v2.position = NewTextPos[2 + (ImageIndex[i] - i)*6];
- v3.position = NewTextPos[4 + (ImageIndex[i] - i)*6];
- ImageVertex[0 + i*4] = v0;
- ImageVertex[1 + i*4] = v1;
- ImageVertex[2 + i*4] = v2;
- ImageVertex[3 + i*4] = v3;
- NewTextPos.RemoveAt(0 + (ImageIndex[i] - i)*6);
- NewTextPos.RemoveAt(0 + (ImageIndex[i] - i)*6);
- NewTextPos.RemoveAt(0 + (ImageIndex[i] - i)*6);
- NewTextPos.RemoveAt(0 + (ImageIndex[i] - i)*6);
- NewTextPos.RemoveAt(0 + (ImageIndex[i] - i)*6);
- NewTextPos.RemoveAt(0 + (ImageIndex[i] - i)*6);
- NewTextIndex.RemoveAt(ImageIndex[i] - i);
- }
- for (int i = 0; i < NewTextIndex.Count; i++)
- {
- int index0 = 0 + NewTextIndex[i]*6;
- int index1 = 1 + NewTextIndex[i]*6;
- int index2 = 2 + NewTextIndex[i]*6;
- int index3 = 4 + NewTextIndex[i]*6;
- UIVertex v0 = TextVertex[index0];
- UIVertex v1 = TextVertex[index1];
- UIVertex v2 = TextVertex[index2];
- UIVertex v3 = TextVertex[index3];
- v0.position = NewTextPos[0 + i*6];
- v1.position = NewTextPos[1 + i*6];
- v2.position = NewTextPos[2 + i*6];
- v3.position = NewTextPos[4 + i*6];
- toFill.SetUIVertex(v0, 0 + NewTextIndex[i]*4);
- toFill.SetUIVertex(v1, 1 + NewTextIndex[i]*4);
- toFill.SetUIVertex(v2, 2 + NewTextIndex[i]*4);
- toFill.SetUIVertex(v3, 3 + NewTextIndex[i]*4);
- }
- ImagePlus.UpdateStatus(true, new VertexHelper(), ImageVertex);
- }
- else
- {
- ImagePlus.UpdateStatus(false, new VertexHelper(), null);
- }
- }
- protected void Initialize()
- {
- LineHeight = preferredHeight/cachedTextGenerator.lineCount;
- LineHeight = Mathf.Min(LineHeight, MaxLineHeight);
- //Debug.Log(transform.name + " " + LineHeight);
- ImageIndex = new List<int>();
- RemovePos = new List<int>();
- RemoveIndex = new List<int>();
- NewTextIndex = new List<int>();
- NewTextPos = new List<Vector3>();
- ImageVertex = new List<UIVertex>();
-
- ToFill.GetUIVertexStream(TextVertex);
- for (int i = 0; i < text.Length; i++)
- {
- NewTextIndex.Add(i);
- }
- for (int i = 0; i < TextVertex.Count; i++)
- {
- NewTextPos.Add(TextVertex[i].position);
- }
- }
- protected void Move(int index1, int index2, float x, float y)
- {
- Vector3 offset = new Vector3(x, y, 0);
-
- for (int i = index1; i <= index2; i++)
- {
- NewTextPos[0 + i * 6] += offset;
- NewTextPos[1 + i * 6] += offset;
- NewTextPos[2 + i * 6] += offset;
- NewTextPos[3 + i * 6] += offset;
- NewTextPos[4 + i * 6] += offset;
- NewTextPos[5 + i * 6] += offset;
- }
- }
- protected void Retract()
- {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < NewTextIndex.Count; i++)
- {
- sb.Append(text[NewTextIndex[i]]);
- }
- string newText = sb.ToString();
- List<int> endIndex = new List<int>();
- List<int> startIndex = new List<int>();
- List<List<int>> imageGroup = new List<List<int>>();
- imageGroup.Add(new List<int>());
- startIndex.Add(0);
- for (int i = 0; i < newText.Length; i++)
- {
- if (newText[i] == '\n')
- {
- endIndex.Add(i);
- startIndex.Add(i + 1);
- imageGroup.Add(new List<int>());
- }
- else if (newText[i] == '<')
- {
- ImageIndex.Add(i);
- }
- }
- endIndex.Add(-1);
- for (int i = 0; i < ImageIndex.Count; i++)
- {
- bool recycle = false;
- for (int j = 0; j < endIndex.Count; j++)
- {
- if (ImageIndex[i] < endIndex[j])
- {
- imageGroup[j].Add(ImageIndex[i]);
- recycle = true;
- break;
- }
- }
- if (recycle)
- {
- continue;
- }
- imageGroup.Back(0).Add(ImageIndex[i]);
- }
- for (int i = 0; i < imageGroup.Count; i++)
- {
- RetractLine(endIndex[i], imageGroup[i]);
- }
- float offset;
- if (alignment == TextAnchor.LowerCenter || alignment == TextAnchor.MiddleCenter || alignment == TextAnchor.UpperCenter)
- {
- for (int i = 0; i < startIndex.Count; i++)
- {
- if (i == startIndex.Count - 1)
- {
- offset = -GetWidth(startIndex[i], newText.Length - 1)/2;
- offset -= NewTextPos[0 + startIndex[i] * 6].x;
- Move(startIndex[i], newText.Length - 1, offset, 0);
- }
- else
- {
- offset = -GetWidth(startIndex[i], endIndex[i]-1)/2;
-
- offset -= NewTextPos[0 + startIndex[i]*6].x;
- Move(startIndex[i], endIndex[i]-1, offset, 0);
- }
- }
- }
- else if (alignment == TextAnchor.LowerRight || alignment == TextAnchor.MiddleRight || alignment == TextAnchor.UpperRight)
- {
- for (int i = 0; i < startIndex.Count; i++)
- {
- if (i == startIndex.Count - 1)
- {
- offset = cachedTextGenerator.rectExtents.xMax / 2 - NewTextPos[1 + (newText.Length - 1) * 6].x;
- Move(startIndex[i], newText.Length - 1, offset, 0);
- }
- else
- {
- offset = cachedTextGenerator.rectExtents.xMax/2 - NewTextPos[1 + (endIndex[i] - 1)*6].x;
- Move(startIndex[i], endIndex[i] - 1, offset, 0);
- }
- }
- }
- else if (alignment == TextAnchor.LowerLeft || alignment == TextAnchor.MiddleLeft || alignment == TextAnchor.UpperLeft)
- {
- }
- if (alignment == TextAnchor.LowerCenter || alignment == TextAnchor.LowerLeft || alignment == TextAnchor.LowerRight)
- {
-
- }
- else if (alignment == TextAnchor.MiddleCenter || alignment == TextAnchor.MiddleLeft || alignment == TextAnchor.MiddleRight)
- {
-
- }
- else if (alignment == TextAnchor.UpperCenter || alignment == TextAnchor.UpperLeft || alignment == TextAnchor.UpperRight)
- {
-
- }
- }
- protected void RetractLine(int endIndex, List<int> imageIndex)
- {
- if (imageIndex.Count == 0)
- {
- return;
- }
- int rear;
- int front;
- if (imageIndex.Count == 1)
- {
- rear = endIndex - 1;
- front = imageIndex[0] + 1;
-
- if (endIndex == -1)
- {
- rear = NewTextIndex.Count - 1;
- }
- if (rear < front)
- {
- return;
- }
-
- Move(front, rear, -GetSpan(imageIndex[0], front), 0);
- }
- else
- {
- for (int i = 0; i < imageIndex.Count; i++)
- {
- if (endIndex == -1)
- {
- rear = NewTextIndex.Count - 1;
- }
- else
- {
- rear = endIndex - 1;
- }
- front = imageIndex.Back(i) + 1;
-
- if (rear < front)
- {
- continue;
- }
-
- Move(front, rear, -GetSpan(imageIndex.Back(i), front), 0);
- }
- }
- }
- protected void ClearChar(int index)
- {
- UIVertex v0 = TextVertex[0 + index*6];
- UIVertex v1 = TextVertex[1 + index*6];
- UIVertex v2 = TextVertex[2 + index*6];
- UIVertex v3 = TextVertex[4 + index*6];
- v0.uv0 = new Vector2();
- v1.uv0 = new Vector2();
- v2.uv0 = new Vector2();
- v3.uv0 = new Vector2();
- ToFill.SetUIVertex(v0, 0 + index * 4);
- ToFill.SetUIVertex(v1, 1 + index * 4);
- ToFill.SetUIVertex(v2, 2 + index * 4);
- ToFill.SetUIVertex(v3, 3 + index * 4);
- }
- protected void RemoveChar(ImageInfo imageInfo)
- {
- for (int i = imageInfo.Left + 1; i <= imageInfo.Right; i++)
- {
- RemoveIndex.Add(i);
- RemovePos.Add(0 + i*6);
- RemovePos.Add(1 + i*6);
- RemovePos.Add(2 + i*6);
- RemovePos.Add(3 + i*6);
- RemovePos.Add(4 + i*6);
- RemovePos.Add(5 + i*6);
- }
- }
- protected void CreateImage(ImageInfo imageInfo)
- {
- float height = LineHeight;
- float width = (height / imageInfo.SpriteInfo.Height) * imageInfo.SpriteInfo.Width;
- bool first = false;
- if (imageInfo.Left == 0)
- {
- first = true;
- }
- else if (!SameLine(imageInfo.Left-1, imageInfo.Left))
- {
- first = true;
- }
-
- UIVertex v0 = new UIVertex();
- UIVertex v1 = new UIVertex();
- UIVertex v2 = new UIVertex();
- UIVertex v3 = new UIVertex();
- v0.color = Color.white;
- v1.color = Color.white;
- v2.color = Color.white;
- v3.color = Color.white;
- v0.uv0 = imageInfo.SpriteInfo.UvList[0];
- v1.uv0 = imageInfo.SpriteInfo.UvList[1];
- v2.uv0 = imageInfo.SpriteInfo.UvList[2];
- v3.uv0 = imageInfo.SpriteInfo.UvList[3];
- if (first)
- {
- Vector3 middleLeft = (TextVertex[0 + imageInfo.Left*6].position + TextVertex[4 + imageInfo.Left*6].position)/2;
- v0.position = middleLeft + new Vector3(0, height/2);
- v1.position = middleLeft + new Vector3(width, height / 2);
- v2.position = middleLeft + new Vector3(width, -height / 2);
- v3.position = middleLeft + new Vector3(0, -height / 2);
- ImageVertex.Add(v0);
- ImageVertex.Add(v1);
- ImageVertex.Add(v2);
- ImageVertex.Add(v3);
- }
- else
- {
- Vector3 middleRight = (TextVertex[1 + (imageInfo.Left - 1) * 6].position + TextVertex[2 + (imageInfo.Left - 1) * 6].position) / 2;
- if (SetY)
- {
- middleRight.y = Y;
- }
- v0.position = middleRight + new Vector3(0, height / 2);
- v1.position = middleRight + new Vector3(width, height / 2);
- v2.position = middleRight + new Vector3(width, -height / 2);
- v3.position = middleRight + new Vector3(0, -height / 2);
- ImageVertex.Add(v0);
- ImageVertex.Add(v1);
- ImageVertex.Add(v2);
- ImageVertex.Add(v3);
- }
- NewTextPos[0 + imageInfo.Left*6] = v0.position;
- NewTextPos[1 + imageInfo.Left*6] = v1.position;
- NewTextPos[2 + imageInfo.Left*6] = v2.position;
- NewTextPos[3 + imageInfo.Left*6] = v2.position;
- NewTextPos[4 + imageInfo.Left*6] = v3.position;
- NewTextPos[5 + imageInfo.Left*6] = v0.position;
- }
- protected bool SameLine(int index1, int index2)
- {
- //if (text[index1] == '\n' || text[index2] == '\n')
- //{
- // return false;
- //}
- if (Mathf.Abs(GetCenter(index1).y - GetCenter(index2).y) < LineHeight/4)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- protected float GetSpan(int index1, int index2)
- {
- return (NewTextPos[0 + index2*6].x - NewTextPos[1 + index1*6].x);
- }
- protected float GetWidth(int index1, int index2)
- {
- return (NewTextPos[1 + index2 * 6].x - NewTextPos[0 + index1 * 6].x);
- }
- protected float GetHeight(int index1, int index2)
- {
- return (NewTextPos[0 + index1 * 6].y - NewTextPos[2 + index2 * 6].y);
- }
- protected Vector3 GetCenter(int index)
- {
- return (TextVertex[0 + index*6].position + TextVertex[3 + index*6].position)/2;
- }
- protected List<ImageInfo> GetImageList()
- {
- List<ImageInfo> imageList = new List<ImageInfo>();
- ImageInfo imageInfo = new ImageInfo();
- for (int i = 0; i < text.Length; i++)
- {
- if (text[i] == '<')
- {
- if (i + 1 != text.Length)
- {
- if (text[i + 1] == '(')
- {
- imageInfo = new ImageInfo();
- imageInfo.Left = i;
- }
- }
- }
- else if (text[i] == ')')
- {
- if (i + 1 != text.Length)
- {
- if (text[i + 1] == '>')
- {
- imageInfo.Right = i + 1;
- string imageName = text.Between(imageInfo.Left + 2, imageInfo.Right - 2);
- if (SpriteAsset.SpriteInfoDic.TryGetValue(imageName, out imageInfo.SpriteInfo))
- {
- imageList.Add(imageInfo);
- }
- }
- }
- }
- }
- return imageList;
- }
- }
|