关闭

Unity Text 插入图片

标签: unityui
16045人阅读 评论(29) 收藏 举报
分类:
当前测试版本:Unity 5.2.0

Unity 新 UI 系统中的 Text 组件支持富文本标签,标签包括 b(黑体)、i(斜体)、size(大小)、color(颜色),并不支持图片的直接插入。但官方文档提到可以对 Text Mesh 插入贴图,文档说明如下:
quad
 
This is only useful for text meshes and renders an image inline with the text. It takes parameters that specify the material to use for the image, the image height in pixels, and a further four that denote a rectangular area of the image to display. Unlike the other tags, quad does not surround a piece of text and so there is no ending tag - the slash character is placed at the end of the initial tag to indicate that it is “self-closing”.
 
   <quad material=1 size=20 x=0.1 y=0.1 width=0.5 height=0.5 />
 
This selects the material at position in the renderer’s material array and sets the height of the image to 20 pixels. The rectangular area of image starts at given by the x, y, width and height values, which are all given as a fraction of the unscaled width and height of the texture.

即 Text Mesh 上可以在文本内插入一张图片,参数 material 表示所要插入图片的材质下标。

创建一个 3D Text 对象,如下所示:

在 Assets 目录下,创建一个空材质,材质设置如下:

对 Mesh Renderer 添加这个材质,然后设置 Text Mesh 的 Text 属性为
1
Hello<quad material=1 size=20 x=0.1 y=0.1 width=0.5 height=0.5 />World
效果为如下所示:

重新设置 Text Mesh 的 Text 属性为
1
Hello<quad material=1 size=20 x=0 y=0 width=1 height=1 />World
效果为如下所示:

插入图片标签里面的属性 x 和 y 表示材质里图片的偏移位置,将会根据这两个值,对最后的图片进行反向偏移。width 和 height 表示图片未缩放前的比例,将会根据这两个值,对最后的图片进行缩放到原始比例。

uGUI 里面的 Text 组件无法使用这种方式插入图片,但是可以使用这种方式来变成占位符,最后再在占位符的位置放上所需要插入的图片。
占位符效果如下所示:

用下面的文本内容进行测试:
1
N<quad name=xb_b size=25 width=1 />
每个字母占4个顶点,即使是 quad 标签所占用的字符串,也要占用顶点数,如下图所示:

我们可以取标签最后所在的顶点,将图片放置于此坐标。新建一个类,派生自原生的 Text 类,代码如下:
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
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine.UI;
 
public class TextPic : Text
{
    /// <summary>
    /// 图片池
    /// </summary>
    private readonly List<Image> m_ImagesPool = new List<Image>();
 
    /// <summary>
    /// 图片的最后一个顶点的索引
    /// </summary>
    private readonly List<int> m_ImagesVertexIndex = new List<int>();
 
    /// <summary>
    /// 正则取出所需要的属性
    /// </summary>
    private static readonly Regex s_Regex = 
          new Regex(@"<quad name=(.+?) size=(\d*\.?\d+%?) width=(\d*\.?\d+%?) />", RegexOptions.Singleline);
 
    public override void SetVerticesDirty()
    {
        base.SetVerticesDirty();
        UpdateQuadImage();
    }
 
    protected void UpdateQuadImage()
    {
        m_ImagesVertexIndex.Clear();
        foreach (Match match in s_Regex.Matches(text))
        {
            var picIndex = match.Index + match.Length - 1;
            var endIndex = picIndex * 4 + 3;
            m_ImagesVertexIndex.Add(endIndex);
 
            m_ImagesPool.RemoveAll(image => image == null);
            if (m_ImagesPool.Count == 0)
            {
                GetComponentsInChildren<Image>(m_ImagesPool);
            }
            if (m_ImagesVertexIndex.Count > m_ImagesPool.Count)
            {
                var resources = new DefaultControls.Resources();
                var go = DefaultControls.CreateImage(resources);
                go.layer = gameObject.layer;
                var rt = go.transform as RectTransform;
                if (rt)
                {
                    rt.SetParent(rectTransform);
                    rt.localPosition = Vector3.zero;
                    rt.localRotation = Quaternion.identity;
                    rt.localScale = Vector3.one;
                }
                m_ImagesPool.Add(go.GetComponent<Image>());
            }
 
            var spriteName = match.Groups[1].Value;
            var size = float.Parse(match.Groups[2].Value);
            var img = m_ImagesPool[m_ImagesVertexIndex.Count - 1];
            if (img.sprite == null || img.sprite.name != spriteName)
            {
                img.sprite = Resources.Load<Sprite>(spriteName);
            }
            img.rectTransform.sizeDelta = new Vector2(size, size);
            img.enabled = true;
        }
 
        for (var i = m_ImagesVertexIndex.Count; i < m_ImagesPool.Count; i++)
        {
            if (m_ImagesPool[i])
            {
                m_ImagesPool[i].enabled = false;
            }
        }
    }
 
    protected override void OnPopulateMesh(Mesh toFill)
    {
        base.OnPopulateMesh(toFill);
        var verts = toFill.vertices;
 
        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 < verts.Length)
            {
                rt.anchoredPosition = new Vector2(verts[endIndex].x + size.x / 2, verts[endIndex].y + size.y / 2);
            }
        }
    }
}
不能够直接在 OnPopulateMesh 里面修改图片的大小,否则会报如下错误:
1
Trying to add Image (UnityEngine.UI.Image) for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported.
最后效果如下所示:

