本篇文章给大家分享的是有关NGUIUILabel 底层实现原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。
这个代码放在草稿箱已经N久了,一直没时间来写写发布,因为我想从底层去实现一个图文混排的功能,所以就第一步先尝试去了解一下NGUI UILabel的底层实现方式。终于剥离了大部分UILabel的代码,找到了最终的动态文字的具体实现方式,具体的代码就贴在下面了,我就不详细叙述了,我这人一直以来都不太喜欢敲文字,文笔太烂,我更喜欢用代码说话。
大概都实现思路:通过动态字体库获取文字都顶点、UV、颜色信息,然后通过Mesh显示出来。具体的请看代码吧。
通过对UILabel都学习,图文混排都实现可以通过我们处理顶点来解决,其实新方案都图文混排功能我已经放在草稿里了,等有时间再整理发布。
using UnityEngine;
using System.Collections;
public class Label : MonoBehaviour
{
public Font trueTypeFont;
int finalSize = 120;
BetterList<Color> mColors = new BetterList<Color>();
public Color tint = Color.white;
public Color gradientBottom = Color.white;
public Color gradientTop = Color.white;
public GlyphInfo glyph = new GlyphInfo();
CharacterInfo mTempChar;
MeshFilter mFilter;
MeshRenderer mRenderer;
void Start()
{
Run();
}
private float _x = 0;
private void Run()
{
BetterList<Vector3> verts = new BetterList<Vector3>();
BetterList<Vector2> uvs = new BetterList<Vector2>();
BetterList<Color32> cols = new BetterList<Color32>();
Print("XA", verts, uvs, cols);
mFilter = gameObject.GetComponent<MeshFilter>();
if (mFilter == null) mFilter = gameObject.AddComponent<MeshFilter>();
Mesh mesh = new Mesh();
mesh.name = "Mesh";
Vector3[] vec = new Vector3[8];
CharacterInfo mTempChar = new CharacterInfo();
if (trueTypeFont.GetCharacterInfo('X', out mTempChar, 120, FontStyle.Normal))
{
Vector3[] v = GetVer(mTempChar);
v.CopyTo(vec, 0);
}
if (trueTypeFont.GetCharacterInfo('A', out mTempChar, 120, FontStyle.Normal))
{
Vector3[] v = GetVer(mTempChar);
v.CopyTo(vec, 4);
}
mesh.vertices = vec;
//mesh.vertices = verts.ToArray();
mesh.uv = uvs.ToArray();
//mesh.colors32 = cols.ToArray();
//mesh.vertices = new Vector3[4] { new Vector3(0.0f, -15.2f, 0.0f), new Vector3(0.0f, 71.8f, 0.0f), new Vector3(74.0f, 71.8f, 0.0f), new Vector3(74.0f, -15.2f, 0.0f) };
//mesh.uv = new Vector2[4] { new Vector2(0f, 0.3f), new Vector2(0f, 0f), new Vector2(0.3f, 0f), new Vector2(0.3f, 0.3f) };
mesh.colors32 = new Color32[8] { Color.red, Color.yellow, Color.blue, Color.green, Color.red, Color.yellow, Color.blue, Color.green };
mesh.triangles = GenerateCachedIndexBuffer(8, 12);
mesh.RecalculateBounds();
mFilter.mesh = mesh;
mRenderer = gameObject.GetComponent<MeshRenderer>();
if (mRenderer == null) mRenderer = gameObject.AddComponent<MeshRenderer>();
mRenderer.enabled = true;
mRenderer.material = material;
}
/// <summary>
///
/// </summary>
/// <param name="vertexCount">顶点数 8 </param>
/// <param name="indexCount">三角形顶点数 12</param>
/// <returns></returns>
int[] GenerateCachedIndexBuffer(int vertexCount, int indexCount)
{
int[] rv = new int[indexCount];
int index = 0;
for (int i = 0; i < vertexCount; i += 4)
{
rv[index++] = i;
rv[index++] = i + 1;
rv[index++] = i + 2;
rv[index++] = i + 2;
rv[index++] = i + 3;
rv[index++] = i;
}
return rv;
}
public Vector3[] GetVer(CharacterInfo info)
{
Vector3[] vects = new Vector3[4];
vects[0] = new Vector3(_x + info.vert.x, info.vert.height);
vects[1] = new Vector3(_x + info.vert.x, info.vert.y);
vects[2] = new Vector3(_x + info.vert.width, info.vert.y);
vects[3] = new Vector3(_x + info.vert.width, info.vert.height);
_x += info.vert.width;
return vects;
}
public Material material
{
get
{
return trueTypeFont.material;
}
}
public void Prepare(string text)
{
if (trueTypeFont != null)
trueTypeFont.RequestCharactersInTexture(text, finalSize, FontStyle.Normal);
}
/// <summary>
/// Get the specified glyph.
/// </summary>
public GlyphInfo GetGlyph(int ch, int prev)
{
if (trueTypeFont.GetCharacterInfo((char)ch, out mTempChar, finalSize, FontStyle.Normal))
{
glyph.v0.x = mTempChar.vert.xMin;
glyph.v1.x = glyph.v0.x + mTempChar.vert.width;
glyph.v0.y = mTempChar.vert.yMax;
glyph.v1.y = glyph.v0.y - mTempChar.vert.height;
glyph.u0.x = mTempChar.uv.xMin;
glyph.u0.y = mTempChar.uv.yMin;
glyph.u1.x = mTempChar.uv.xMax;
glyph.u1.y = mTempChar.uv.yMax;
glyph.advance = mTempChar.width;
glyph.channel = 0;
glyph.rotatedUVs = mTempChar.flipped;
float pd = 1;
if (pd != 1f)
{
glyph.v0 *= pd;
glyph.v1 *= pd;
glyph.advance *= pd;
}
glyph.advance = Mathf.Round(glyph.advance);
return glyph;
}
return null;
}
public void Print(string text, BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
{
Prepare(text);
// Start with the white tint
mColors.Add(Color.white);
int ch = 0, prev = 0;
float x = 0f, y = 0f;
float sizeF = finalSize;
Color gb = tint * gradientBottom;
Color gt = tint * gradientTop;
Color32 uc = tint;
int textLength = text.Length;
float sizePD = sizeF * 1f;
int subscriptMode = 0; // 0 = normal, 1 = subscript, 2 = superscript
bool bold = false;
bool italic = false;
const float sizeShrinkage = 0.75f;
float v0x;
float v1x;
float v1y;
float v0y;
float prevX = 0;
for (int i = 0; i < textLength; ++i)
{
ch = text[i];
prevX = x;
GlyphInfo glyph = GetGlyph(ch, prev);
if (glyph == null) continue;
prev = ch;
float y0 = glyph.v0.y;
float y1 = glyph.v1.y;
v0x = glyph.v0.x + x;
v0y = glyph.v0.y - y;
v1x = glyph.v1.x + x;
v1y = glyph.v1.y - y;
float w = glyph.advance;
// Advance the position
x += (subscriptMode == 0) ? glyph.advance :
glyph.advance * sizeShrinkage;
// No need to continue if this is a space character
if (ch == ' ') continue;
// Texture coordinates
if (uvs != null)
{
for (int j = 0, jmax = (bold ? 4 : 1); j < jmax; ++j)
{
uvs.Add(glyph.u0);
uvs.Add(new Vector2(glyph.u0.x, glyph.u1.y));
uvs.Add(glyph.u1);
uvs.Add(new Vector2(glyph.u1.x, glyph.u0.y));
}
}
// Vertex colors
if (cols != null)
{
for (int j = 0, jmax = (bold ? 16 : 4); j < jmax; ++j)
cols.Add(uc);
}
// Bold and italic contributed by Rudy Pangestu.
verts.Add(new Vector3(v0x, v0y));
verts.Add(new Vector3(v0x, v1y));
verts.Add(new Vector3(v1x, v1y));
verts.Add(new Vector3(v1x, v0y));
}
mColors.Clear();
}
}
public class GlyphInfo
{
public Vector2 v0;
public Vector2 v1;
public Vector2 u0;
public Vector2 u1;
public float advance = 0f;
public int channel = 0;
public bool rotatedUVs = false;
}
以上就是NGUIUILabel 底层实现原理是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4589456/blog/4585000