项目中有使用到了很多对称的图片,于是美术哥为了减少图片占用的大小,提出要程序来将做对称,美术只需要出一半的图,剩余的一半有程序实现对称。参考文章:点击打开链接。
自己实现了一版本,将这个组件挂在拥有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();
}
}