图片根据标签里面的 name 属性来加载,从 Resources 目录读取。图片的大小通过 size 属性来控制。

但是,可以发现左下角有小黑点绘制,这是因为使用到了 quad 标签,但是没有用它底层的插入图片方式,所以“乱码”显示了小黑点。这里用更改顶点坐标方式来抹除,更改代码如下:
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
    protected override void OnPopulateMesh(Mesh toFill)
    {
        base.OnPopulateMesh(toFill);
        var verts = toFill.vertices;
 
        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 < verts.Length)
            {
                rt.anchoredPosition = new Vector2(verts[endIndex].x + size.x / 2, verts[endIndex].y + size.y / 2);
 
                // 抹掉左下角的小黑点
                for (int j = endIndex, m = endIndex - 3; j > m; j--)
                {
                    verts[j] = verts[m];
                }
            }
        }
 
        if (m_ImagesVertexIndex.Count != 0)
        {
            toFill.vertices = verts;
            m_ImagesVertexIndex.Clear();
        }
    }
最后的效果如下:

测试例子如下:

当然离最后的使用,还需要进行进一步的修改。

Unity 5.2.2 接口更改,见下一篇文章《Unity Text 插入超链接》。



5
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Unity Text 插入图片

http://blog.csdn.net/akof1314/article/details/49028279
  • lihui061119
  • lihui061119
  • 2016-08-23 17:40
  • 495

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

继上一篇说的更新了一张图集对应多个Text的功能,为了节省资源嘛 这里,但是也没有舍弃之前的一个Text一个图集,因为我感觉应该两个都有用,于是我重新写了一个脚本 1.其实大体跟前面的都没变,解析标签,获取表情的相关数据,这里只是将绘制图片的功能,移植到SpriteGraphic上,本地增加了一...
  • qq992817263
  • qq992817263
  • 2016-10-14 19:54
  • 3135

Unity UGUI——显示图片(Raw Image)

Texture、Color、Material、UV Rect
  • Mr_AHao
  • Mr_AHao
  • 2015-03-18 19:47
  • 13232

Unity UI(四):Text、Image/RawImage和Mask

TextText组件CharacterText:显示的文本 Font:字体 FontStyle:样式 LineSpacing:行间距,单位是行高 Rich Text:是否支持HTML标签。支持b、i、size、color等标签。ParagraphAlignment对齐方式 Horizont...
  • wkhabc
  • wkhabc
  • 2016-08-25 22:30
  • 1723

Unity笔记 UGUI RichText 文字表情图片

文字插入图片
  • fjl2007
  • fjl2007
  • 2015-07-23 11:25
  • 3863

知道 Text Mesh Pro插件比Unity原生的Text组件效果好的原因了

在了解 国人开发开源的一个游戏引擎  “ KlayGE游戏引擎”  的文档时看到  它“klayge中的字体系统”  http://www.klayge.org/docs/klayge%e4%b8%ad%e7%9a%84%e5%ad%97%...
  • u010019717
  • u010019717
  • 2016-11-14 09:21
  • 3774

Unity3D 官方文档 UGUI总览 一个将图片铺满整个屏幕的技巧、可视化组件的介绍

版本:unity 5.6  语言:C#   总起: 可视化组件主要包括Text、Image等只提供显示效果,并不提供点击事件的组件,这些组件其实是基础,很多可互动的组件都会用到这些显示效果。   不过先不忙介绍这个,最近看了锚点之后,问了一个新员工怎么将图片铺满整个屏幕...
  • u012632851
  • u012632851
  • 2017-08-06 19:50
  • 1513

Unity3d中插入图片

using UnityEngine; using System.Collections; using UnityEditor; public class Script1_1 : MonoBehaviour { //贴图 Texture2D texture; // Use this for...
  • u013425527
  • u013425527
  • 2014-09-28 15:21
  • 1216

unity canvas text显示及其角色伤害TextMesh显示

1、unity canvas text显示 ①参考:http://www.unity.5helpyou.com/3228.html ②在摄像头视角绑定角色(即角色在屏幕坐标位置始终不变)时,使用第一种方法。 ③摄像头不绑定角色时,使用第二种方法,如果游戏中摄像头视角可变,则可以让canvas游...
  • u014686875
  • u014686875
  • 2015-08-11 13:34
  • 1636

[原创]unity3D学习【功能实现】之五:在图片上显示文字或名字,可更改text mesh

mesh" TITLE="[原创]unity3D学习【功能实现】之五:在图片上显示文字或名字,可更改text mesh" /> mesh" TITLE="[原创]unity3D学习【功能实现】之五:在图片上显示文字或名字,可更改...
  • vipzjh
  • vipzjh
  • 2016-08-15 15:14
  • 2413
    个人资料
    • 访问:3510471次
    • 积分:35832
    • 等级:
    • 排名:第138名
    • 原创:400篇
    • 转载:88篇
    • 译文:5篇
    • 评论:3420条
    个人说明
    联系方式:
    文章存档
    最新评论