分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

当前测试版本:Unity 5.2.0
Unity 新 UI 系统中的 Text 组件支持富文本标签,标签包括 b(黑体)、i(斜体)、size(大小)、color(颜色),并不支持超链接以及超链接点击。之前一篇实现了简单的插入图片方法,见《Unity Text 插入图片》。这里在上一篇的基础上,继续实现插入超链接。

标签

设计超链接自有的标签,这里使用 a 标签来表示超链接,完整的内容如下:
<a href=超链接>文本</a>

颜色支持

让超链接的文本内容,自动变成其他颜色显示,比如通用的蓝色显示。这一步,只需解析超链接标签,提取里面的文本,对其加上颜色标签,然后去掉超链接标签内容。
增加变量声明,代码如下:
1
2
3
4
5
6
7
8
9
10
11
/// <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);
增加获取解析之后的文本方法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
    /// 获取超链接解析后的最后输出文本
    /// </summary>
    /// <returns></returns>
    protected string GetOutputText()
    {
        s_TextBuilder.Length = 0;
        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>");  // 超链接颜色            
 
            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();
    }
更改 OnPopulateMesh 方法,替换最终绘制的文本,代码如下:
1
2
3
4
5
6
7
8
9
protected override void OnPopulateMesh(Mesh toFill)
    {
        var orignText = m_Text;
        m_Text = GetOutputText();
        base.OnPopulateMesh(toFill);
        m_Text = orignText;
        
        // ................
    }
用下面的内容进行测试:
1
请立即装备<a href=mujian>[木剑]</a>武器
效果如下所示:

点击支持

超链接需要支持可点击事件,故要让派生类继承自 IPointerClickHandler 接口。另外,点中超链接文本的位置检测,需要有矩形框来判断,而当文本被折行时,矩形框也要包括下一行的部分。
修改之后的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/// <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);
 
    [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>();
    }
修改 OnPopulateMesh 方法,在里面进行超链接矩形框的处理添加,代码更改如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
protected override void OnPopulateMesh(Mesh toFill)
    {
        var orignText = m_Text;
        m_Text = GetOutputText();
        base.OnPopulateMesh(toFill);
        m_Text = orignText;
        var verts = toFill.vertices;
 
        // ...... 处理图片
      
        // 处理超链接包围框
        foreach (var hrefInfo in m_HrefInfos)
        {
            hrefInfo.boxes.Clear();
            if (hrefInfo.startIndex >= verts.Length)
            {
                continue;
            }
 
            // 将超链接里面的文本顶点索引坐标加入到包围框
            var pos = verts[hrefInfo.startIndex];
            var bounds = new Bounds(pos, Vector3.zero);
            for (int i = hrefInfo.startIndex, m = hrefInfo.endIndex; i < m; i++)
            {
                if (i >= verts.Length)
                {
                    break;
                }
 
                pos = verts[i];
                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));
        }
    }
最后更改类的派生,代码如下:
1
2
3
4
5
6
7
8
9
10
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
 
public class TextPic : Text, IPointerClickHandler
添加测试脚本 testHref.cs,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using UnityEngine;
 
public class testHref : MonoBehaviour
{
    public TextPic textPic;
 
    void Awake()
    {
        textPic = GetComponent<TextPic>();
    }
 
    void OnEnable()
    {
        textPic.onHrefClick.AddListener(OnHrefClick);
    }
 
    void OnDisable()
    {
        textPic.onHrefClick.RemoveListener(OnHrefClick);
    }
 
    private void OnHrefClick(string hrefName)
    {
        Debug.Log("点击了 " + hrefName);
    }
}
附加测试脚本到文本控件上,运行,鼠标点击超链接文本,打印出点击的名称,效果如下图所示:

图片结合

在与上一篇的插入图片进行结合使用时,会发现图片显示不正确了,如下图所示:
这是因为图片解析时的文本跟超链接解析时的文本不同导致顶点索引位置不对应,更改方法为,将图片解析时的文本改为最终解析完的文本,更改 UpdateQuadImage 方法代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
/// <summary>
    /// 解析完最终的文本
    /// </summary>
    private string m_OutputText;
 
    protected void UpdateQuadImage()
    {
        m_OutputText = GetOutputText();
        m_ImagesVertexIndex.Clear();
        foreach (Match match in s_Regex.Matches(m_OutputText))
        // ......................
    }
更改 OnPopulateMesh 方法,代码如下:
1
2
3
4
5
6
7
8
protected override void OnPopulateMesh(Mesh toFill)
    {
        var orignText = m_Text;
        m_Text = m_OutputText;
        base.OnPopulateMesh(toFill);
        m_Text = orignText;
        // ..........................
     }
最后运行效果如下图所示:
当然离最后的使用,还需要进行进一步的修改。

Unity 5.2.2 接口更改,更改上面的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
protected override void OnPopulateMesh(VertexHelper toFill)
    {
        var orignText = m_Text;
        m_Text = m_OutputText;
        base.OnPopulateMesh(toFill);
        m_Text = orignText;

UIVertex vert = new UIVertex();
        for (var i = 0; i < m_ImagesVertexIndex.Count; i++)
        {
            var endIndex = m_ImagesVertexIndex[i];
            var rt = m_ImagesPool[i].rectTransform;
            var size = rt.sizeDelta;
            if (endIndex < toFill.currentVertCount)
            {
                toFill.PopulateUIVertex(ref vert, endIndex);
                rt.anchoredPosition = new Vector2(vert.position.x + size.x / 2, vert.position.y + size.y / 2);

// 抹掉左下角的小黑点
                toFill.PopulateUIVertex(ref vert, endIndex - 3);
                var pos = vert.position;
                for (int j = endIndex, m = endIndex - 3; j > m; j--)
                {
                    toFill.PopulateUIVertex(ref vert, endIndex);
                    vert.position = pos;
                    toFill.SetUIVertex(vert, j);
                }
            }
        }

if (m_ImagesVertexIndex.Count != 0)
        {
            m_ImagesVertexIndex.Clear();
        }

// 处理超链接包围框
        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));
        }
    }

