Unity 镜像sprite

项目中有使用到了很多对称的图片,于是美术哥为了减少图片占用的大小,提出要程序来将做对称,美术只需要出一半的图,剩余的一半有程序实现对称。参考文章:点击打开链接。 

 自己实现了一版本,将这个组件挂在拥有Image的对象上就可以了,要弄清楚几个点:

1.RectTransform中各项数值的意思

2.ModifyMesh调用时机(UGUI填充了图元数据后,会调用虚函数ModifyMesh给用户修改数据的机会)

3.获取的顶点数据的方法(VertexHelper)

4.Sprite的类型(Simple,Sliced)

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class MirrorSprite : BaseMeshEffect
{
    public enum eMirrorType
    {
        eHor,
        eVer,
    }

    [SerializeField]
    private eMirrorType mMirrorType;

    private List<UIVertex> mVerts = new List<UIVertex>();
    private List<int> mIndices = new List<int>();
    private UIVertex mVertex = new UIVertex();

    protected override void Awake()
    {
        mMirrorType = eMirrorType.eHor;
    }

    public override void ModifyMesh(VertexHelper vh)
    {
        mVerts.Clear();
        for (int i = 0; i < vh.currentVertCount; i++)
        {
            vh.PopulateUIVertex(ref mVertex, i);
            mVerts.Add(mVertex);
        }

        if(graphic is Image)
        {
            Image image = graphic as Image;
            switch (image.type)
            {
                case Image.Type.Simple:
                    {
                        DrawSimple();
                    }
                    break;
                case Image.Type.Sliced:
                    {
                        DrawSliced();
                    }
                    break;
                case Image.Type.Tiled:
                    {

                    }
                    break;
            }
        }

        vh.Clear();
        vh.AddUIVertexStream(mVerts, mIndices);
    }

    public void SetIndice()
    {
        mIndices.Clear();
        for (int i = 0; i < mVerts.Count;)
        {
            mIndices.Add(i);
            mIndices.Add(i + 1);
            mIndices.Add(i + 2);

            mIndices.Add(i);
            mIndices.Add(i + 2);
            mIndices.Add(i + 3);

            i = i + 4;
        }
    }

    //为了解决拼接处的缝隙问题,让uv进行偏移
    public void FixUV()
    {
        for (int i = 0; i < mVerts.Count; i++)
        {
            var vertex = mVerts[i];
            Vector2 uv = vertex.uv0;
            int remainder = i % 4;

            if (mMirrorType == eMirrorType.eHor)
            {
                if (remainder == 2 || remainder == 3)
                {
                    uv.x -= 1.5f / Screen.width;
                }
            }

            if (mMirrorType == eMirrorType.eVer)
            {
                if (remainder == 1 || remainder == 2)
                {
                    uv.y -= 1.5f / Screen.height;
                }
            }

            vertex.uv0 = uv;
            mVerts[i] = vertex;
        }
    }

    //放缩
    //public void SimpleScale()
    //{
    //    Rect rect = graphic.GetPixelAdjustedRect();
    //    RectTransform rt = graphic.rectTransform;
        
    //    for (int i = 0; i < mVerts.Count; i++)
    //    {
    //        var vertex = mVerts[i];
    //        Vector3 position = vertex.position;


    //        if(mMirrorType == eMirrorType.eHor)
    //        {
    //            position.x = (position.x + rect.x) * 0.5f;
    //        }

    //        if (mMirrorType == eMirrorType.eVer)
    //        {
    //            position.y = (position.y + rect.y) * 0.5f;
    //        }

    //        vertex.position = position;
    //        mVerts[i] = vertex;
    //    }
    //}

    //镜像图片
    public void Mirror()
    {
        Rect rect = graphic.GetPixelAdjustedRect();

        switch (mMirrorType)
        {
            case eMirrorType.eHor:
                {
                    int count = mVerts.Count;
                    for(int i = 0; i < count; i++)
                    {
                        //公式: x1 - x = x - x2 => x1 = 2x - x2 (x1在对称轴x的右侧,x2在对称轴x的左侧)
                        var vertex = mVerts[i];
                        var position = vertex.position;
                        position.x = rect.max.x * 2 - position.x;
                        vertex.position = position;
                        mVerts.Add(vertex);
                    }
                }
                break;
            case eMirrorType.eVer:
                {
                    int count = mVerts.Count;
                    for (int i = 0; i < count; i++)
                    {
                        var vertex = mVerts[i];
                        var position = vertex.position;
                        position.y = rect.max.y * 2 - position.y;
                        vertex.position = position;
                        mVerts.Add(vertex);
                    }
                }
                break;
        }
    }

    public void DrawSimple()
    {
        FixUV();
        Mirror();
        SetIndice();
    }

    public void DrawSliced()
    {
        FixUV();
        Mirror();
        SetIndice();
    }
}


猜你喜欢

转载自blog.csdn.net/qweewqpkn/article/details/79857112