千家信息网

NGUIUILabel 底层实现原理是什么

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,本篇文章给大家分享的是有关NGUIUILabel 底层实现原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。这个代码放在草稿箱已经
千家信息网最后更新 2025年01月24日NGUIUILabel 底层实现原理是什么

本篇文章给大家分享的是有关NGUIUILabel 底层实现原理是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

这个代码放在草稿箱已经N久了,一直没时间来写写发布,因为我想从底层去实现一个图文混排的功能,所以就第一步先尝试去了解一下NGUI UILabel的底层实现方式。终于剥离了大部分UILabel的代码,找到了最终的动态文字的具体实现方式,具体的代码就贴在下面了,我就不详细叙述了,我这人一直以来都不太喜欢敲文字,文笔太烂,我更喜欢用代码说话。

大概都实现思路:通过动态字体库获取文字都顶点、UV、颜色信息,然后通过Mesh显示出来。具体的请看代码吧。

通过对UILabel都学习,图文混排都实现可以通过我们处理顶点来解决,其实新方案都图文混排功能我已经放在草稿里了,等有时间再整理发布。

using UnityEngine;using System.Collections;public class Label : MonoBehaviour{        public Font trueTypeFont;    int finalSize = 120;    BetterList mColors = new BetterList();    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 verts = new BetterList();        BetterList uvs = new BetterList();        BetterList cols = new BetterList();        Print("XA", verts, uvs, cols);        mFilter = gameObject.GetComponent();        if (mFilter == null) mFilter = gameObject.AddComponent();        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();        if (mRenderer == null) mRenderer = gameObject.AddComponent();        mRenderer.enabled = true;        mRenderer.material = material;    }    ///     ///     ///     /// 顶点数 8     /// 三角形顶点数 12    ///     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);    }    ///     /// Get the specified glyph.    ///     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 verts, BetterList uvs, BetterList 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 底层实现原理是什么,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

0