using System;
using System.Collections.Generic;
namespace UnityEngine.UI
{
[RequireComponent(typeof(Graphic))]
public class Mirror : BaseMeshEffect
{
public enum MirrorType
{
/// <summary>
/// 水平
/// </summary>
Horizontal,
/// <summary>
/// 垂直
/// </summary>
Vertical,
/// <summary>
/// 四分之一
/// 相当于水平,然后再垂直
/// </summary>
Quarter,
}
/// <summary>
/// 镜像类型
/// </summary>
[SerializeField]
private MirrorType m_MirrorType = MirrorType.Horizontal;
[NonSerialized]
private RectTransform m_RectTransform;
public RectTransform RectTransform
{
get { return m_RectTransform ?? (m_RectTransform = GetComponent<RectTransform>()); }
}
private readonly List<UIVertex> output = new List<UIVertex>();
/// <summary>
/// 设置原始尺寸
/// </summary>
[ContextMenu("SetNativeSize")]
public void SetNativeSize()
{
if (graphic != null && graphic is Image)
{
Sprite overrideSprite = (graphic as Image).overrideSprite;
if (overrideSprite != null)
{
float w = overrideSprite.rect.width / (graphic as Image).pixelsPerUnit;
float h = overrideSprite.rect.height / (graphic as Image).pixelsPerUnit;
RectTransform.anchorMax = RectTransform.anchorMin;
switch (m_MirrorType)
{
case MirrorType.Horizontal:
RectTransform.sizeDelta = new Vector2(w * 2, h);
break;
case MirrorType.Vertical:
RectTransform.sizeDelta = new Vector2(w, h * 2);
break;
case MirrorType.Quarter:
RectTransform.sizeDelta = new Vector2(w * 2, h * 2);
break;
}
graphic.SetVerticesDirty();
}
}
}
public override void ModifyMesh(VertexHelper vh)
{
if (!IsActive())
{
return;
}
vh.GetUIVertexStream(output);
int count = output.Count;
if (graphic is Image)
{
Image.Type type = (graphic as Image).type;
switch (type)
{
case Image.Type.Simple:
DrawSimple(output, count);
break;
case Image.Type.Sliced:
break;
case Image.Type.Tiled:
break;
case Image.Type.Filled:
break;
}
}
else
{
DrawSimple(output, count);
}
vh.Clear();
vh.AddUIVertexTriangleStream(output);
}
/// <summary>
/// 绘制简单版
/// </summary>
/// <param name="output"></param>
/// <param name="count"></param>
protected void DrawSimple(List<UIVertex> output, int count)
{
Rect rect = graphic.GetPixelAdjustedRect();
SimpleScale(rect, output, count);
switch (m_MirrorType)
{
case MirrorType.Horizontal:
ExtendCapacity(output, count);
MirrorVerts(rect, output, count, true);
break;
case MirrorType.Vertical:
ExtendCapacity(output, count);
MirrorVerts(rect, output, count, false);
break;
case MirrorType.Quarter:
ExtendCapacity(output, count * 3);
MirrorVerts(rect, output, count, true);
MirrorVerts(rect, output, count * 2, false);
break;
}
}
protected void ExtendCapacity(List<UIVertex> verts, int addCount)
{
var neededCapacity = verts.Count + addCount;
if (verts.Capacity < neededCapacity)
{
verts.Capacity = neededCapacity;
}
}
protected void SimpleScale(Rect rect, List<UIVertex> verts, int count)
{
for (int i = 0; i < count; i++)
{
UIVertex vertex = verts[i];
Vector3 position = vertex.position;
if (m_MirrorType == MirrorType.Horizontal || m_MirrorType == MirrorType.Quarter)
{
position.x = (position.x + rect.x) * 0.5f;
}
if (m_MirrorType == MirrorType.Vertical || m_MirrorType == MirrorType.Quarter)
{
position.y = (position.y + rect.y) * 0.5f;
}
vertex.position = position;
verts[i] = vertex;
}
}
protected void MirrorVerts(Rect rect, List<UIVertex> verts, int count, bool isHorizontal = true)
{
for (int i = 0; i < count; i++)
{
UIVertex vertex = verts[i];
Vector3 position = vertex.position;
if (isHorizontal)
{
position.x = rect.center.x * 2 - position.x;
}
else
{
position.y = rect.center.y * 2 - position.y;
}
vertex.position = position;
verts.Add(vertex);
}
}
}
}