还有图片的位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected void UpdateQuadImage()
    {
#if UNITY_EDITOR
        if (UnityEditor.PrefabUtility.GetPrefabType(this) == UnityEditor.PrefabType.Prefab)
        {
            return;
        }
#endif
        m_OutputText = GetOutputText(text);
        m_ImagesVertexIndex.Clear();
        foreach (Match match in s_ImageRegex.Matches(m_OutputText))
        {
            var picIndex = match.Index;
            var endIndex = picIndex * 4 + 3;
            m_ImagesVertexIndex.Add(endIndex);

// ......
    }

源码和示例地址:https://github.com/akof1314/uGUI_LinkImageText

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

Unity Text 插入超链接相关推荐

  1. Unity Text 插入图片

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 当前测试 ...

  2. Ctrl+K:插入超链接(Hyperlink)

    也许大家都知道了这个快捷键(Shortcut Key):Ctrl+K在Office程序之中可用来插入超链接.今天在写Blog的时候,才发现.Text使用的FreeTextBox其实也支持这个Short ...

  3. jsp中去掉超链接下划线吗_好烦啊,PPT 插入超链接,文字自动变色还有下划线!还不能改?!...

    「老师,PPT 中插入超链接,为什么设置之后文字不仅改变了颜色,还多了一条下划线,但是选中后更改没有反应--有没有办法让文字看着正常一点?」 效果类似这样: 这是在给秋叶PPT的学员进行答疑的时候,遇 ...

  4. PPT文档中如何插入超链接

    PPT如何插入超链接呢?一起来看看吧! 1.运行office软件,打开需要插入超链接的PPT文档: 2.点击鼠标选中想要插入超链接位置,右键,菜单中选择"超链接": ​3.此时,在 ...

  5. Unity Text富文本(文本变得多姿多彩)

    Unity Text富文本(文本变得多姿多彩) 实例: 步骤如下: 1.创建一个UI Text 2.Text组件中的Rich Text要勾选上 3.写内容 html控制代码 实例: 步骤如下: 1.创 ...

  6. unity Text文字淡入效果

    unity Text文字淡入效果 CrossFadeAlpha()方法 先将alpha降为0,再改为1. public Text t;void Start() {t.CrossFadeAlpha(0f ...

  7. unity Text Mesh Pro Sprite Animation 支持动图,动态表情

    unity Text Mesh Pro Sprite Animation 支持动图,动态表情 使用格式 <sprite='assetName' anim='first frame, last f ...

  8. 用计算机做表格的超链接,如何在Excel中插入”超链接”功能

    我们在中文Excel中查阅数据时,往往须要把工作表从头至尾浏览一遍,如果工作表很长,这样做显得很麻烦.使用中文Excel提供的超链接功能,只须单击鼠标,即可跳转到当前工作表的某个位置或者其他工作表(甚 ...

  9. 超链接有哪几种 制作表格时WPS怎么在表格中插入超链接

    在制作wps表格的时候,怎么样在表格中插入超链接呢?下面小编就为你介绍wps表格如何插入超链接的方法啦! wps表格插入超链接的方法: 1.打开WPS表格,我们新建一个空白文档. 2.我们点击插入菜单 ...

最新文章

  1. 解决烦人的img与input不能水平对齐的问题
  2. 【转】Hibernate和IBatis对比
  3. c# 类的基本知识,未完,待续
  4. leetcode696. 计数二进制子串
  5. 博客园配置windows live writer,实现本地代码高亮
  6. 在计算机系统中 外存储器必须通过,大学计算机基础第4章作业.doc
  7. zookeeper:Too many connections 故障处理记录
  8. Java基础篇:如何应用接口?
  9. 11.30上海交大PMP试题每日一题
  10. LabVIEW 使用入门(简明笔记)
  11. 计算机网络基础知识题,计算机网络基础知识试题及答案
  12. Spotfire中文教程
  13. 企业无线产品认证好吗
  14. 利用Python,通过关键字获取漏洞平台最新漏洞信息
  15. 音视频入门之如何绘制一张图片
  16. 远程视频监控之构思篇
  17. 微信小程序的运营与装修,简单几步掌握
  18. PVCBOT【21号】挑战者--人形机甲战士
  19. nvh个人检测下载_变速箱NVH质量检验系统.pdf
  20. python使用目录_python目录操作一

热门文章

  1. 数据库面试 - 如何设计才可以让系统从未分库分表动态切换到分库分表上?
  2. arp协议、arp应答出现的原因、arp应答过程、豁免ARP详细解答附图(建议电脑观看)
  3. 方法 注释_在IDEA中配置类和方法的文档注释
  4. leaflet-webpack 入门开发系列二加载不同在线地图切换显示(附源码下载)
  5. mac chrome 跨域
  6. 【Python】自动化升级所有pip安装的包
  7. 【Python】Python库之网络爬虫
  8. 在线编码工具_我希望在开始编码时就已经知道的工具
  9. 103_Power Pivot 透视表中空白标签处理及百分比
  10. 云服务器 存放 文件夹,云服务器 存放 文件夹