当前位置:网站首页>Unity图文混排实现
Unity图文混排实现
2022-08-08 22:07:00 【w0100746363】
实现在文本中插入图片,图片替换符使用如下格式 //XML: <quad index=0 size=60> 代码中<quad index=0 size=60>
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Text))]
public class TextTagHook : BaseMeshEffect
{
public class SpriteTagInfo
{
public int index;
public int stringIndex;
public Vector2 size;
public bool isVisible = true;
}
//in XML: <quad index=0 size=60> <quad index=0 size=60>
private static readonly Regex spriteTagRegex = new Regex(@"<quad\s+index=(\d+)\s+size=(\d*\.?\d+%?)(\s+width=(\d*\.?\d+%?))?\s*>", RegexOptions.Singleline);
private static readonly Regex spriteTagReplacementRegex = new Regex(@"{}", RegexOptions.Singleline);
private static readonly Regex tagRegex = new Regex(@"<.*?>", RegexOptions.Singleline);
private static readonly Regex whitespaceRegex = new Regex(@"\s+", RegexOptions.Singleline);
public RectTransform[] tagObjects = new RectTransform[] { };
private Text _text;
public Text text
{
get
{
if (_text == null)
{
_text = GetComponent<Text>();
}
return _text;
}
}
private List<SpriteTagInfo> spriteTags = new List<SpriteTagInfo>();
private string lastContent;
private bool lastBestFit;
private int lastVertexCount;
private bool isContentDirty
{
get
{
return true;
}
}
private bool isValid;
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive()) return;
if (isContentDirty)
{
lastContent = text.text;
lastBestFit = text.resizeTextForBestFit;
lastVertexCount = text.cachedTextGenerator.vertexCount;
spriteTags.Clear();
try
{
foreach (Match match in spriteTagRegex.Matches(lastContent))
{
SpriteTagInfo spriteTag = new SpriteTagInfo();
spriteTag.index = int.Parse(match.Groups[1].Value);
spriteTag.stringIndex = match.Index;
spriteTag.size = new Vector2(float.Parse(match.Groups[2].Value), float.Parse(match.Groups[2].Value));
if (match.Groups[4].Success)
{
spriteTag.size.x *= float.Parse(match.Groups[4].Value);
}
spriteTag.isVisible = text.cachedTextGenerator.vertexCount / 4 > spriteTag.stringIndex;
spriteTags.Add(spriteTag);
}
if (text.cachedTextGenerator.vertexCount / 4 != text.cachedTextGenerator.characterCount)
{
string toGenerateContent = spriteTagRegex.Replace(lastContent, "{}");
toGenerateContent = tagRegex.Replace(toGenerateContent, string.Empty);
toGenerateContent = whitespaceRegex.Replace(toGenerateContent, string.Empty);
int index = 0;
foreach (Match match in spriteTagReplacementRegex.Matches(toGenerateContent))
{
spriteTags[index].stringIndex = match.Index - index;
spriteTags[index].isVisible = true;
index++;
}
}
isValid = true;
}
catch (System.Exception e)
{
isValid = false;
}
}
for (int i = 0; i < tagObjects.Length; i++)
{
if (tagObjects[i] != null)
{
tagObjects[i].localScale = Vector3.zero;
}
}
if (isValid)
{
for (int i = 0; i < spriteTags.Count; i++)
{
SpriteTagInfo spriteTag = spriteTags[i];
if (tagObjects.Length > spriteTag.index)
{
var target = tagObjects[spriteTag.index];
if (target == null) continue;
if (spriteTag.isVisible)
{
float unitsPerPixel = 1 / text.pixelsPerUnit;
var verts = text.cachedTextGenerator.verts;
Vector2 roundingOffset = new Vector2(verts[0].position.x, verts[0].position.y) * unitsPerPixel;
roundingOffset = text.PixelAdjustPoint(roundingOffset) - roundingOffset;
Vector3 pox1 = verts[spriteTag.stringIndex * 4 + 3].position;
Vector3 pox2 = verts[spriteTag.stringIndex * 4 + 2].position;
if (roundingOffset != Vector2.zero)
{
pox1 *= unitsPerPixel;
pox1.x += roundingOffset.x;
pox1.y += roundingOffset.y;
pox2 *= unitsPerPixel;
pox2.x += roundingOffset.x;
pox2.y += roundingOffset.y;
}
else
{
pox1 *= unitsPerPixel;
pox2 *= unitsPerPixel;
}
target.localPosition = pox1;
target.localScale = Vector3.one * (pox2.x - pox1.x) / spriteTag.size.x;
}
}
}
List<UIVertex> vertexList = new List<UIVertex>();
vh.GetUIVertexStream(vertexList);
for (int i = 0; i < spriteTags.Count; i++)
{
if (!spriteTags[i].isVisible) continue;
//UGUIText不支持<quad/>标签,表现为乱码,这里将他的uv全设置为0,清除乱码
for (int m = spriteTags[i].stringIndex * 6; m < spriteTags[i].stringIndex * 6 + 6; m++)
{
UIVertex tempVertex = vertexList[m];
tempVertex.uv0 = Vector2.zero;
tempVertex.uv1 = Vector2.zero;
tempVertex.uv2 = Vector2.zero;
tempVertex.uv3 = Vector2.zero;
tempVertex.color = Color.clear;
vertexList[m] = tempVertex;
}
}
vh.Clear();
vh.AddUIVertexTriangleStream(vertexList);
}
}
}
将脚本挂到Text上,如下图,可以通过调整icon1和icon2的位置来调整图片显示的位置。
边栏推荐
- 百度 IP 查询
- Cesium快速上手2-Model图元使用讲解
- 爬虫视频教学:网页数据抓取
- SRv6故障管理
- 基于阿里云的基础架构设施保障(三)IAAS之网络运用
- 为什么要做LiveVideoStack课程?
- CrossFormer: A Versatile Vision Transformer -based on Cross - Scale Transformer paper and code parsing
- 给定二叉搜索树和两个整数A,B (最小整数和最大整数)。如何删除不在该区间内的元素(剪枝)
- 如何判断一个 IP 是爬虫
- 依赖注入的正确打开方式 bilibili/kratos × google/wire
猜你喜欢
ZERO Technology "Chain on the South"——deeply cultivated in the field of digital finance
"scala programming (3rd edition)" study notes
【硬件通讯协议】IIC总线协议以及模拟(软件)IIC
如何寻找竞争情报发挥企业优势
零数科技向海南省委书记汇报数字金融创新
【计网】(五)网络层首部
Cesium快速上手2-Model图元使用讲解
How do I use cURL with a proxy?
Cesium快速上手3-Billboard/Label/PointPrimitives图元使用讲解
C盘的空间管理
随机推荐
论网络安全的重要性
sqli_libsLess-2 GET - Error based - Intiger based (基于错误的GET整型注入)
2.1.5 折叠剪切展开问题
每天记录学习的新知识 :ParameterizedType +
SRv6故障管理
How do I use cURL with a proxy?
2020-03-09
爬虫系列:存储媒体文件
DCM: 中间件家族迎来新成员
Real-time crawler example explanation
Scala encryption and hash functions
BSV 中的零开销私人时间戳
Mysql汉字乱码的问题
Is the commission for online account opening reliable? Is it safe to open an account with an online account manager?
Unity添加程序集引用
Use of the printer
实时爬虫实例讲解
U disk cannot be displayed on computer
一个英文字母,一个中文各占多少字节
Baidu IP query