UGUI源码:

https://bitbucket.org/Unity-Technologies/ui/downloads/?tab=tags

首先下载一份UGUI源码,这里我下载的版本是5.3.2f1。然后找到Text.cs,里面有方法OnPopulateMesh,这个方法会修改文字的顶点。而图文混排,涉及到顶点数据的修改。因此,我们的重点就是对这个方法进行修改,这里给出一个最简单的重写版本,它和普通的text是一样的。Text的渲染过程是由TextGenerator产生顶点数据,配合字体产生的贴图最终显示在屏幕上。

 using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Text;
using UnityEngine.EventSystems;
using System;
using UnityEngine;
using UnityEngine.UI; //下划线<material=underline c=#ffffff h=1 n=*** p=***>blablabla...</material>
public class RichTextTest : Text { private FontData fontData = FontData.defaultFontData; protected RichTextTest()
{
fontData = typeof(Text).GetField("m_FontData", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(this) as FontData;
} readonly UIVertex[] m_TempVerts = new UIVertex[];
protected override void OnPopulateMesh(VertexHelper toFill)
{
if (font == null)
return; // We don't care if we the font Texture changes while we are doing our Update.
// The end result of cachedTextGenerator will be valid for this instance.
// Otherwise we can get issues like Case 619238.
m_DisableFontTextureRebuiltCallback = true; Vector2 extents = rectTransform.rect.size; var settings = GetGenerationSettings(extents);
cachedTextGenerator.Populate(text, settings); Rect inputRect = rectTransform.rect; // get the text alignment anchor point for the text in local space
Vector2 textAnchorPivot = GetTextAnchorPivot(fontData.alignment);
Vector2 refPoint = Vector2.zero;
refPoint.x = Mathf.Lerp(inputRect.xMin, inputRect.xMax, textAnchorPivot.x);
refPoint.y = Mathf.Lerp(inputRect.yMin, inputRect.yMax, textAnchorPivot.y); // Determine fraction of pixel to offset text mesh.
Vector2 roundingOffset = PixelAdjustPoint(refPoint) - refPoint; // Apply the offset to the vertices
IList<UIVertex> verts = cachedTextGenerator.verts;
float unitsPerPixel = / pixelsPerUnit;
//Last 4 verts are always a new line...
int vertCount = verts.Count - ; toFill.Clear();
if (roundingOffset != Vector2.zero)
{
for (int i = ; i < vertCount; ++i)
{
int tempVertsIndex = i & ;
m_TempVerts[tempVertsIndex] = verts[i];
m_TempVerts[tempVertsIndex].position *= unitsPerPixel;
m_TempVerts[tempVertsIndex].position.x += roundingOffset.x;
m_TempVerts[tempVertsIndex].position.y += roundingOffset.y;
if (tempVertsIndex == )
toFill.AddUIVertexQuad(m_TempVerts);
}
}
else
{
for (int i = ; i < vertCount; ++i)
{
int tempVertsIndex = i & ;
m_TempVerts[tempVertsIndex] = verts[i];
m_TempVerts[tempVertsIndex].position *= unitsPerPixel;
if (tempVertsIndex == )
toFill.AddUIVertexQuad(m_TempVerts);
}
}
m_DisableFontTextureRebuiltCallback = false;
}
}

分析一下上面的代码是怎么实现的:

首先,复制OnPopulateMesh这个方法,发现需要m_TempVerts这个变量,这个变量其实充当临时变量的作用,因此直接复制过来即可。然后提示需要m_FontData这个变量,这个变量是FontData类型的,因此跳到FontData.cs,发现FontData这个东西几乎就是Text在Inspector面板上的东西,但是m_FontData是私有的,这里可以通过反射去获取这个私有变量,又因为序列化的原因,不能同名,所以这里使用变量名fontData。

内部源码分析:

1.unitsPerPixel

意思为每像素单位,即一个像素占几个unity单位。因此可以推出这个cachedTextGenerator.verts是像素单位(cachedTextGenerator.verts赋值给m_TempVerts,然后再做乘法)。那么这个变量的作用是什么呢?可以通过改变Game视图的分辨率,然后打印下,发现随分辨率变化,这个值也在变化,不过文字在矩形框的位置还是不变的,因此可以推测这个是用于自适应的。

2.m_TempVerts

在Text控件中赋值2个字,然后在循环中添加代码:Debug.LogWarning(i + "_" + tempVertsIndex + "_" + m_TempVerts[tempVertsIndex].position);,结果如下图。

可以看到,1个字符有4个顶点,而顶点的排列如下:

3.顶点的生成

通过OnPopulateMesh这个方法可以看到,生成顶点的方法如下。不过生成的顶点要去掉最后四个点,可以打印一下看看最后四个点的位置。至于为什么要这样处理呢,因为TextGenerator这个类是在UnityEngine命名空间下的,所以我们就不得而知了...

Vector2 extents = rectTransform.rect.size;
var settings = GetGenerationSettings(extents);
cachedTextGenerator.Populate(text, settings);
IList<UIVertex> verts = cachedTextGenerator.verts;
//Last 4 verts are always a new line...
int vertCount = verts.Count - ;

4.获取字符串的长度

TextGenerator类中的GetPreferredWidth方法可以获取字符串的长度。具体使用方式可以看Text类中的preferredWidth,这个方法得到的宽度同样是像素单位的,因此要做转换处理。

[UGUI]图文混排(二):Text源码分析的更多相关文章

