美文网首页
NGUI-UIBasicSprite/UISprite/UITe

NGUI-UIBasicSprite/UISprite/UITe

作者: 白桦叶 | 来源:发表于2019-10-28 17:52 被阅读0次

    1. 整体类图

    NGUI_Class.png

    从类图可以看出,UISprite和UITexture都是继承UIBasicSprite,UIBasicSprite则继承UIWidget。

    2. UIBasicSprite

    2.1 作用
    主要提供图片类型属性,flip属性及提供统一填充几何信息的方法(Fill)。
    2.2 图片类型

    public enum Type
    {
            Simple,
            Sliced,
            Tiled,
            Filled,
            Advanced,
    }
    

    每一种Type的解释及适用场景:

    Simple:标准的Sprite,自适应大小
    Sliced:九宫格切片,创建固定边框控件的最佳选择。边框固定,图片中间做拉伸(缩放),如角色头像,按钮背景
    Tiled:平铺,一个Sprite缩放填充整个区域,如背景平铺
    Filed:每个Sprite有一个单独的参数(file Amout)来控制哪些是可见的,用来制作技能CD冷却时间或进度条
    Advanced:高级的,自定义左右上下中的Sprite Type

    关于Type的具体信息和示例可以参考这篇文章

    2.3 Flip类型

    public enum Flip
    {
            Nothing,
            Horizontally,
            Vertically,
            Both,
    }
    

    2.4 Fill方法
    Fill方法根据图片类型调用SimpleFill/SlicedFill/FilledFill/TiledFill/AdvancedFill方法填充几何信息

    protected void Fill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols, Rect outer, Rect inner)
        {
            mOuterUV = outer;
            mInnerUV = inner;
    
            switch (type)
            {
                case Type.Simple:
                SimpleFill(verts, uvs, cols);
                break;
    
                case Type.Sliced:
                SlicedFill(verts, uvs, cols);
                break;
    
                case Type.Filled:
                FilledFill(verts, uvs, cols);
                break;
    
                case Type.Tiled:
                TiledFill(verts, uvs, cols);
                break;
    
                case Type.Advanced:
                AdvancedFill(verts, uvs, cols);
                break;
            }
        }
    

    2.5 SimpleFill
    几何信息按照左下 左上 右上 右下的顺序依次填入

    void SimpleFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            Vector4 v = drawingDimensions;
            Vector4 u = drawingUVs;
            Color32 c = drawingColor;
    
            verts.Add(new Vector3(v.x, v.y));
            verts.Add(new Vector3(v.x, v.w));
            verts.Add(new Vector3(v.z, v.w));
            verts.Add(new Vector3(v.z, v.y));
    
            uvs.Add(new Vector2(u.x, u.y));
            uvs.Add(new Vector2(u.x, u.w));
            uvs.Add(new Vector2(u.z, u.w));
            uvs.Add(new Vector2(u.z, u.y));
    
            cols.Add(c);
            cols.Add(c);
            cols.Add(c);
            cols.Add(c);
        }
    

    2.6 SlicedFill

    • 当边界border等于Vector4.zero的时候按照Simple类型处理
    • 由于Slice分成外矩形和内矩形,将外矩形和内矩形的左下,右上总共4个顶点/UV分配到mTempPos和mTempUVs临时缓存
    • Sliced的中文意思为九宫格,填充几何信息的时候也是将图片分成9块进行的,按照以下规则
      3 6 9
      2 5 8
      1 4 7
    void SlicedFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            Vector4 br = border * pixelSize;
            
            if (br.x == 0f && br.y == 0f && br.z == 0f && br.w == 0f)
            {
                SimpleFill(verts, uvs, cols);
                return;
            }
    
            Color32 c = drawingColor;
            Vector4 v = drawingDimensions;
    
            mTempPos[0].x = v.x;
            mTempPos[0].y = v.y;
            mTempPos[3].x = v.z;
            mTempPos[3].y = v.w;
    
            if (mFlip == Flip.Horizontally || mFlip == Flip.Both)
            {
                mTempPos[1].x = mTempPos[0].x + br.z;
                mTempPos[2].x = mTempPos[3].x - br.x;
    
                mTempUVs[3].x = mOuterUV.xMin;
                mTempUVs[2].x = mInnerUV.xMin;
                mTempUVs[1].x = mInnerUV.xMax;
                mTempUVs[0].x = mOuterUV.xMax;
            }
            else
            {
                mTempPos[1].x = mTempPos[0].x + br.x;
                mTempPos[2].x = mTempPos[3].x - br.z;
    
                mTempUVs[0].x = mOuterUV.xMin;
                mTempUVs[1].x = mInnerUV.xMin;
                mTempUVs[2].x = mInnerUV.xMax;
                mTempUVs[3].x = mOuterUV.xMax;
            }
    
            if (mFlip == Flip.Vertically || mFlip == Flip.Both)
            {
                mTempPos[1].y = mTempPos[0].y + br.w;
                mTempPos[2].y = mTempPos[3].y - br.y;
    
                mTempUVs[3].y = mOuterUV.yMin;
                mTempUVs[2].y = mInnerUV.yMin;
                mTempUVs[1].y = mInnerUV.yMax;
                mTempUVs[0].y = mOuterUV.yMax;
            }
            else
            {
                mTempPos[1].y = mTempPos[0].y + br.y;
                mTempPos[2].y = mTempPos[3].y - br.w;
    
                mTempUVs[0].y = mOuterUV.yMin;
                mTempUVs[1].y = mInnerUV.yMin;
                mTempUVs[2].y = mInnerUV.yMax;
                mTempUVs[3].y = mOuterUV.yMax;
            }
    
            for (int x = 0; x < 3; ++x)
            {
                int x2 = x + 1;
    
                for (int y = 0; y < 3; ++y)
                {
                    if (centerType == AdvancedType.Invisible && x == 1 && y == 1) continue;
    
                    int y2 = y + 1;
    
                    verts.Add(new Vector3(mTempPos[x].x, mTempPos[y].y));
                    verts.Add(new Vector3(mTempPos[x].x, mTempPos[y2].y));
                    verts.Add(new Vector3(mTempPos[x2].x, mTempPos[y2].y));
                    verts.Add(new Vector3(mTempPos[x2].x, mTempPos[y].y));
    
                    uvs.Add(new Vector2(mTempUVs[x].x, mTempUVs[y].y));
                    uvs.Add(new Vector2(mTempUVs[x].x, mTempUVs[y2].y));
                    uvs.Add(new Vector2(mTempUVs[x2].x, mTempUVs[y2].y));
                    uvs.Add(new Vector2(mTempUVs[x2].x, mTempUVs[y].y));
    
                    cols.Add(c);
                    cols.Add(c);
                    cols.Add(c);
                    cols.Add(c);
                }
            }
        }
    

    2.7 TiledFill

    • 计算对应纹理贴图的大小
    • UV进行Flip处理
    • 按照从左到右,从下到上不断添加平铺纹理的几何信息,限制显示区域(对顶点和UV范围限制)
    void TiledFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            Texture tex = mainTexture;
            if (tex == null) return;
    
            Vector2 size = new Vector2(mInnerUV.width * tex.width, mInnerUV.height * tex.height);
            size *= pixelSize;
            if (tex == null || size.x < 2f || size.y < 2f) return;
    
            Color32 c = drawingColor;
            Vector4 v = drawingDimensions;
            Vector4 u;
    
            if (mFlip == Flip.Horizontally || mFlip == Flip.Both)
            {
                u.x = mInnerUV.xMax;
                u.z = mInnerUV.xMin;
            }
            else
            {
                u.x = mInnerUV.xMin;
                u.z = mInnerUV.xMax;
            }
    
            if (mFlip == Flip.Vertically || mFlip == Flip.Both)
            {
                u.y = mInnerUV.yMax;
                u.w = mInnerUV.yMin;
            }
            else
            {
                u.y = mInnerUV.yMin;
                u.w = mInnerUV.yMax;
            }
    
            float x0 = v.x;
            float y0 = v.y;
    
            float u0 = u.x;
            float v0 = u.y;
    
            while (y0 < v.w)
            {
                x0 = v.x;
                float y1 = y0 + size.y;
                float v1 = u.w;
    
                if (y1 > v.w)
                {
                    v1 = Mathf.Lerp(u.y, u.w, (v.w - y0) / size.y);
                    y1 = v.w;
                }
    
                while (x0 < v.z)
                {
                    float x1 = x0 + size.x;
                    float u1 = u.z;
    
                    if (x1 > v.z)
                    {
                        u1 = Mathf.Lerp(u.x, u.z, (v.z - x0) / size.x);
                        x1 = v.z;
                    }
    
                    verts.Add(new Vector3(x0, y0));
                    verts.Add(new Vector3(x0, y1));
                    verts.Add(new Vector3(x1, y1));
                    verts.Add(new Vector3(x1, y0));
    
                    uvs.Add(new Vector2(u0, v0));
                    uvs.Add(new Vector2(u0, v1));
                    uvs.Add(new Vector2(u1, v1));
                    uvs.Add(new Vector2(u1, v0));
    
                    cols.Add(c);
                    cols.Add(c);
                    cols.Add(c);
                    cols.Add(c);
    
                    x0 += size.x;
                }
                y0 += size.y;
            }
        }
    

    2.8 FilledFill
    2.8.1 FillDirection

    public enum FillDirection
    {
            Horizontal,
            Vertical,
            Radial90,
            Radial180,
            Radial360,
    }
    
    • 主要由mfillDirection(填充方式)、mfillAmount(填充量)和mInvert(是否反转)来控制填充的效果
    • 对于FillDirection.Horizontal或者FillDirection.Vertical的情况,根据mfillAmount重新计算顶点坐标和UV坐标并填入即可
    • 对于FillDirection其他3种类型,但都用到RadialCut函数,里面涉及到一些三角函数的运算。Radial90画1个矩形即可,Radial180需要分左右画2个矩形,而Radial360则需要分四块画4个矩形。
    void FilledFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            if (mFillAmount < 0.001f) return;
    
            Vector4 v = drawingDimensions;
            Vector4 u = drawingUVs;
            Color32 c = drawingColor;
    
            // Horizontal and vertical filled sprites are simple -- just end the sprite prematurely
            if (mFillDirection == FillDirection.Horizontal || mFillDirection == FillDirection.Vertical)
            {
                if (mFillDirection == FillDirection.Horizontal)
                {
                    float fill = (u.z - u.x) * mFillAmount;
    
                    if (mInvert)
                    {
                        v.x = v.z - (v.z - v.x) * mFillAmount;
                        u.x = u.z - fill;
                    }
                    else
                    {
                        v.z = v.x + (v.z - v.x) * mFillAmount;
                        u.z = u.x + fill;
                    }
                }
                else if (mFillDirection == FillDirection.Vertical)
                {
                    float fill = (u.w - u.y) * mFillAmount;
    
                    if (mInvert)
                    {
                        v.y = v.w - (v.w - v.y) * mFillAmount;
                        u.y = u.w - fill;
                    }
                    else
                    {
                        v.w = v.y + (v.w - v.y) * mFillAmount;
                        u.w = u.y + fill;
                    }
                }
            }
    
            mTempPos[0] = new Vector2(v.x, v.y);
            mTempPos[1] = new Vector2(v.x, v.w);
            mTempPos[2] = new Vector2(v.z, v.w);
            mTempPos[3] = new Vector2(v.z, v.y);
    
            mTempUVs[0] = new Vector2(u.x, u.y);
            mTempUVs[1] = new Vector2(u.x, u.w);
            mTempUVs[2] = new Vector2(u.z, u.w);
            mTempUVs[3] = new Vector2(u.z, u.y);
    
            if (mFillAmount < 1f)
            {
                if (mFillDirection == FillDirection.Radial90)
                {
                    if (RadialCut(mTempPos, mTempUVs, mFillAmount, mInvert, 0))
                    {
                        for (int i = 0; i < 4; ++i)
                        {
                            verts.Add(mTempPos[i]);
                            uvs.Add(mTempUVs[i]);
                            cols.Add(c);
                        }
                    }
                    return;
                }
    
                if (mFillDirection == FillDirection.Radial180)
                {
                    for (int side = 0; side < 2; ++side)
                    {
                        float fx0, fx1, fy0, fy1;
    
                        fy0 = 0f;
                        fy1 = 1f;
    
                        if (side == 0) { fx0 = 0f; fx1 = 0.5f; }
                        else { fx0 = 0.5f; fx1 = 1f; }
    
                        mTempPos[0].x = Mathf.Lerp(v.x, v.z, fx0);
                        mTempPos[1].x = mTempPos[0].x;
                        mTempPos[2].x = Mathf.Lerp(v.x, v.z, fx1);
                        mTempPos[3].x = mTempPos[2].x;
    
                        mTempPos[0].y = Mathf.Lerp(v.y, v.w, fy0);
                        mTempPos[1].y = Mathf.Lerp(v.y, v.w, fy1);
                        mTempPos[2].y = mTempPos[1].y;
                        mTempPos[3].y = mTempPos[0].y;
    
                        mTempUVs[0].x = Mathf.Lerp(u.x, u.z, fx0);
                        mTempUVs[1].x = mTempUVs[0].x;
                        mTempUVs[2].x = Mathf.Lerp(u.x, u.z, fx1);
                        mTempUVs[3].x = mTempUVs[2].x;
    
                        mTempUVs[0].y = Mathf.Lerp(u.y, u.w, fy0);
                        mTempUVs[1].y = Mathf.Lerp(u.y, u.w, fy1);
                        mTempUVs[2].y = mTempUVs[1].y;
                        mTempUVs[3].y = mTempUVs[0].y;
    
                        float val = !mInvert ? fillAmount * 2f - side : mFillAmount * 2f - (1 - side);
    
                        if (RadialCut(mTempPos, mTempUVs, Mathf.Clamp01(val), !mInvert, NGUIMath.RepeatIndex(side + 3, 4)))
                        {
                            for (int i = 0; i < 4; ++i)
                            {
                                verts.Add(mTempPos[i]);
                                uvs.Add(mTempUVs[i]);
                                cols.Add(c);
                            }
                        }
                    }
                    return;
                }
    
                if (mFillDirection == FillDirection.Radial360)
                {
                    for (int corner = 0; corner < 4; ++corner)
                    {
                        float fx0, fx1, fy0, fy1;
    
                        if (corner < 2) { fx0 = 0f; fx1 = 0.5f; }
                        else { fx0 = 0.5f; fx1 = 1f; }
    
                        if (corner == 0 || corner == 3) { fy0 = 0f; fy1 = 0.5f; }
                        else { fy0 = 0.5f; fy1 = 1f; }
    
                        mTempPos[0].x = Mathf.Lerp(v.x, v.z, fx0);
                        mTempPos[1].x = mTempPos[0].x;
                        mTempPos[2].x = Mathf.Lerp(v.x, v.z, fx1);
                        mTempPos[3].x = mTempPos[2].x;
    
                        mTempPos[0].y = Mathf.Lerp(v.y, v.w, fy0);
                        mTempPos[1].y = Mathf.Lerp(v.y, v.w, fy1);
                        mTempPos[2].y = mTempPos[1].y;
                        mTempPos[3].y = mTempPos[0].y;
    
                        mTempUVs[0].x = Mathf.Lerp(u.x, u.z, fx0);
                        mTempUVs[1].x = mTempUVs[0].x;
                        mTempUVs[2].x = Mathf.Lerp(u.x, u.z, fx1);
                        mTempUVs[3].x = mTempUVs[2].x;
    
                        mTempUVs[0].y = Mathf.Lerp(u.y, u.w, fy0);
                        mTempUVs[1].y = Mathf.Lerp(u.y, u.w, fy1);
                        mTempUVs[2].y = mTempUVs[1].y;
                        mTempUVs[3].y = mTempUVs[0].y;
    
                        float val = mInvert ?
                            mFillAmount * 4f - NGUIMath.RepeatIndex(corner + 2, 4) :
                            mFillAmount * 4f - (3 - NGUIMath.RepeatIndex(corner + 2, 4));
    
                        if (RadialCut(mTempPos, mTempUVs, Mathf.Clamp01(val), mInvert, NGUIMath.RepeatIndex(corner + 2, 4)))
                        {
                            for (int i = 0; i < 4; ++i)
                            {
                                verts.Add(mTempPos[i]);
                                uvs.Add(mTempUVs[i]);
                                cols.Add(c);
                            }
                        }
                    }
                    return;
                }
            }
    
            // Fill the buffer with the quad for the sprite
            for (int i = 0; i < 4; ++i)
            {
                verts.Add(mTempPos[i]);
                uvs.Add(mTempUVs[i]);
                cols.Add(c);
            }
        }
    

    2.9 AdvancedFill

    public enum AdvancedType
    {
            Invisible,
            Sliced,
            Tiled,
    }
    

    根据border边界将图片区域分成9块,每块可以独立设置AdvancedType图片类型,然后根据每块的类型进行几何信息填充

    void AdvancedFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            Texture tex = mainTexture;
            if (tex == null) return;
    
            Vector4 br = border * pixelSize;
    
            if (br.x == 0f && br.y == 0f && br.z == 0f && br.w == 0f)
            {
                SimpleFill(verts, uvs, cols);
                return;
            }
    
            Color32 c = drawingColor;
            Vector4 v = drawingDimensions;
            Vector2 tileSize = new Vector2(mInnerUV.width * tex.width, mInnerUV.height * tex.height);
            tileSize *= pixelSize;
    
            if (tileSize.x < 1f) tileSize.x = 1f;
            if (tileSize.y < 1f) tileSize.y = 1f;
    
            mTempPos[0].x = v.x;
            mTempPos[0].y = v.y;
            mTempPos[3].x = v.z;
            mTempPos[3].y = v.w;
    
            if (mFlip == Flip.Horizontally || mFlip == Flip.Both)
            {
                mTempPos[1].x = mTempPos[0].x + br.z;
                mTempPos[2].x = mTempPos[3].x - br.x;
    
                mTempUVs[3].x = mOuterUV.xMin;
                mTempUVs[2].x = mInnerUV.xMin;
                mTempUVs[1].x = mInnerUV.xMax;
                mTempUVs[0].x = mOuterUV.xMax;
            }
            else
            {
                mTempPos[1].x = mTempPos[0].x + br.x;
                mTempPos[2].x = mTempPos[3].x - br.z;
    
                mTempUVs[0].x = mOuterUV.xMin;
                mTempUVs[1].x = mInnerUV.xMin;
                mTempUVs[2].x = mInnerUV.xMax;
                mTempUVs[3].x = mOuterUV.xMax;
            }
    
            if (mFlip == Flip.Vertically || mFlip == Flip.Both)
            {
                mTempPos[1].y = mTempPos[0].y + br.w;
                mTempPos[2].y = mTempPos[3].y - br.y;
    
                mTempUVs[3].y = mOuterUV.yMin;
                mTempUVs[2].y = mInnerUV.yMin;
                mTempUVs[1].y = mInnerUV.yMax;
                mTempUVs[0].y = mOuterUV.yMax;
            }
            else
            {
                mTempPos[1].y = mTempPos[0].y + br.y;
                mTempPos[2].y = mTempPos[3].y - br.w;
    
                mTempUVs[0].y = mOuterUV.yMin;
                mTempUVs[1].y = mInnerUV.yMin;
                mTempUVs[2].y = mInnerUV.yMax;
                mTempUVs[3].y = mOuterUV.yMax;
            }
    
            for (int x = 0; x < 3; ++x)
            {
                int x2 = x + 1;
    
                for (int y = 0; y < 3; ++y)
                {
                    if (centerType == AdvancedType.Invisible && x == 1 && y == 1) continue;
                    int y2 = y + 1;
    
                    if (x == 1 && y == 1) // Center
                    {
                        if (centerType == AdvancedType.Tiled)
                        {
                            float startPositionX = mTempPos[x].x;
                            float endPositionX = mTempPos[x2].x;
                            float startPositionY = mTempPos[y].y;
                            float endPositionY = mTempPos[y2].y;
                            float textureStartX = mTempUVs[x].x;
                            float textureStartY = mTempUVs[y].y;
                            float tileStartY = startPositionY;
    
                            while (tileStartY < endPositionY)
                            {
                                float tileStartX = startPositionX;
                                float textureEndY = mTempUVs[y2].y;
                                float tileEndY = tileStartY + tileSize.y;
    
                                if (tileEndY > endPositionY)
                                {
                                    textureEndY = Mathf.Lerp(textureStartY, textureEndY, (endPositionY - tileStartY) / tileSize.y);
                                    tileEndY = endPositionY;
                                }
    
                                while (tileStartX < endPositionX)
                                {
                                    float tileEndX = tileStartX + tileSize.x;
                                    float textureEndX = mTempUVs[x2].x;
    
                                    if (tileEndX > endPositionX)
                                    {
                                        textureEndX = Mathf.Lerp(textureStartX, textureEndX, (endPositionX - tileStartX) / tileSize.x);
                                        tileEndX = endPositionX;
                                    }
    
                                    Fill(verts, uvs, cols,
                                        tileStartX, tileEndX,
                                        tileStartY, tileEndY,
                                        textureStartX, textureEndX,
                                        textureStartY, textureEndY, c);
    
                                    tileStartX += tileSize.x;
                                }
                                tileStartY += tileSize.y;
                            }
                        }
                        else if (centerType == AdvancedType.Sliced)
                        {
                            Fill(verts, uvs, cols,
                                mTempPos[x].x, mTempPos[x2].x,
                                mTempPos[y].y, mTempPos[y2].y,
                                mTempUVs[x].x, mTempUVs[x2].x,
                                mTempUVs[y].y, mTempUVs[y2].y, c);
                        }
                    }
                    else if (x == 1) // Top or bottom
                    {
                        if ((y == 0 && bottomType == AdvancedType.Tiled) || (y == 2 && topType == AdvancedType.Tiled))
                        {
                            float startPositionX = mTempPos[x].x;
                            float endPositionX = mTempPos[x2].x;
                            float startPositionY = mTempPos[y].y;
                            float endPositionY = mTempPos[y2].y;
                            float textureStartX = mTempUVs[x].x;
                            float textureStartY = mTempUVs[y].y;
                            float textureEndY = mTempUVs[y2].y;
                            float tileStartX = startPositionX;
    
                            while (tileStartX < endPositionX)
                            {
                                float tileEndX = tileStartX + tileSize.x;
                                float textureEndX = mTempUVs[x2].x;
    
                                if (tileEndX > endPositionX)
                                {
                                    textureEndX = Mathf.Lerp(textureStartX, textureEndX, (endPositionX - tileStartX) / tileSize.x);
                                    tileEndX = endPositionX;
                                }
    
                                Fill(verts, uvs, cols,
                                    tileStartX, tileEndX,
                                    startPositionY, endPositionY,
                                    textureStartX, textureEndX,
                                    textureStartY, textureEndY, c);
    
                                tileStartX += tileSize.x;
                            }
                        }
                        else if ((y == 0 && bottomType != AdvancedType.Invisible) || (y == 2 && topType != AdvancedType.Invisible))
                        {
                            Fill(verts, uvs, cols,
                                mTempPos[x].x, mTempPos[x2].x,
                                mTempPos[y].y, mTempPos[y2].y,
                                mTempUVs[x].x, mTempUVs[x2].x,
                                mTempUVs[y].y, mTempUVs[y2].y, c);
                        }
                    }
                    else if (y == 1) // Left or right
                    {
                        if ((x == 0 && leftType == AdvancedType.Tiled) || (x == 2 && rightType == AdvancedType.Tiled))
                        {
                            float startPositionX = mTempPos[x].x;
                            float endPositionX = mTempPos[x2].x;
                            float startPositionY = mTempPos[y].y;
                            float endPositionY = mTempPos[y2].y;
                            float textureStartX = mTempUVs[x].x;
                            float textureEndX = mTempUVs[x2].x;
                            float textureStartY = mTempUVs[y].y;
                            float tileStartY = startPositionY;
    
                            while (tileStartY < endPositionY)
                            {
                                float textureEndY = mTempUVs[y2].y;
                                float tileEndY = tileStartY + tileSize.y;
    
                                if (tileEndY > endPositionY)
                                {
                                    textureEndY = Mathf.Lerp(textureStartY, textureEndY, (endPositionY - tileStartY) / tileSize.y);
                                    tileEndY = endPositionY;
                                }
    
                                Fill(verts, uvs, cols,
                                    startPositionX, endPositionX,
                                    tileStartY, tileEndY,
                                    textureStartX, textureEndX,
                                    textureStartY, textureEndY, c);
    
                                tileStartY += tileSize.y;
                            }
                        }
                        else if ((x == 0 && leftType != AdvancedType.Invisible) || (x == 2 && rightType != AdvancedType.Invisible))
                        {
                            Fill(verts, uvs, cols,
                                mTempPos[x].x, mTempPos[x2].x,
                                mTempPos[y].y, mTempPos[y2].y,
                                mTempUVs[x].x, mTempUVs[x2].x,
                                mTempUVs[y].y, mTempUVs[y2].y, c);
                        }
                    }
                    else // Corner
                    {
                        if ((y == 0 && bottomType != AdvancedType.Invisible) || (y == 2 && topType != AdvancedType.Invisible) ||
                            (x == 0 && leftType != AdvancedType.Invisible) || (x == 2 && rightType != AdvancedType.Invisible))
                        {
                            Fill(verts, uvs, cols,
                                mTempPos[x].x, mTempPos[x2].x,
                                mTempPos[y].y, mTempPos[y2].y,
                                mTempUVs[x].x, mTempUVs[x2].x,
                                mTempUVs[y].y, mTempUVs[y2].y, c);
                        }
                    }
                }
            }
        }
    

    3. UISprite

    3.1 UISprite是和图集UIAtlas搭配使用的。通过指定图集atlas和图集里面图片名称spriteName,可以显示对应一张图片。通过UIAtlas.GetSprite方法得到UISpriteData,UISpriteData拥有Sprite的信息:name (名称),x,y(在图集纹理贴图对应Sprite起始坐标-左上角),大小,border和padding。

    public class UISpriteData
    {
        public string name = "Sprite";
        public int x = 0;
        public int y = 0;
        public int width = 0;
        public int height = 0;
    
        public int borderLeft = 0;
        public int borderRight = 0;
        public int borderTop = 0;
        public int borderBottom = 0;
    
        public int paddingLeft = 0;
        public int paddingRight = 0;
        public int paddingTop = 0;
        public int paddingBottom = 0;
    }
    

    3.2 核心方法OnFill
    通过UIAtlas.GetSprite接口得到对应SpriteData,以此计算得到Sprite外矩形和内边距的纹理信息
    调用Fill方法填充几何信息

    public override void OnFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            Texture tex = mainTexture;
            if (tex == null) return;
    
            if (mSprite == null) mSprite = atlas.GetSprite(spriteName);
            if (mSprite == null) return;
    
            Rect outer = new Rect(mSprite.x, mSprite.y, mSprite.width, mSprite.height);
            Rect inner = new Rect(mSprite.x + mSprite.borderLeft, mSprite.y + mSprite.borderTop,
                mSprite.width - mSprite.borderLeft - mSprite.borderRight,
                mSprite.height - mSprite.borderBottom - mSprite.borderTop);
    
            outer = NGUIMath.ConvertToTexCoords(outer, tex.width, tex.height);
            inner = NGUIMath.ConvertToTexCoords(inner, tex.width, tex.height);
    
            int offset = verts.size;
            Fill(verts, uvs, cols, outer, inner);
    
            if (onPostFill != null)
                onPostFill(this, offset, verts, uvs, cols);
        }
    

    4. UITexture

    4.1 属性
    mainTexture:纹理贴图
    material:制定材质
    shader:如果material非空则使用material对应的shader,默认使用“Unlit/Transparent Colored“的shader
    uvRect:指定纹理信息:x,y, width,height;其中x,y 为纹理的起始坐标,width,height为其显示的纹理大小。
    fixedAspect:
    4.2 核心方法OnFill
    通过mRect(uvRect)和mainTexture计算外矩形纹理信息
    加上border得到内矩形纹理信息
    调用Fill函数填充几何信息

    public override void OnFill (BetterList<Vector3> verts, BetterList<Vector2> uvs, BetterList<Color32> cols)
        {
            Texture tex = mainTexture;
            if (tex == null) return;
    
            Rect outer = new Rect(mRect.x * tex.width, mRect.y * tex.height, tex.width * mRect.width, tex.height * mRect.height);
            Rect inner = outer;
            Vector4 br = border;
            inner.xMin += br.x;
            inner.yMin += br.y;
            inner.xMax -= br.z;
            inner.yMax -= br.w;
    
            float w = 1f / tex.width;
            float h = 1f / tex.height;
    
            outer.xMin *= w;
            outer.xMax *= w;
            outer.yMin *= h;
            outer.yMax *= h;
    
            inner.xMin *= w;
            inner.xMax *= w;
            inner.yMin *= h;
            inner.yMax *= h;
    
            int offset = verts.size;
            Fill(verts, uvs, cols, outer, inner);
    
            if (onPostFill != null)
                onPostFill(this, offset, verts, uvs, cols);
        }
    

    相关文章

      网友评论

          本文标题:NGUI-UIBasicSprite/UISprite/UITe

          本文链接:https://www.haomeiwen.com/subject/dlovvctx.html