图文混排更新到超链接这儿,好像也差不多了,不过就在最后一点,博主也表现得相当不专业,直接整合了山中双木林同学提供的超链接的解决方案,博主甚至没来得及细看就直接复制了,但感觉还是挺好用的。

博主已经将超链接的功能直接整合到了之前的InlineText和InlineSpriteText的两个脚本中

1.定义超链接的正则表达式和事件监听

  1. #region 超链接
  2. /// <summary>
  3. /// 超链接信息列表
  4. /// </summary>
  5. private readonly List<HrefInfo> m_HrefInfos = new List<HrefInfo>();
  6.  
  7. /// <summary>
  8. /// 文本构造器
  9. /// </summary>
  10. private static readonly StringBuilder s_TextBuilder = new StringBuilder();
  11.  
  12. /// <summary>
  13. /// 超链接正则
  14. /// </summary>
  15. private static readonly Regex s_HrefRegex =
  16. new Regex(@"<a href=([^>\n\s]+)>(.*?)(</a>)", RegexOptions.Singleline);
  17.  
  18. [System.Serializable]
  19. public class HrefClickEvent : UnityEvent<string> { }
  20.  
  21. [SerializeField]
  22. private HrefClickEvent m_OnHrefClick = new HrefClickEvent();
  23.  
  24. /// <summary>
  25. /// 超链接点击事件
  26. /// </summary>
  27. public HrefClickEvent onHrefClick
  28. {
  29. get { return m_OnHrefClick; }
  30. set { m_OnHrefClick = value; }
  31. }
  32.  
  33. /// <summary>
  34. /// 获取超链接解析后的最后输出文本
  35. /// </summary>
  36. /// <returns></returns>
  37. protected string GetOutputText()
  38. {
  39. s_TextBuilder.Length = 0;
  40. m_HrefInfos.Clear();
  41. var indexText = 0;
  42. foreach (Match match in s_HrefRegex.Matches(text))
  43. {
  44. s_TextBuilder.Append(text.Substring(indexText, match.Index - indexText));
  45. s_TextBuilder.Append("<color=blue>"); // 超链接颜色
  46.  
  47. var group = match.Groups[1];
  48. var hrefInfo = new HrefInfo
  49. {
  50. startIndex = s_TextBuilder.Length * 4, // 超链接里的文本起始顶点索引
  51. endIndex = (s_TextBuilder.Length + match.Groups[2].Length - 1) * 4 + 3,
  52. name = group.Value
  53. };
  54. m_HrefInfos.Add(hrefInfo);
  55.  
  56. s_TextBuilder.Append(match.Groups[2].Value);
  57. s_TextBuilder.Append("</color>");
  58. indexText = match.Index + match.Length;
  59. }
  60. s_TextBuilder.Append(text.Substring(indexText, text.Length - indexText));
  61. return s_TextBuilder.ToString();
  62. }
  63.  
  64. /// <summary>
  65. /// 点击事件检测是否点击到超链接文本
  66. /// </summary>
  67. /// <param name="eventData"></param>
  68. public void OnPointerClick(PointerEventData eventData)
  69. {
  70. Vector2 lp;
  71. RectTransformUtility.ScreenPointToLocalPointInRectangle(
  72. rectTransform, eventData.position, eventData.pressEventCamera, out lp);
  73.  
  74. foreach (var hrefInfo in m_HrefInfos)
  75. {
  76. var boxes = hrefInfo.boxes;
  77. for (var i = 0; i < boxes.Count; ++i)
  78. {
  79. if (boxes[i].Contains(lp))
  80. {
  81. m_OnHrefClick.Invoke(hrefInfo.name);
  82. return;
  83. }
  84. }
  85. }
  86. }
  87.  
  88. /// <summary>
  89. /// 超链接信息类
  90. /// </summary>
  91. private class HrefInfo
  92. {
  93. public int startIndex;
  94.  
  95. public int endIndex;
  96.  
  97. public string name;
  98.  
  99. public readonly List<Rect> boxes = new List<Rect>();
  100. }
  101. #endregion

2.在文本绘制完成后处理超链接的包围盒

  1. #region 处理超链接的包围盒
  2. // 处理超链接包围框
  3. UIVertex vert = new UIVertex();
  4. foreach (var hrefInfo in m_HrefInfos)
  5. {
  6. hrefInfo.boxes.Clear();
  7. if (hrefInfo.startIndex >= toFill.currentVertCount)
  8. {
  9. continue;
  10. }
  11.  
  12. // 将超链接里面的文本顶点索引坐标加入到包围框
  13. toFill.PopulateUIVertex(ref vert, hrefInfo.startIndex);
  14. var pos = vert.position;
  15. var bounds = new Bounds(pos, Vector3.zero);
  16. for (int i = hrefInfo.startIndex, m = hrefInfo.endIndex; i < m; i++)
  17. {
  18. if (i >= toFill.currentVertCount)
  19. {
  20. break;
  21. }
  22.  
  23. toFill.PopulateUIVertex(ref vert, i);
  24. pos = vert.position;
  25. if (pos.x < bounds.min.x) // 换行重新添加包围框
  26. {
  27. hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));
  28. bounds = new Bounds(pos, Vector3.zero);
  29. }
  30. else
  31. {
  32. bounds.Encapsulate(pos); // 扩展包围框
  33. }
  34. }
  35. hrefInfo.boxes.Add(new Rect(bounds.min, bounds.size));
  36. }
  37. #endregion