  1. Unity UGUI图文混排源码(二)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

  2. Unity UGUI图文混排源码(一)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

  3. Unity UGUI图文混排源码(三) -- 动态表情

    这里是根据图文混排源码(二)进一步修改的,其他链接也不贴了,就贴一个链接就好了,第一次看这文章的同学可以先去看看其他几篇文章 Unity UGUI图文混排源码(二):http://blog.csdn. ...

  4. Unity琐碎(3) UGUI 图文混排解决方案和优化

    感觉使用Unity之后总能看到各种各样解决混排的方案,只能说明Unity不够体恤下情啊.这篇文章主要讲一下个人在使用过程中方案选择和优化过程,已做记录.顺便提下,开源很多意味着坑,还是要开实际需求. ...

  5. Spring PropertyResolver 占位符解析(二)源码分析

    Spring PropertyResolver 占位符解析(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) ...

  6. Spring Environment(二)源码分析

    Spring Environment(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring Envi ...

  7. Spring 循环引用(二)源码分析

    Spring 循环引用(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) Spring 循环引用相关文章: & ...

  8. Spring Boot REST(二)源码分析

    Spring Boot REST(二)源码分析 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) SpringBoot RE ...

  9. Alink漫谈(二十二) :源码分析之聚类评估

    Alink漫谈(二十二) :源码分析之聚类评估 目录 Alink漫谈(二十二) :源码分析之聚类评估 0x00 摘要 0x01 背景概念 1.1 什么是聚类 1.2 聚类分析的方法 1.3 聚类评估 ...

随机推荐

  1. ajaxFileupload 多文件上传

    ajaxFileupload 多文件上传 修改前的代码: var oldElement = jQuery('#' + fileElementId); var newElement = jQuery(o ...

  2. kindeditor在线编辑器的使用心得

    1. 如何声明引用? <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...

  3. Ribbon 常用配置

    配置参数 默认值 说明 <client>.<namespace>.listOfServers 配置服务器列表 <client>.<namespace>. ...

  4. Google program AB程序的基本理解

    这个是2017年机器人项目中涉及到的一点东西,虽然没有派上什么大用场,但是还是有必要在这里记录一下! 1. 初始化Bot A. 配置各种路径,例如aiml,aimlif,config,set,map等 ...

  5. 源代码安装Apache、Mysql、PHP

    源代码软件的优点:     获得最新版,能及时修复bug:     能自行修改和定制: 源代码打包形式:     .tar.gz和.tar.bz2格式居多: 完整性校验:     md5sum校验工具 ...

  6. Fiddler的学习之路

    Fiddler是位于客户端和服务器端的HTTP代理,也是目前最常用的http抓包工具之一 . 它能够记录客户端和服务器之间的所有 HTTP请求,可以针对特定的HTTP请求,分析请求数据.设置断点.调试 ...

  7. axios 上传图片

    let data = new FormData(); for (var i = 0; i < files.length; i++) { let file = files.item(i); dat ...

  8. DS二叉树--叶子数量

    题目描述 计算一颗二叉树包含的叶子结点数量. 提示:叶子是指它的左右孩子为空. 建树方法采用“先序遍历+空树用0表示”的方法,即给定一颗二叉树的先序遍历的结果为AB0C00D00,其中空节点用字符‘0 ...

  9. JDK类集框架实验(ArrayList,LinkedList,TreeSet,HashSet,TreeMap,HashMap)

        ArrayList import java.util.ArrayList; public class C8_3 { public static void main(String[] args) ...

  10. [转][C#]Environment 类

    当执行 Environment.GetEnvironmentVariables() 时,可以得到以下结果(受所安装软件影响,每台电脑都不一样) Count = ["SystemDrive&q ...