819 lines
28 KiB
C#
819 lines
28 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
using System.Text.RegularExpressions;
|
||
using System.Text;
|
||
using UnityEngine.EventSystems;
|
||
using System;
|
||
|
||
namespace BF
|
||
{
|
||
public class InlineText : Text, IPointerClickHandler
|
||
{
|
||
#region 属性
|
||
// 用正则取 [*#emoji*_*#] *值为0 ,表示为超链接 没有值则为表情
|
||
private static readonly Regex inputTagRegex = new Regex(@"\[(\d{0,})#emoji(\d{1,})_(\d{1,})#\]", RegexOptions.Singleline);
|
||
//记录表情匹配信息
|
||
private List<EmojiInfo> emojiInfos = new List<EmojiInfo>();
|
||
//计算定点信息的缓存数组
|
||
private readonly UIVertex[] m_TempVerts = new UIVertex[4];
|
||
//stringbuilder
|
||
private StringBuilder textBuilder = new StringBuilder();
|
||
//tmp uivertext
|
||
UIVertex _tempVertex = UIVertex.simpleVert;
|
||
//tmp isvisible
|
||
private bool isVisible = false;
|
||
//tmp vector3
|
||
private Vector3 tmpVector3 = Vector3.zero;
|
||
//offset
|
||
private Vector3 offset = Vector3.zero;
|
||
//表情大小
|
||
private float emojiSize;
|
||
|
||
//自定义表情绘制
|
||
private EmojiGraphic emojiGraphic;
|
||
//luaGetEmojiUVs
|
||
private Func<int, int, List<float>> luaGetEmojiUVs;
|
||
|
||
#if !UNITY_2018_4_23
|
||
//lua获取顶点计算需要屏蔽的符号
|
||
private Func<List<string>> luaGetNotCalVertice;
|
||
//符号缓存
|
||
private List<string> notCalVertice = new List<string>();
|
||
#endif
|
||
private Func<Texture2D> luaSetMainTexture;
|
||
|
||
#region 超链接
|
||
|
||
//点击事件监听
|
||
public BFEvent<string, int> OnHrefClick = new BFEvent<string, int>();
|
||
// 超链接信息列表
|
||
private readonly List<HrefInfo> hrefInfos = new List<HrefInfo>();
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
|
||
#region 重写函数
|
||
[TextArea(3, 10)]
|
||
[SerializeField]
|
||
protected string _text = string.Empty;
|
||
|
||
public override string text
|
||
{
|
||
get
|
||
{
|
||
return m_Text;
|
||
}
|
||
set
|
||
{
|
||
if (String.IsNullOrEmpty(value))
|
||
{
|
||
m_Text = "";
|
||
m_Text = GetOutputText(value);
|
||
SetVerticesDirty();
|
||
SetLayoutDirty();
|
||
}
|
||
else if (_text != value)
|
||
{
|
||
m_Text = GetOutputText(value);
|
||
SetVerticesDirty();
|
||
SetLayoutDirty();
|
||
}
|
||
#if UNITY_EDITOR
|
||
//编辑器赋值 如果是一样的 也可以刷新一下
|
||
else
|
||
{
|
||
m_Text = GetOutputText(value);
|
||
SetVerticesDirty();
|
||
SetLayoutDirty();
|
||
}
|
||
#endif
|
||
//输入字符备份
|
||
_text = value;
|
||
}
|
||
}
|
||
|
||
protected override void OnEnable()
|
||
{
|
||
base.OnEnable();
|
||
supportRichText = true;
|
||
alignByGeometry = false;
|
||
//alignByGeometry = false;
|
||
isVisible = true;
|
||
|
||
if (Application.isPlaying)
|
||
{
|
||
BFMain.Instance.OneShotManager.AddOneShot(UpdateDrawSprite);
|
||
}
|
||
}
|
||
|
||
protected override void OnDisable()
|
||
{
|
||
base.OnDisable();
|
||
isVisible = false;
|
||
|
||
if (Application.isPlaying)
|
||
{
|
||
BFMain.Instance.OneShotManager.AddOneShot(UpdateDrawSprite);
|
||
}
|
||
}
|
||
|
||
protected override void Awake()
|
||
{
|
||
base.Start();
|
||
|
||
if (!Application.isPlaying)
|
||
{
|
||
return;
|
||
}
|
||
|
||
emojiSize = fontSize;
|
||
var gameObj = new GameObject();
|
||
gameObj.transform.SetParent(transform);
|
||
gameObj.transform.localPosition = Vector3.zero;
|
||
gameObj.transform.localScale = Vector3.one;
|
||
emojiGraphic = gameObj.AddComponent<EmojiGraphic>();
|
||
var rectTran = emojiGraphic.rectTransform;
|
||
rectTran.anchorMin = Vector2.zero;
|
||
rectTran.anchorMax = Vector2.one;
|
||
rectTran.sizeDelta = Vector2.zero;
|
||
rectTran.pivot = rectTransform.pivot;
|
||
}
|
||
|
||
protected override void OnRectTransformDimensionsChange()
|
||
{
|
||
if (emojiGraphic != null)
|
||
{
|
||
emojiGraphic.rectTransform.pivot = rectTransform.pivot;
|
||
}
|
||
base.OnRectTransformDimensionsChange();
|
||
}
|
||
|
||
protected override void Start()
|
||
{
|
||
//base.Start();
|
||
|
||
if (!Application.isPlaying)
|
||
{
|
||
return;
|
||
}
|
||
|
||
|
||
m_Text = GetOutputText(_text);
|
||
SetVerticesDirty();
|
||
SetLayoutDirty();
|
||
}
|
||
|
||
protected override void OnPopulateMesh(VertexHelper toFill)
|
||
{
|
||
if (font == null)
|
||
return;
|
||
base.OnPopulateMesh(toFill);
|
||
|
||
m_DisableFontTextureRebuiltCallback = true;
|
||
//更新顶点位置&去掉乱码uv
|
||
DealSpriteTagInfo(toFill);
|
||
//处理超链接的信息
|
||
DealHrefInfo(toFill);
|
||
m_DisableFontTextureRebuiltCallback = false;
|
||
|
||
isVisible = true;
|
||
BFMain.Instance.OneShotManager.AddOneShot(UpdateDrawSprite);
|
||
}
|
||
|
||
|
||
// 重写文本所占的长宽
|
||
//文本的宽度计算好像有bug,超过sizeDelta就取sizeDelta
|
||
|
||
public override float preferredWidth
|
||
{
|
||
get
|
||
{
|
||
var settings = GetGenerationSettings(Vector2.zero);
|
||
float width = cachedTextGeneratorForLayout.GetPreferredWidth(m_Text, settings) / pixelsPerUnit;
|
||
|
||
|
||
|
||
//Debug.LogWarning("width " + width);
|
||
//return width;
|
||
return width < rectTransform.sizeDelta.x || horizontalOverflow == HorizontalWrapMode.Overflow ? width : rectTransform.sizeDelta.x;
|
||
}
|
||
}
|
||
|
||
public override float preferredHeight
|
||
{
|
||
get
|
||
{
|
||
var settings = GetGenerationSettings(new Vector2(rectTransform.rect.size.x, 0.0f));
|
||
float height = cachedTextGeneratorForLayout.GetPreferredHeight(m_Text, settings) / pixelsPerUnit;
|
||
//Debug.LogWarning("height " + height);
|
||
return height;
|
||
//return height < rectTransform.sizeDelta.y || verticalOverflow == VerticalWrapMode.Overflow ? height : rectTransform.sizeDelta.y;
|
||
}
|
||
}
|
||
|
||
protected override void OnDestroy()
|
||
{
|
||
base.OnDestroy();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 事件回调
|
||
//响应点击事件-->检测是否在超链接的范围内
|
||
public void OnPointerClick(PointerEventData eventData)
|
||
{
|
||
Vector2 lp;
|
||
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
||
rectTransform, eventData.position, eventData.pressEventCamera, out lp);
|
||
|
||
foreach (var hrefInfo in hrefInfos)
|
||
{
|
||
var boxes = hrefInfo.Boxes;
|
||
for (var i = 0; i < boxes.Count; ++i)
|
||
{
|
||
if (boxes[i].Contains(lp))
|
||
{
|
||
Debug.LogWarningFormat("点击超链接 id {0}", hrefInfo.Id);
|
||
OnHrefClick.Invoke(hrefInfo.HrefValue, hrefInfo.Id);
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
#region 内部函数
|
||
|
||
public int GetTrueLength()
|
||
{
|
||
var countDown = 0;
|
||
foreach (var emojiInfo in emojiInfos)
|
||
{
|
||
countDown += emojiInfo.Length - 1;
|
||
}
|
||
|
||
return _text.Length - countDown;
|
||
}
|
||
|
||
public void SetEmojiSize(int size)
|
||
{
|
||
emojiSize = size;
|
||
}
|
||
|
||
public string FilterStr(int length)
|
||
{
|
||
if (length >= _text.Length)
|
||
{
|
||
return _text;
|
||
}
|
||
|
||
EmojiInfo tmp = new EmojiInfo();
|
||
var countDown = 0;
|
||
var emojiCount = 0;
|
||
|
||
foreach (var emojiInfo in emojiInfos)
|
||
{
|
||
if (emojiInfo.StartStrIndex <= length)
|
||
{
|
||
//取出最后一个emojiInfo
|
||
countDown += emojiInfo.Length - 1;
|
||
tmp = emojiInfo;
|
||
emojiCount++;
|
||
}
|
||
}
|
||
|
||
var str = "";
|
||
|
||
if (tmp.Length != 0)
|
||
{
|
||
var end = tmp.StartStrIndex + countDown;
|
||
str = _text.Substring(0, end);
|
||
if (tmp.StartStrIndex < length && _text.Length - end > 0)
|
||
{
|
||
str += _text.Substring(end, Mathf.Min(length - tmp.StartStrIndex,_text.Length - end));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
str = _text.Substring(0, length);
|
||
}
|
||
|
||
if (_text.Length - countDown > length)
|
||
{
|
||
str += "...";
|
||
}
|
||
|
||
return str;
|
||
}
|
||
|
||
public bool IsOnlyEmoji()
|
||
{
|
||
var total = emojiInfos.Count;
|
||
var length = 0;
|
||
if (total <= 0)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
emojiInfos.Sort((x, y) =>
|
||
{
|
||
return x.StartStrIndex.CompareTo(y.StartStrIndex);
|
||
});
|
||
|
||
for (var i = 0; i < total - 1; i++)
|
||
{
|
||
if (emojiInfos[i].StartStrIndex + 1 != emojiInfos[i + 1].StartStrIndex)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
length += emojiInfos[i].Length;
|
||
}
|
||
|
||
if (length + emojiInfos[total - 1].Length != _text.Length)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
#if !UNITY_2018_4_23
|
||
public List<string> GetTranslateStr(out string format)
|
||
{
|
||
var sb = new StringBuilder();
|
||
var list = new List<string>();
|
||
var lastIndex = 0;
|
||
var endIndex = 0;
|
||
|
||
if (emojiInfos.Count == 0)
|
||
{
|
||
list.Add(_text);
|
||
format = "#&&&#";
|
||
}
|
||
else
|
||
{
|
||
foreach (var emojiInfo in emojiInfos)
|
||
{
|
||
if (lastIndex < emojiInfo.StartTrueStrIndex)
|
||
{
|
||
|
||
list.Add(_text.Substring(lastIndex, emojiInfo.StartTrueStrIndex - lastIndex));
|
||
sb.Append("#&&&#");
|
||
sb.Append(_text.Substring(emojiInfo.StartTrueStrIndex, emojiInfo.Length));
|
||
lastIndex = emojiInfo.StartTrueStrIndex + emojiInfo.Length;
|
||
}
|
||
else if (lastIndex == emojiInfo.StartTrueStrIndex)
|
||
{
|
||
sb.Append(_text.Substring(emojiInfo.StartTrueStrIndex, emojiInfo.Length));
|
||
lastIndex = emojiInfo.StartTrueStrIndex + emojiInfo.Length;
|
||
}
|
||
|
||
endIndex = emojiInfo.StartTrueStrIndex + emojiInfo.Length;
|
||
}
|
||
|
||
if (endIndex < _text.Length)
|
||
{
|
||
var tmp = _text.Substring(endIndex, _text.Length - endIndex);
|
||
sb.Append("#&&&#");
|
||
list.Add(tmp);
|
||
}
|
||
format = sb.ToString();
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
#endif
|
||
public void AddLuaGetEmojiUVs(Func<int, int, List<float>> callback)
|
||
{
|
||
luaGetEmojiUVs = callback;
|
||
}
|
||
|
||
public void AddLuaSetMainTexture(Func<Texture2D> callback)
|
||
{
|
||
luaSetMainTexture = callback;
|
||
}
|
||
|
||
#if !UNITY_2018_4_23
|
||
public void AddLuaGetNotCalVerticeStr(Func<List<string>> callback)
|
||
{
|
||
luaGetNotCalVertice = callback;
|
||
}
|
||
#endif
|
||
|
||
public void SetMainTexture(Texture2D texture)
|
||
{
|
||
if (emojiGraphic)
|
||
{
|
||
emojiGraphic.MainTexture = texture;
|
||
}
|
||
}
|
||
|
||
//根据正则规则更新文本
|
||
private string GetOutputText(string inputText)
|
||
{
|
||
//回收表情对象和超链接对象
|
||
ReleaseEmojiInfo();
|
||
ReleaseHrefInfos();
|
||
|
||
if (string.IsNullOrEmpty(inputText))
|
||
return "";
|
||
|
||
textBuilder.Clear();
|
||
var textIndex = 0;
|
||
var emojiTpye = 0;
|
||
var emojiIndex = 0;
|
||
#if !UNITY_2018_4_23
|
||
var richTextLength = 0;
|
||
var notCalVerticeLength = 0;
|
||
if (notCalVertice.Count <= 0)
|
||
{
|
||
notCalVertice = luaGetNotCalVertice();
|
||
}
|
||
#endif
|
||
var startStrIndexOffset = 0;
|
||
|
||
foreach (Match match in inputTagRegex.Matches(inputText))
|
||
{
|
||
int tempId = -1;
|
||
if (!string.IsNullOrEmpty(match.Groups[1].Value) && !match.Groups[1].Value.Equals("-"))
|
||
tempId = int.Parse(match.Groups[1].Value);
|
||
|
||
var fronStr = inputText.Substring(textIndex, match.Index - textIndex);
|
||
#if !UNITY_2018_4_23
|
||
//先加入之前的匹配位置字符串
|
||
foreach (var str in notCalVertice)
|
||
{
|
||
|
||
var m = Regex.Matches(fronStr, str);
|
||
foreach (Match _match in m)
|
||
{
|
||
notCalVerticeLength += _match.Groups[0].Value.Length;
|
||
}
|
||
}
|
||
#endif
|
||
textBuilder.Append(fronStr);
|
||
|
||
//更新超链接
|
||
if (tempId == 0)
|
||
{
|
||
textBuilder.Append("<color=blue>");
|
||
int startIndex = textBuilder.Length * 4;
|
||
textBuilder.Append("[" + match.Groups[2].Value + "]");
|
||
int endIndex = textBuilder.Length * 4 - 1;
|
||
textBuilder.Append("</color>");
|
||
|
||
|
||
var hrefInfo = BFMain.Instance.PoolMgr.GetClassPool<HrefInfo>().Get();
|
||
hrefInfo.Id = Mathf.Abs(tempId);
|
||
hrefInfo.StartIndex = startIndex;// 超链接里的文本起始顶点索引
|
||
hrefInfo.EndIndex = endIndex;
|
||
hrefInfo.Name = match.Groups[2].Value;
|
||
hrefInfo.HrefValue = match.Groups[3].Value;
|
||
hrefInfos.Add(hrefInfo);
|
||
}
|
||
//更新表情
|
||
else
|
||
{
|
||
//先判断是否有这个图
|
||
emojiTpye = int.Parse(match.Groups[2].Value);
|
||
emojiIndex = int.Parse(match.Groups[3].Value);
|
||
|
||
var info = luaGetEmojiUVs?.Invoke(emojiTpye, emojiIndex);
|
||
if (info != null)
|
||
{
|
||
EmojiInfo emojiInfo = BFMain.Instance.PoolMgr.GetClassPool<EmojiInfo>().Get();
|
||
|
||
#if !UNITY_2018_4_23
|
||
emojiInfo.StartTrueStrIndex = match.Index;
|
||
#endif
|
||
//获取uv
|
||
for (var i = 0; i < 4; i++)
|
||
{
|
||
var index = i * 2;
|
||
emojiInfo.UVs[i] = new Vector2(info[index], info[index + 1]);
|
||
}
|
||
|
||
//设置乱码开始index
|
||
#if !UNITY_2018_4_23
|
||
var tempIndex = (textBuilder.Length - richTextLength - notCalVerticeLength) * 4;
|
||
emojiInfo.StartIndex = tempIndex;
|
||
emojiInfo.StartStrIndex = textBuilder.Length - startStrIndexOffset + 1;
|
||
|
||
var str = @"<quad size=" + emojiSize + " width=" + 1 + " />";
|
||
richTextLength = richTextLength + str.Length - 1;
|
||
#else
|
||
var tempIndex = textBuilder.Length * 4;
|
||
emojiInfo.StartIndex = tempIndex;
|
||
emojiInfo.StartStrIndex = textBuilder.Length - startStrIndexOffset + 1;
|
||
|
||
var str = @"<quad size=" + emojiSize + " width=" + 1 + " />";
|
||
#endif
|
||
textBuilder.Append(str);
|
||
startStrIndexOffset += str.Length - 1;
|
||
emojiInfo.Length = match.Groups[0].Value.Length;
|
||
emojiInfos.Add(emojiInfo);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("没有图片");
|
||
textBuilder.Append(match.Groups[0].Value);
|
||
textIndex = match.Index + match.Length;
|
||
continue;
|
||
}
|
||
}
|
||
textIndex = match.Index + match.Length;
|
||
}
|
||
|
||
textBuilder.Append(inputText.Substring(textIndex, inputText.Length - textIndex));
|
||
|
||
return textBuilder.ToString();
|
||
}
|
||
//处理表情信息 设置顶点信息
|
||
private void DealSpriteTagInfo(VertexHelper toFill)
|
||
{
|
||
int index = -1;
|
||
//emoji
|
||
for (int i = 0; i < emojiInfos.Count; i++)
|
||
{
|
||
index = emojiInfos[i].StartIndex;
|
||
#if !UNITY_2018_4_23
|
||
if ((index + 4) <= toFill.currentVertCount)
|
||
#else
|
||
if ((index + 4) < toFill.currentVertCount)
|
||
#endif
|
||
{
|
||
for (int j = index; j < index + 4; j++)
|
||
{
|
||
toFill.PopulateUIVertex(ref _tempVertex, j);
|
||
//清理多余的乱码uv
|
||
_tempVertex.uv0 = Vector2.zero;
|
||
|
||
toFill.SetUIVertex(_tempVertex, j);
|
||
//获取quad的位置 --> 转为世界坐标
|
||
//emojiInfos[i].Corner[j - index] = Utils.TransformPoint2World(transform, _tempVertex.position);
|
||
emojiInfos[i].Corner[j - index] = _tempVertex.position;
|
||
|
||
}
|
||
}
|
||
}
|
||
}
|
||
//处理超链接的信息
|
||
private void DealHrefInfo(VertexHelper toFill)
|
||
{
|
||
if (hrefInfos.Count > 0)
|
||
{
|
||
// 处理超链接包围框
|
||
for (int i = 0; i < hrefInfos.Count; i++)
|
||
{
|
||
hrefInfos[i].Boxes.Clear();
|
||
if (hrefInfos[i].StartIndex >= toFill.currentVertCount)
|
||
continue;
|
||
|
||
toFill.PopulateUIVertex(ref _tempVertex, hrefInfos[i].StartIndex);
|
||
// 将超链接里面的文本顶点索引坐标加入到包围框
|
||
var pos = _tempVertex.position;
|
||
var bounds = new Bounds(pos, Vector3.zero);
|
||
for (int j = hrefInfos[i].StartIndex + 1; j < hrefInfos[i].EndIndex; j++)
|
||
{
|
||
if (j >= toFill.currentVertCount)
|
||
{
|
||
break;
|
||
}
|
||
toFill.PopulateUIVertex(ref _tempVertex, j);
|
||
pos = _tempVertex.position;
|
||
if (pos.x < bounds.min.x)
|
||
{
|
||
// 换行重新添加包围框
|
||
hrefInfos[i].Boxes.Add(new Rect(bounds.min, bounds.size));
|
||
bounds = new Bounds(pos, Vector3.zero);
|
||
}
|
||
else
|
||
{
|
||
bounds.Encapsulate(pos); // 扩展包围框
|
||
}
|
||
}
|
||
//添加包围盒
|
||
hrefInfos[i].Boxes.Add(new Rect(bounds.min, bounds.size));
|
||
}
|
||
|
||
//添加下划线
|
||
Vector2 extents = rectTransform.rect.size;
|
||
var settings = GetGenerationSettings(extents);
|
||
TextGenerator underlineText = BFMain.Instance.PoolMgr.GetClassPool<TextGenerator>().Get();
|
||
underlineText.Populate("_", settings);
|
||
IList<UIVertex> tut = underlineText.verts;
|
||
for (int m = 0; m < hrefInfos.Count; m++)
|
||
{
|
||
for (int i = 0; i < hrefInfos[m].Boxes.Count; i++)
|
||
{
|
||
//计算下划线的位置
|
||
Vector3[] ulPos = new Vector3[4];
|
||
ulPos[0] = hrefInfos[m].Boxes[i].position + new Vector2(0.0f, fontSize * 0.2f);
|
||
ulPos[1] = ulPos[0] + new Vector3(hrefInfos[m].Boxes[i].width, 0.0f);
|
||
ulPos[2] = hrefInfos[m].Boxes[i].position + new Vector2(hrefInfos[m].Boxes[i].width, 0.0f);
|
||
ulPos[3] = hrefInfos[m].Boxes[i].position;
|
||
//绘制下划线
|
||
for (int j = 0; j < 4; j++)
|
||
{
|
||
m_TempVerts[j] = tut[j];
|
||
m_TempVerts[j].color = Color.blue;
|
||
m_TempVerts[j].position = ulPos[j];
|
||
if (j == 3)
|
||
toFill.AddUIVertexQuad(m_TempVerts);
|
||
}
|
||
}
|
||
}
|
||
//回收下划线的对象
|
||
BFMain.Instance.PoolMgr.GetClassPool<TextGenerator>().Release(underlineText);
|
||
}
|
||
|
||
}
|
||
//表情绘制
|
||
private void UpdateDrawSprite()
|
||
{
|
||
if (this == null || emojiGraphic == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (emojiGraphic.MainTexture == null)
|
||
{
|
||
emojiGraphic.MainTexture = luaSetMainTexture?.Invoke();
|
||
}
|
||
|
||
if (emojiGraphic.MainTexture != null)
|
||
{
|
||
emojiGraphic.SetMeshInfos(emojiInfos);
|
||
}
|
||
}
|
||
|
||
//回收EmojiInfo
|
||
private void ReleaseEmojiInfo()
|
||
{
|
||
//记录之前的信息
|
||
for (var i = 0; i < emojiInfos.Count; i++)
|
||
{
|
||
//回收信息到对象池
|
||
BFMain.Instance.PoolMgr.GetClassPool<EmojiInfo>().Release(emojiInfos[i]);
|
||
}
|
||
emojiInfos.Clear();
|
||
}
|
||
|
||
//回收超链接的信息
|
||
private void ReleaseHrefInfos()
|
||
{
|
||
for (var i = 0; i < hrefInfos.Count; i++)
|
||
{
|
||
BFMain.Instance.PoolMgr.GetClassPool<HrefInfo>().Release(hrefInfos[i]);
|
||
}
|
||
hrefInfos.Clear();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region UNITY_EDITOR
|
||
#if UNITY_EDITOR
|
||
// protected override void OnValidate()
|
||
// {
|
||
// base.OnValidate();
|
||
// m_Text = GetOutputText(_text);
|
||
// SetVerticesDirty();
|
||
// SetLayoutDirty();
|
||
// }
|
||
|
||
//辅助线框
|
||
Vector3[] _textWolrdVertexs = new Vector3[4];
|
||
private void OnDrawGizmos()
|
||
{
|
||
//text
|
||
rectTransform.GetWorldCorners(_textWolrdVertexs);
|
||
GizmosDrawLine(Color.white, _textWolrdVertexs);
|
||
|
||
//preferred size
|
||
Vector2 pivot = GetTextAnchorPivot(alignment);
|
||
Rect rect = new Rect();
|
||
Vector2 size = rectTransform.sizeDelta - new Vector2(preferredWidth, preferredHeight);
|
||
rect.position = new Vector2(pivot.x * size.x, pivot.y * size.y) - new Vector2(rectTransform.sizeDelta.x * rectTransform.pivot.x, rectTransform.sizeDelta.y * rectTransform.pivot.y);
|
||
rect.width = preferredWidth;
|
||
rect.height = preferredHeight;
|
||
_textWolrdVertexs[0] = Utils.TransformPoint2World(transform, new Vector3(rect.x, rect.y));
|
||
_textWolrdVertexs[1] = Utils.TransformPoint2World(transform, new Vector3(rect.x + rect.width, rect.y));
|
||
_textWolrdVertexs[2] = Utils.TransformPoint2World(transform, new Vector3(rect.x + rect.width, rect.y + rect.height));
|
||
_textWolrdVertexs[3] = Utils.TransformPoint2World(transform, new Vector3(rect.x, rect.y + rect.height));
|
||
GizmosDrawLine(Color.blue, _textWolrdVertexs);
|
||
|
||
//href
|
||
for (int i = 0; i < hrefInfos.Count; i++)
|
||
{
|
||
for (int j = 0; j < hrefInfos[i].Boxes.Count; j++)
|
||
{
|
||
rect = hrefInfos[i].Boxes[j];
|
||
_textWolrdVertexs[0] = Utils.TransformPoint2World(transform, rect.position);
|
||
_textWolrdVertexs[1] = Utils.TransformPoint2World(transform, new Vector3(rect.x + rect.width, rect.y));
|
||
_textWolrdVertexs[2] = Utils.TransformPoint2World(transform, new Vector3(rect.x + rect.width, rect.y + rect.height));
|
||
_textWolrdVertexs[3] = Utils.TransformPoint2World(transform, new Vector3(rect.x, rect.y + rect.height));
|
||
|
||
GizmosDrawLine(Color.green, _textWolrdVertexs);
|
||
}
|
||
}
|
||
|
||
//sprite
|
||
for (int i = 0; i < emojiInfos.Count; i++)
|
||
{
|
||
GizmosDrawLine(Color.yellow, emojiInfos[i].Corner);
|
||
}
|
||
}
|
||
//划线
|
||
private void GizmosDrawLine(Color color, Vector3[] pos)
|
||
{
|
||
Gizmos.color = color;
|
||
|
||
Gizmos.DrawLine(Utils.TransformPoint2World(transform, pos[0]), Utils.TransformPoint2World(transform, pos[1]));
|
||
Gizmos.DrawLine(Utils.TransformPoint2World(transform, pos[1]), Utils.TransformPoint2World(transform, pos[2]));
|
||
Gizmos.DrawLine(Utils.TransformPoint2World(transform, pos[2]), Utils.TransformPoint2World(transform, pos[3]));
|
||
Gizmos.DrawLine(Utils.TransformPoint2World(transform, pos[3]), Utils.TransformPoint2World(transform, pos[0]));
|
||
}
|
||
#endif
|
||
#endregion
|
||
}
|
||
|
||
#region Struct
|
||
/// <summary>
|
||
/// 表情的信息
|
||
/// </summary>
|
||
public class EmojiInfo
|
||
{
|
||
/// <summary>
|
||
/// 顶点索引id
|
||
/// </summary>
|
||
public int StartIndex;
|
||
/// <summary>
|
||
/// 开始自定义自负索引
|
||
/// </summary>
|
||
public int StartStrIndex;
|
||
/// <summary>
|
||
/// 所占字符数量
|
||
/// </summary>
|
||
public int Length;
|
||
/// <summary>
|
||
/// 表情corner
|
||
/// </summary>
|
||
public Vector3[] Corner;
|
||
/// <summary>
|
||
/// 表情uv
|
||
/// </summary>
|
||
public Vector2[] UVs;
|
||
|
||
#if !UNITY_2018_4_23
|
||
/// <summary>
|
||
/// 字符串开始真实索引
|
||
/// </summary>
|
||
public int StartTrueStrIndex;
|
||
#endif
|
||
|
||
public EmojiInfo()
|
||
{
|
||
Corner = new Vector3[4];
|
||
UVs = new Vector2[4];
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 超链接信息类
|
||
/// </summary>
|
||
public class HrefInfo
|
||
{
|
||
/// <summary>
|
||
/// 超链接id
|
||
/// </summary>
|
||
public int Id;
|
||
/// <summary>
|
||
/// 顶点开始索引值
|
||
/// </summary>
|
||
public int StartIndex;
|
||
/// <summary>
|
||
/// 顶点结束索引值
|
||
/// </summary>
|
||
public int EndIndex;
|
||
/// <summary>
|
||
/// 名称
|
||
/// </summary>
|
||
public string Name;
|
||
/// <summary>
|
||
/// 超链接的值
|
||
/// </summary>
|
||
public string HrefValue;
|
||
/// <summary>
|
||
/// 碰撞盒范围
|
||
/// </summary>
|
||
public readonly List<Rect> Boxes = new List<Rect>();
|
||
}
|
||
#endregion
|
||
|
||
}
|