中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

NGUIUILabel 底層實現原理是什么

發布時間:2021-11-15 16:14:24 來源:億速云 閱讀:136 作者:柒染 欄目:大數據

本篇文章給大家分享的是有關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 底層實現原理是什么,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

太和县| 始兴县| 新民市| 呈贡县| 兰坪| 万山特区| 垦利县| 肇源县| 乐都县| 定结县| 望江县| 米脂县| 鹤山市| 花莲市| 荆门市| 本溪| 梁山县| 永登县| 成都市| 涞水县| 松潘县| 富平县| 巨鹿县| 嵊泗县| 连城县| 郯城县| 舞钢市| 祁阳县| 昭平县| 辉县市| 宁都县| 东港市| 寿阳县| 游戏| 张家港市| 仙居县| 金昌市| 扶绥县| 和顺县| 新郑市| 吐鲁番市|