UGUI制作自己的圆

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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值