Unity Text 插入图片
来源:互联网 发布:淘宝实拍保护入口 编辑:程序博客网 时间:2024/06/05 18:29
当前测试版本:Unity 5.2.0
Unity 新 UI 系统中的 Text 组件支持富文本标签,标签包括 b(黑体)、i(斜体)、size(大小)、color(颜色),并不支持图片的直接插入。但官方文档提到可以对 Text Mesh 插入贴图,文档说明如下:
quadThis 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 属性为
Hello<quad material=1 size=20 x=0.1 y=0.1 width=0.5 height=0.5 />World
效果为如下所示:
重新设置 Text Mesh 的 Text 属性为
Hello<quad material=1 size=20 x=0 y=0 width=1 height=1 />World
效果为如下所示:
插入图片标签里面的属性 x 和 y 表示材质里图片的偏移位置,将会根据这两个值,对最后的图片进行反向偏移。width 和 height 表示图片未缩放前的比例,将会根据这两个值,对最后的图片进行缩放到原始比例。
uGUI 里面的 Text 组件无法使用这种方式插入图片,但是可以使用这种方式来变成占位符,最后再在占位符的位置放上所需要插入的图片。
占位符效果如下所示:
用下面的文本内容进行测试:
N<quad name=xb_b size=25 width=1 />
每个字母占4个顶点,即使是 quad 标签所占用的字符串,也要占用顶点数,如下图所示:
我们可以取标签最后所在的顶点,将图片放置于此坐标。新建一个类,派生自原生的 Text 类,代码如下:
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);
}
}
}
}
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);
}
}
}
}
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 标签,但是没有用它底层的插入图片方式,所以“乱码”显示了小黑点。这里用更改顶点坐标方式来抹除,更改代码如下:
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();
}
}
{
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 插入超链接》。
源码和示例地址:https://github.com/akof1314/uGUI_LinkImageText
4 0
- Unity Text 插入图片
- Unity Text 插入图片
- Unity Text 插入超链接
- Unity Text 插入超链接
- Unity Text 插入超链接
- unity 富文本 插入图片
- Tkinter——在text中插入图片
- Unity Text加入超链接
- unity 2048 noplaymaker text
- Unity UGUI--Text组件
- Unity重写Text
- Unity Text文本样式
- unity -- 关于文字text和图片image等组件一起居中解决方案
- 插入图片
- Unity 插入视频vedio
- Unity插入视频音频
- Unity UGUI基础之Text
- Unity读取Text文本案例
- 判断iframe是否加载完毕,在执行某方法
- java—封装、继承、多态
- HDU 4421 & ZOJ 3556 Bit Magic(2-SAT 位运算 模板题)
- 集体智慧编程第二三章学习总结
- 今天的小收获
- Unity Text 插入图片
- 文件过滤
- c# ascill码和对应字符转化
- 关于PADS的一些概念和实用技巧(二)
- Mongo中id介绍
- 链表的创建 查找 排序 插入 删除 逆序 长度 显示
- LeetCode---Remove Linked List Elements
- 自定义函数库
- 好用的iOS开发工具