3.看一下文中中超链接的输入规则

4.简单写了一个测试脚本,用来监听点击事件

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. public class TestClickInlineText : MonoBehaviour {
  5. private InlieText _text;
  6.  
  7. void Awake()
  8. {
  9. _text = GetComponent<InlieText>();
  10. }
  11.  
  12. void OnEnable()
  13. {
  14. _text.onHrefClick.AddListener(OnHrefClick);
  15. }
  16.  
  17. void OnDisable()
  18. {
  19. _text.onHrefClick.RemoveListener(OnHrefClick);
  20. }
  21.  
  22. private void OnHrefClick(string hrefName)
  23. {
  24. Debug.Log("点击了 " + hrefName);
  25. // Application.OpenURL("www.baidu.com");
  26. }
  27. }

5.运行截图:

6.更新速度实在太慢,为了早点完结图文混排,这里的功能是复制的,有什么疑问的话,可以再讨论,这里的功能也就更新得差不多了,最后再给一个最新的源码链接,短时间没有特殊的功能或者bug,就不打算再更新了

工程源码链接:https://github.com/coding2233/TextInlineSprite

Unity UGUI图文混排(六) -- 超链接的更多相关文章

  1. Unity UGUI图文混排源码(三) -- 动态表情

    这里是根据图文混排源码(二)进一步修改的,其他链接也不贴了,就贴一个链接就好了,第一次看这文章的同学可以先去看看其他几篇文章 Unity UGUI图文混排源码(二):http://blog.csdn. ...

  2. Unity UGUI图文混排源码(二)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

  3. Unity UGUI图文混排源码(一)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

  4. Unity UGUI图文混排(七) -- 下划线

    之前更新超链接的时候,忘了搭配实现一个下划线的功能,这篇文章就是来补上这一个功能,时间有点长,一方面没有很好的思路,一方面也没多少时间. 先在网上收集了一下下划线的实现操作,一种是在文本下再创建一个文 ...

  5. Unity UGUI图文混排(五) -- 一张图集对应多个Text

    继上一篇说的更新了一张图集对应多个Text的功能,为了节省资源嘛 这里,但是也没有舍弃之前的一个Text一个图集,因为我感觉应该两个都有用,于是我重新写了一个脚本 1.其实大体跟前面的都没变,解析标签 ...

  6. Unity UGUI图文混排源码(四) -- 聊天气泡

    这里有同学建议在做聊天气泡时,可以更改为一张图集对应多个Text,这样能节省资源,不过我突然想到每个Text一个图集,可以随时更换图集,这样表情图更丰富一些,于是我就先将现有的聊天demo改为了聊天气 ...

  7. [UGUI]图文混排(六):点击区域

    点击区域可以分成两部分来分析: 0.Rect 搜索api:Rect和Rect.Rect,可以知道: 在GUI和GUILayout中,Rect的原点在左上角,向右为x轴正方向,向下为y轴正方向: 除此之 ...

  8. Unity琐碎(3) UGUI 图文混排解决方案和优化

    感觉使用Unity之后总能看到各种各样解决混排的方案,只能说明Unity不够体恤下情啊.这篇文章主要讲一下个人在使用过程中方案选择和优化过程,已做记录.顺便提下,开源很多意味着坑,还是要开实际需求. ...

  9. [UGUI]图文混排(二):Text源码分析

    UGUI源码: https://bitbucket.org/Unity-Technologies/ui/downloads/?tab=tags 首先下载一份UGUI源码,这里我下载的版本是5.3.2f ...

随机推荐

  1. C#之Winform跨线程访问控件

    C#中禁止跨线程直接访问控件,InvokeRequired是为了解决这个问题而产生的,当一个控件的InvokeRequired属性值为真时,说明有一个创建它以外的线程想访问它.此时它将会在内部调用ne ...

  2. 树莓派控制HC-SR04超声波模块测距(新手向+C语言向)

    因为作业要求使用c语言代码,这里先附上一段摘自网上的代码 感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/6 ...

  3. [NOIp 2012]国王游戏

    Description 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排成一排,国 ...

  4. 模板Link Cut Tree (动态树)

    题目描述 给定N个点以及每个点的权值,要你处理接下来的M个操作.操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和.保证x到y是联 ...

  5. [SDOI2010]代码拍卖会

    题目描述 随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库.猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库.iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关 ...

  6. 【LSGDOJ1834 Tree】树链剖分

    题目描述 给定一个N个结点的无向树,树中的结点按照1...N编号,树中的边按照1...N − 1编号,每条边都赋予一个权值.你需要编写程序支持以下三种操作: 1.    CHANGE i v:将i号边 ...

  7. bzoj2007 NOI2010 网络流转对偶图

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2775  Solved: 1331[Submit][Status] ...

  8. JFinal实现伪静态

    JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速.代码量少.学习简单.功能强大.轻量级.易扩展.Restful.在拥有Java语言所有优势的同时再拥有ru ...

  9. 在浏览器中运行Keras模型,并支持GPU

    Keras.js 推荐一下网页上的 demo https://transcranial.github.io/keras-js/#/ 加载的比较慢,但是识别的非常快. Run Keras models ...

  10. 认识Json解析json生成json

    .markdown-body hr::after,.markdown-body::after { clear: both } .loopLine,.messageLine0 { } .markdown ...