雷达图在我们的游戏中是一个非常重要的组成部分,例如我们在初次进入一个游戏,在创建角色的过程中经常见到雷达图。 它可以将数据可视化,更直观的将数据展现了出来, 可以让我们快速了解游戏中人物的各项数据,从而让更快的选出适合我们的人物。除了选人之外,还有很多地方也用到了雷达图,今天,让我们一起来学习一下UGUI中雷达图的绘制。
我们首先来了解一下雷达图的实现原理:
1.我们重写image的OnPopulateMesh(VertexHelper vh)函数,清空所有顶点信息(VertexHelper.Clear() 清空后该image就不会进行显示);
2..然后我们构建五边形的5个顶点(初始位置在正五边形的五个顶点位置),之后创建外部系数控制5项数据的大小,得到5个顶点的最终显示位置,之后3个顶点构成面即可;
3.重新给VertexHelper对象添加顶点信息,三角面信息,我们原始的Image就会显示为五边形形状 来表现数据倾向。
下面是代码:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
public class CreateLDT : MaskableGraphic
{
//精灵
public Sprite activeSprite;
//纹理
public override Texture mainTexture
{
get
{
if (activeSprite==null) //如果精灵为空
{
//如果材质球不为空 并且 材质球的mainTexture不为空
if (material!=null && material.mainTexture!=null)
{
//有材质球的使用材质球
return material.mainTexture;
}
//没有精灵并且材质球为空的,使用白色
return s_WhiteTexture;
}
//有精灵使用精灵
return activeSprite.texture;
}
}
public float[] arr; //存储数据的数组
protected override void OnPopulateMesh(VertexHelper vh)
{
//小于3条边绘制默认图形(默认图形为正方形)
if (arr.Length<3)
{
base.OnPopulateMesh(vh);
return;
}
//获取宽高
float w = rectTransform.sizeDelta.x;
float h = rectTransform.sizeDelta.y;
//找到数组中的最大值
float max = arr.Max();
//计算最大值与宽高的比例
float p = w < h ? (w / 2) / max : (h / 2) / max;
vh.Clear();
//每个角的弧度
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;
//计算UV坐标
float uvx = (x + w / 2) / w;
float uvy = (y + h / 2) / h;
//添加顶点
vh.AddVert(new Vector3(x, y, 0), color, new Vector2(uvx, uvy));
//添加绘制顺序
if (i==0)
{
vh.AddTriangle(0, arr.Length, 1);
}
else
{
vh.AddTriangle(0, i, i + 1);
}
}
}
}
在代码中,我们首先重写了Texture 的 mainTexture,这一步是为了给我们绘制出来的雷达图赋材质。有精灵的话我们就用精灵,没有精灵的话就用材质球,如果精灵和材质球都没有的话我们就给它赋上自带的白色材质。
然后我们又重写了OnPopulateMesh,这一步里面的东西是真正重要的东西。里面包括了计算宽高,比例,顶点坐标,UV坐标,添加点,添加绘制顺序等各个步骤,代码中我的注释写的还是挺详细的,大家可以仔细看一下。