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 |
1 | Hello<quad material=1 size=20 x=0 y=0 width=1 height=1 />World |
1 | N<quad name=xb_b size=25 width=1 /> |
我们可以取标签最后所在的顶点,将图片放置于此坐标。新建一个类,派生自原生的 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); } } } } |
1 | Trying to add Image (UnityEngine.UI.Image) for graphic rebuild while we are already inside a graphic rebuild loop. This is not supported. |
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 插入超链接》。
源码和示例地址:https://github.com/akof1314/uGUI_LinkImageText再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net