图文混排更新到超链接这儿,好像也差不多了,不过就在最后一点,博主也表现得相当不专业,直接整合了山中双木林同学提供的超链接的解决方案,博主甚至没来得及细看就直接复制了,但感觉还是挺好用的。
博主已经将超链接的功能直接整合到了之前的InlineText和InlineSpriteText的两个脚本中
1.定义超链接的正则表达式和事件监听
#region 超链接 /// <summary> /// 超链接信息列表 /// </summary> private readonly List<HrefInfo> m_HrefInfos = new List<HrefInfo>(); /// <summary> /// 文本构造器 /// </summary> private static readonly StringBuilder s_TextBuilder = new StringBuilder(); /// <summary> /// 超链接正则 /// </summary> private static readonly Regex s_HrefRegex = new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline); [System.Serializable] public class HrefClickEvent : UnityEvent<string> { } [SerializeField] private HrefClickEvent m_OnHrefClick = new HrefClickEvent(); /// <summary> /// 超链接点击事件 /// </summary> public HrefClickEvent onHrefClick { get { return m_OnHrefClick; } set { m_OnHrefClick = value; } } /// <summary> /// 获取超链接解析后的最后输出文本 /// </summary> /// <returns></returns> protected string GetOutputText() { s_TextBuilder.Length = 0; m_HrefInfos.Clear(); var indexText = 0; foreach (Match match in s_HrefRegex.Matches(text)) { s_TextBuilder.Append(text.Substring(indexText, match.Index - indexText)); s_TextBuilder.Append("<color=blue>"); // 超链接颜色 var group = match.Groups[1]; var hrefInfo = new HrefInfo { startIndex = s_TextBuilder.Length * 4, // 超链接里的文本起始顶点索引 endIndex = (s_TextBuilder.Length + match.Groups[2].Length - 1) * 4 + 3, name = group.Value }; m_HrefInfos.Add(hrefInfo); s_TextBuilder.Append(match.Groups[2].Value); s_TextBuilder.Append("</color>"); indexText = match.Index + match.Length; } s_TextBuilder.Append(text.Substring(indexText, text.Length - indexText)); return s_TextBuilder.ToString(); } /// <summary> /// 点击事件检测是否点击到超链接文本 /// </summary> /// <param name="eventData"></param> public void OnPointerClick(PointerEventData eventData) { Vector2 lp; RectTransformUtility.ScreenPointToLocalPointInRectangle( rectTransform, eventData.position, eventData.pressEventCamera, out lp); foreach (var hrefInfo in m_HrefInfos) { var boxes = hrefInfo.boxes; for (var i = 0; i < boxes.Count; ++i) { if (boxes[i].Contains(lp)) { m_OnHrefClick.Invoke(hrefInfo.name); return; } } } } /// <summary> /// 超链接信息类 /// </summary> private class HrefInfo { public int startIndex; public int endIndex; public string name; public readonly List<Rect> boxes = new List<Rect>(); } #endregion2.在文本绘制完成后处理超链接的包围盒
#region 处理超链接的包围盒 // 处理超链接包围框 UIVertex vert = new UIVertex(); foreach (var hrefInfo in m_HrefInfos) { hrefInfo.boxes.Clear(); if (hrefInfo.startIndex >= toFill.currentVertCount) { continue; } // 将超链接里面的文本顶点索引坐标加入到包围框 toFill.PopulateUIVertex(ref vert, hrefInfo.startIndex); var pos = vert.position; var bounds = new Bounds(pos, Vector3.zero); for (int i = hrefInfo.startIndex, m = hrefInfo.endIndex; i < m; i++) { if (i >= toFill.currentVertCount) { break; } toFill.PopulateUIVertex(ref vert, i); pos = vert.position; if (pos.x < bounds.min.x) // 换行重新添加包围框 { hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size)); bounds = new Bounds(pos, Vector3.zero); } else { bounds.Encapsulate(pos); // 扩展包围框 } } hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size)); } #endregion3.看一下文中中超链接的输入规则
4.简单写了一个测试脚本,用来监听点击事件
using UnityEngine; using System.Collections; public class TestClickInlineText : MonoBehaviour { private InlieText _text; void Awake() { _text = GetComponent<InlieText>(); } void OnEnable() { _text.onHrefClick.AddListener(OnHrefClick); } void OnDisable() { _text.onHrefClick.RemoveListener(OnHrefClick); } private void OnHrefClick(string hrefName) { Debug.Log("点击了 " + hrefName); // Application.OpenURL("www.baidu.com"); } }5.运行截图:
6.更新速度实在太慢,为了早点完结图文混排,这里的功能是复制的,有什么疑问的话,可以再讨论,这里的功能也就更新得差不多了,最后再给一个最新的源码链接,短时间没有特殊的功能或者bug,就不打算再更新了
工程源码链接:https://github.com/coding2233/TextInlineSprite
作者:qq992817263 发表于2016/10/25 11:14:44 原文链接
阅读:141 评论:0 查看评论