雷达图的设计

一:雷达图的概括

是一个五边形,其中可以扩展贴图,限制Image大小和描边

首先,要了解一些UGUI底层的原理代码,因为其中包括了生成五边形的一些特定条件,它的代码路径在“Unity\Hub\Editor\2020.3.33f1c2\Editor\Data\Resources\PackageManager\BuiltInPackages\com.unity.ugui\Runtime\UI\Core”的Image文件中OnPopulateMesh的方法

使用OnPopulateMesh方法必须要继承MaskableGraphic这个类

这个方法是判断要创建的图形有多少个顶点,如果不满足对应顶点数量的话,则直接退出,代码如下:

public float[] arr;
    protected override void OnPopulateMesh(VertexHelper vh)//顶点助手
    {
        if (arr.Length<3)
        {
            base.OnPopulateMesh(vh);
            return;
        }
    }

 arr数组是用来存储顶点数量的一个容器

二:创建图形的具体逻辑如下:

vh.Clear();//因为底层涉及到了集合,所以每次执行这个方法之前先把集合内数据清空

        
        float ang = 2 * Mathf.PI / arr.Length;//弧度
        vh.AddVert(Vector3.zero,color,Vector2.zero);//圆心
        for (int i = 0; i < arr.Length; i++)
        {
            float x = Mathf.Sin(i * ang) * arr[i] ;
            float y = Mathf.Cos(i * ang) * arr[i] ;

            vh.AddVert(new Vector3(x, y, 0), color, Vector2.zero);
            //添加绘制顺序
            if (i==0)
            {
                vh.AddTriangle(0, arr.Length, 1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);//正常的绘制顺序
            }
        }

三:在创建好图形之后,可以考虑是否加入贴图;

如果考虑加入贴图,那么要考虑两点,一个是对象的2D坐标和uv坐标;

加入好贴图之后,要更改创建图形中的两条数据,一条为圆心数据,一条为贴图的uv坐标;

public Sprite activeSprite;
public override Texture mainTexture//赋值图片
    {
        get
        {
            if (activeSprite == null)
            {
                if (material != null && material.mainTexture != null)
                {
                    return material.mainTexture;
                }
                return s_WhiteTexture;
            }

            return activeSprite.texture;
        }
    }

以上是创建好图形之后的返回Sprite精灵的方法,如果图片上存在精灵(Sprite)或者存在Material(材质球)等效果,那么进行展示,如果都不存在,直接返回初始图片 

 

四:设置图片的限制大小,让效果更美观

vh.Clear();//因为底层涉及到了集合,所以每次执行这个方法之前先把集合内数据清空

        float w = rectTransform.sizeDelta.x;
        float h = rectTransform.sizeDelta.y;//贴图,获取2D坐标
        
        float max = arr.Max();//限制雷达图长宽
        float p=w<h?(w/2)/max:(h/2)/max;//比例
        
        float ang = 2 * Mathf.PI / arr.Length;//弧度
        vh.AddVert(Vector3.zero,color, new Vector2(0.5f, 0.5f));//圆心
        for (int i = 0; i < arr.Length; i++)
        {
            float x = Mathf.Sin(i * ang) * arr[i] * p;
            float y = Mathf.Cos(i * ang) * arr[i] * p;

            float uvx = (x + w / 2) / w;
            float uvy = (y + h / 2) / h;//uv的横纵坐标
            vh.AddVert(new Vector3(x,y,0), color, new Vector2(uvx, uvy));//贴图需要改变Vector2参数
            //添加绘制顺序
            if (i==0)
            {
                vh.AddTriangle(0, arr.Length, 1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);//正常的绘制顺序
            }
        }

五:添加描边的效果

//描边颜色
    public Color uColor = Color.red;
    //描边宽度
    public float m = 1;
//画描边
        int next = arr.Length + 1;
        for (int i = 0; i < arr.Length; i++)
        {
            //内顶点
            //计算顶点坐标
            float x0 = Mathf.Sin(i * ang) * (arr[i] * p - m);
            float y0 = Mathf.Cos(i * ang) * (arr[i] * p - m);
            //计算uv坐标
            float uvx0 = (x0 + w / 2) / w;
            float uvy0 = (y0 + h / 2) / h;
            //添加顶点
            vh.AddVert(new Vector3(x0, y0, 0), uColor, new Vector2(uvx0, uvy0));

            //外顶点
            //计算顶点坐标
            float x = Mathf.Sin(i * ang) * arr[i] * p;
            float y = Mathf.Cos(i * ang) * arr[i] * p;
            //计算uv坐标
            float uvx = (x + w / 2) / w;
            float uvy = (y + h / 2) / h;
            //添加顶点
            vh.AddVert(new Vector3(x, y, 0), uColor, new Vector2(uvx, uvy));
            //添加绘制顺序
            if (i == arr.Length - 1)
            {
                vh.AddTriangle(i * 2 + next, i * 2 + 1 + next, 1 + next);
                vh.AddTriangle(i * 2 + next, 1 + next, next);
            }
            else
            {
                vh.AddTriangle(i * 2 + next, i * 2 + 1 + next, (i + 1) * 2 + 1 + next);
                vh.AddTriangle(i * 2 + next, (i + 1) * 2 + 1 + next, (i + 1) * 2 + next);
            }
        }

描边效果:计算出每个顶点和对应点(可以自定义设置)之间的宽度,增加一个颜色的效果即可

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值