![Mesh-Clip分割 Mesh-Clip分割](https://img-blog.csdnimg.cn/img_convert/914121f4d9d9ebfa7697ce26bd31ab9e.png)
效果图如上,分割各种多边形图,具体操作是通过修改uv过滤显示,具体代码如下:
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.UI;
public class MeshClipBase : MaskableGraphic, ILayoutElement, ICanvasRaycastFilter
{
{
[SerializeField]
Sprite m_Sprite;
public Sprite sprite
{
get { return m_Sprite; }
set
{
m_Sprite = value;
SetAllDirty();
}
}
Sprite m_Sprite;
public Sprite sprite
{
get { return m_Sprite; }
set
{
m_Sprite = value;
SetAllDirty();
}
}
[NonSerialized]
Sprite m_OverrirdeSprite;
Sprite m_OverrirdeSprite;
public Sprite overrideSprite
{
get { return m_OverrirdeSprite==null?sprite:m_OverrirdeSprite; }
set
{
m_OverrirdeSprite = value;
SetAllDirty();
}
}
{
get { return m_OverrirdeSprite==null?sprite:m_OverrirdeSprite; }
set
{
m_OverrirdeSprite = value;
SetAllDirty();
}
}
public float alphaThreshold = 1;
public override Texture mainTexture
{
get
{
if (overrideSprite != null)
{
return overrideSprite.texture;
}
else if (material != null && material.mainTexture != null)
{
return material.mainTexture;
}
else
{
return s_WhiteTexture;
}
}
}
{
get
{
if (overrideSprite != null)
{
return overrideSprite.texture;
}
else if (material != null && material.mainTexture != null)
{
return material.mainTexture;
}
else
{
return s_WhiteTexture;
}
}
}
public float pixelsPerUnit
{
get
{
float spritePixelsPerUnit = 100;
float referencePixelsPerUnit = 100;
if (sprite != null)
{
spritePixelsPerUnit = sprite.pixelsPerUnit;
}
{
get
{
float spritePixelsPerUnit = 100;
float referencePixelsPerUnit = 100;
if (sprite != null)
{
spritePixelsPerUnit = sprite.pixelsPerUnit;
}
if (canvas != null)
{
referencePixelsPerUnit = canvas.referencePixelsPerUnit;
}
{
referencePixelsPerUnit = canvas.referencePixelsPerUnit;
}
return spritePixelsPerUnit / referencePixelsPerUnit;
}
}
}
protected UIVertex[] SetVBO(Vector2[] vertices, Vector2[] uvs)
{
UIVertex[] vbo = new UIVertex[4];
for (int i = 0; i < vertices.Length; i++)
{
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
vertex.position = vertices[i];
vertex.uv0 = uvs[i];
vbo[i] = vertex;
}
return vbo;
}
{
UIVertex[] vbo = new UIVertex[4];
for (int i = 0; i < vertices.Length; i++)
{
UIVertex vertex = UIVertex.simpleVert;
vertex.color = color;
vertex.position = vertices[i];
vertex.uv0 = uvs[i];
vbo[i] = vertex;
}
return vbo;
}
public float minWidth => 0;
public float preferredWidth => overrideSprite!=null ? overrideSprite.rect.size.x/pixelsPerUnit:0 ;
public float flexibleWidth => -1;
public float minHeight => 0;
public float preferredHeight => overrideSprite!=null? overrideSprite.rect.size.y/pixelsPerUnit :0;
public float flexibleHeight => -1;
public int layoutPriority => 0;
public void CalculateLayoutInputHorizontal()
{
throw new System.NotImplementedException();
}
{
throw new System.NotImplementedException();
}
public void CalculateLayoutInputVertical()
{
throw new System.NotImplementedException();
}
{
throw new System.NotImplementedException();
}
public bool IsRaycastLocationValid(Vector2 point, Camera eventCamera)
{
if (alphaThreshold >= 1 || overrideSprite==null) return true;
Sprite sp = overrideSprite;
Vector2 local;
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,point , eventCamera, out local);
Rect rect = GetPixelAdjustedRect();
local.x += rectTransform.pivot.x * rect.width;
local.y += rectTransform.pivot.y * rect.height;
local = MapCoordinate(local, rect);
{
if (alphaThreshold >= 1 || overrideSprite==null) return true;
Sprite sp = overrideSprite;
Vector2 local;
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,point , eventCamera, out local);
Rect rect = GetPixelAdjustedRect();
local.x += rectTransform.pivot.x * rect.width;
local.y += rectTransform.pivot.y * rect.height;
local = MapCoordinate(local, rect);
Rect sp_rect = sprite.textureRect;
Vector2 normallized = new Vector2(local.x / sp_rect.width, local.y / sp_rect.height);
Vector2 normallized = new Vector2(local.x / sp_rect.width, local.y / sp_rect.height);
float x = Mathf.Lerp(sp_rect.x, sp_rect.xMax, normallized.x) / sp.texture.width;
float y = Mathf.Lerp(sp_rect.y, sp_rect.yMax, normallized.y) / sp.texture.height;
float y = Mathf.Lerp(sp_rect.y, sp_rect.yMax, normallized.y) / sp.texture.height;
return sp.texture.GetPixelBilinear(x, y).a >= alphaThreshold;
}
Vector2 MapCoordinate(Vector2 local, Rect rect)
{
Rect sp_rect = sprite.rect;
return new Vector2(local.x * sp_rect.width / rect.width, local.y * sp_rect.height / rect.height);
}
{
Rect sp_rect = sprite.rect;
return new Vector2(local.x * sp_rect.width / rect.width, local.y * sp_rect.height / rect.height);
}
Vector4 GetAdjustedBorders(Vector4 border, Rect rect)
{
for (int i = 0; i <= 1; i++)
{
float combineBorders = border[i] + border[i + 2];
if ( combineBorders != 0 && rect.size[i] < combineBorders)
{
float borderScaleRatio = rect.size[i] / combineBorders;
border[i] *= borderScaleRatio;
border[i + 2] *= borderScaleRatio;
}
}
return border;
}
}
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.UI;
public class MeshClip : MeshClipBase
{
static readonly int FILL_PERCENT = 100;
public bool isFill = true;
public float thicness = 5;
{
static readonly int FILL_PERCENT = 100;
public bool isFill = true;
public float thicness = 5;
[Range(3,360)]
public int sides = 6;
public int sides = 6;
[Range(0, 360)]
public float rotation = 0;
public float rotation = 0;
[Range(0, 1)]
public List verticesValues;
public List verticesValues;
float size = 0;
public void SetVerticeValues(List values)
{
if (values != null)
{
verticesValues.Clear();
verticesValues.AddRange(values);
}
else
{
ResetValues();
}
SetVerticesDirty();
#if UNITY_EDITOR
UnityEditor.EditorUtility.SetDirty(transform);
#endif
}
{
if (values != null)
{
verticesValues.Clear();
verticesValues.AddRange(values);
}
else
{
ResetValues();
}
SetVerticesDirty();
#if UNITY_EDITOR
UnityEditor.EditorUtility.SetDirty(transform);
#endif
}
public void DrawPolygon(int m_sides,float m_rotation =0,List m_verticesValues = null)
{
sides = m_sides;
if (m_verticesValues != null)
{
verticesValues.Clear();
verticesValues.AddRange(m_verticesValues);
}
else
{
ResetValues();
}
{
sides = m_sides;
if (m_verticesValues != null)
{
verticesValues.Clear();
verticesValues.AddRange(m_verticesValues);
}
else
{
ResetValues();
}
rotation = m_rotation;
}
}
protected override void OnRectTransformDimensionsChange()
{
base.OnRectTransformDimensionsChange();
size = Mathf.Min( rectTransform.rect.width,rectTransform.rect.height);
thicness = (float)Mathf.Clamp(thicness, 0, size / 2);
}
{
base.OnRectTransformDimensionsChange();
size = Mathf.Min( rectTransform.rect.width,rectTransform.rect.height);
thicness = (float)Mathf.Clamp(thicness, 0, size / 2);
}
void StepThroughPointsAndFill(float outer, float inner, ref Vector2 prevX, ref Vector2 prevY, out Vector2 pos0, out Vector2 pos1, out Vector2 pos2, out Vector2 pos3, float cos, float sin)
{
pos0 = prevX;
pos1 = new Vector2(outer * cos, inner * sin);
pos2 = Vector2.zero;
pos3 = Vector2.zero;
prevX = pos1;
prevY = pos2;
}
{
pos0 = prevX;
pos1 = new Vector2(outer * cos, inner * sin);
pos2 = Vector2.zero;
pos3 = Vector2.zero;
prevX = pos1;
prevY = pos2;
}
protected override void OnPopulateMesh(VertexHelper vh)
{
float flag = -rectTransform.pivot.x * size;
float outer = flag;
float inner = flag + thicness;
vh.Clear();
{
float flag = -rectTransform.pivot.x * size;
float outer = flag;
float inner = flag + thicness;
vh.Clear();
Vector2 prevX = Vector2.zero;
Vector2 prevY = Vector2.zero;
Vector2 uv0 = Vector2.zero;
Vector2 uv1 = Vector2.up;
Vector2 uv2 = Vector2.one;
Vector2 uv3 = Vector2.right;
Vector2 prevY = Vector2.zero;
Vector2 uv0 = Vector2.zero;
Vector2 uv1 = Vector2.up;
Vector2 uv2 = Vector2.one;
Vector2 uv3 = Vector2.right;
Vector2 pos0;
Vector2 pos1;
Vector2 pos2;
Vector2 pos3;
Vector2 pos1;
Vector2 pos2;
Vector2 pos3;
float w = rectTransform.rect.width;
float h = rectTransform.rect.height;
float h = rectTransform.rect.height;
if (verticesValues.Count != sides)
{
ResetValues();
}
{
ResetValues();
}
float angleStep = (FILL_PERCENT / 100f *( Mathf.PI * 2f)) / sides;
float currentAngle = 0;
Vector2[] pos = new Vector2[4];
Vector2[] uv = new Vector2[4];
Vector2[] pos = new Vector2[4];
Vector2[] uv = new Vector2[4];
for (int i = 0; i <= sides; i++)
{
float angle = currentAngle + rotation;
float cos = Mathf.Cos(angle);
float sin = Mathf.Sin(angle);
outer = flag * verticesValues[i % sides];
inner = flag * verticesValues[i % sides] +thicness;
{
float angle = currentAngle + rotation;
float cos = Mathf.Cos(angle);
float sin = Mathf.Sin(angle);
outer = flag * verticesValues[i % sides];
inner = flag * verticesValues[i % sides] +thicness;
StepThroughPointsAndFill(outer ,inner,ref prevX,ref prevY,out pos0,out pos1,out pos2,out pos3,cos,sin);
uv0 = Vector2.one * 0.5f + new Vector2(pos0.x / w, pos0.y / h);
uv1 = Vector2.one * 0.5f + new Vector2(pos1.x / w, pos1.y / h);
uv2 = Vector2.one * 0.5f + new Vector2(pos2.x / w, pos2.y / h);
uv3 = Vector2.one * 0.5f + new Vector2(pos3.x / w, pos3.y / h);
uv1 = Vector2.one * 0.5f + new Vector2(pos1.x / w, pos1.y / h);
uv2 = Vector2.one * 0.5f + new Vector2(pos2.x / w, pos2.y / h);
uv3 = Vector2.one * 0.5f + new Vector2(pos3.x / w, pos3.y / h);
pos[0] = pos0;
pos[1] = pos1;
pos[2] = pos2;
pos[3] = pos3;
pos[1] = pos1;
pos[2] = pos2;
pos[3] = pos3;
uv[0] = uv0;
uv[1] = uv1;
uv[2] = uv2;
uv[3] = uv3;
uv[1] = uv1;
uv[2] = uv2;
uv[3] = uv3;
vh.AddUIVertexQuad( SetVBO( pos,uv));
currentAngle += angleStep;
currentAngle += angleStep;
}
}
void ResetValues()
{
verticesValues.Clear();
for (int i = 0; i < sides; i++)
{
verticesValues.Add(1);
}
}
{
verticesValues.Clear();
for (int i = 0; i < sides; i++)
{
verticesValues.Add(1);
}
}
}