using System.Collections;
using System.Collections.Generic;
using UnityEditor.Sprites;
using UnityEngine;
using UnityEngine.Sprites;
using UnityEngine.UI;
public class CircleImage : Image
{
public float precent = 1;
//三角形数量
public int segements = 100;
//[SerializeField]
//private float precent = 1;
//[SerializeField]
//private int segements = 100;
private List<Vector3> vertexList;
//VertexHelper=顶点
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
vertexList = new List<Vector3> { };
//获得rect的宽高
float width=rectTransform.rect.width;
float height=rectTransform.rect.height;
//获取精灵的UV
Vector4 uv = overrideSprite != null ? UnityEngine.Sprites.DataUtility.
GetOuterUV(overrideSprite) : Vector4.zero;
float uvwidth = uv.z - uv.x;
float uvheight = uv.w - uv.y;
Vector2 uvCenter = new Vector2((uv.z - uv.x) * 0.5f, (uv.w - uv.y) * 0.5f);
//convertRatio=系数
Vector2 convertRatio=new Vector2(uvwidth/width, uvheight/height);
//每个三角形的角度
float radian = 2 * Mathf.PI / segements;
float radius=width/2;
//postermp是圆心点位置
Vector2 originPos = new Vector2((0.5f - rectTransform.pivot.x) * width,
(0.5f - rectTransform.pivot.y) * height);
Vector2 vertPos = new Vector2(0, 0);
//原点信息
UIVertex origin = new UIVertex();
origin.color = color;
origin.position=originPos;
//uv0点是不跟随顶点坐标而改变的
origin.uv0 = new Vector2(vertPos.x*convertRatio.x+uvCenter.x,vertPos.y*convertRatio.y+uvCenter.y);
vh.AddVert(origin);
//除去原点的顶点数量
int vertexCount = segements + 1;
//生成顶点信息
float curRadian = 0;
for (int i = 0; i<segements+1; i++)
{
float x = Mathf.Cos(curRadian) * radius;
float y = Mathf.Sin(curRadian) * radius;
curRadian += radian;
UIVertex vertexTemp= new UIVertex();
vertexTemp.color = color;
Vector2 posTermp = new Vector2(x, y);
vertexTemp.position = posTermp + originPos;
//如果不加uvcenter,那么uv0点就会从左下角开始生成
//uv0点是不跟随顶点坐标而改变的
vertexTemp.uv0= new Vector2(posTermp.x*convertRatio.x+uvCenter.x,posTermp.y*convertRatio.y+uvCenter.y);
vh.AddVert(vertexTemp);
vertexList.Add(vertexTemp.position);
}
int id = 1;
for (int i=0;i<segements;i++)
{
vh.AddTriangle(id, 0, id + 1);
id++;
}
}
//如果组允许射线投射,则返回 true。
public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
{
Vector2 localPoint;
//将一个屏幕空间点转换为 RectTransform 的本地空间中位于其矩形平面上的一个位置。
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint,
eventCamera, out localPoint);
Debug.Log(IsValid(localPoint));
return IsValid(localPoint);
}
public bool IsValid(Vector2 localPoint)
{
return GetCrossNum(localPoint)%2 == 1 ? true : false;
}
public int GetCrossNum(Vector2 localPoint)
{
Vector3 vert1 = Vector3.zero;
Vector3 vert2 = Vector3.zero;
int num = 0;
for (int i=0;i<vertexList.Count;i++)
{
vert1 = vertexList[i];
vert2 = vertexList[(i + 1) % vertexList.Count];
IsInRang(localPoint, vert1, vert2);
if (GetX(vert1,vert2,localPoint.y)>=localPoint.x)
{
num++;
}
}
return num;
}
public bool IsInRang(Vector2 localPoint,Vector3 vert1,Vector3 vert2)
{
if (vert2.y > vert1.y)
{
return localPoint.y >= vert1.y && localPoint.y <= vert2.y;
}
else
{
return localPoint.y <= vert1.y && localPoint.y >= vert2.y;
}
}
public float GetX(Vector2 vert1,Vector2 vert2,float y)
{
float k = (vert1.y - vert2.y) / (vert1.x - vert2.x);
float x = vert1.x + (y - vert1.y) / k;
return x;
}
}
UGUI制作自己的圆
于 2024-10-03 18:04:07 首次发布