Unity绘制圆和缓动雷达图
Unity绘制圆和缓动雷达图
之前在做UI模块的时候遇到过需要做雷达图的效果,所以简单复习了一下
关于网格绘制
我们都知道Unity绘制图形是通过Mesh网格添加顶点进行绘制,那么知道顶点信息后如何实现图形的绘制,就是由Graphic
类来帮助我们实现。因此我们需要自定义一个类继承Graphic
,然后重写其OnPopulateMesh
方法,将其挂载到UI物体上。
public class RadarMap : Graphic
{
protected override void OnPopulateMesh(VertexHelper vh)
{
}
}
注:若想要支持RectMask2D功能,则改为继承MaskableGraphic
即可
在OnPopulateMesh
方法中提供了VertexHelper
参数,这是Unity的顶点辅助类,通过它我们可以轻松实现添加顶点和绘制等操作了。
添加顶点
//参数是顶点坐标,颜色以及uv坐标
new VertexHelper().AddVert(Vector3 position, Color32 color, Vector2 uv0)
顶点的绘制
new VertexHelper().AddTriangle(int idx0, int idx1, int idx2);
绘制圆
对于Unity中的网格,我们只能通过一个个三角形拼接成不同的形状,包括Unity本身的物体网格也是如此,因此,画圆可以通过弧度和半径,以及圆的边长去绘制多个三角形,拼接而成一个圆
这是对画圆的一些总结
画圆的代码如下:
using UnityEngine;
using UnityEngine.UI;
public class RadarMap : Graphic
{
public Texture2D texture;
public Color _color = Color.white;
public int n;
public float r;
public override Texture mainTexture//赋值UI图片
{
get
{
if (texture != null)
{
return texture;//如果有外部精灵则返回外部精灵的texture
}
if (material != null && material.mainTexture != null)
{
return material.mainTexture;//如果有材质则返回材质上的texture
}
return s_WhiteTexture;//什么都没有的情况返回默认的texture
}
}
protected override void OnPopulateMesh(VertexHelper vh)
{
Rect rect = rectTransform.rect;
r = rect.width < rect.height ? rect.width / 2 : rect.height / 2;//取当前最小的宽或高,取一半获得半径
if (n >= 3)
{
vh.Clear();
vh.AddVert(Vector3.zero, color, new Vector2(0.5f, 0.5f));//添加圆心点
float ang = 2 * Mathf.PI / n;
for (int i = 0; i < n; i++)
{
float x = Mathf.Sin(i * ang) * r;
float y = Mathf.Cos(i * ang) * r;
float uvx = (x + r) / (2 * r);//通过圆上点+半径/直径求出uv坐标
float uvy = (y + r) / (2 * r);
vh.AddVert(new Vector3(x, y, 0), color, new Vector3(uvx, uvy));//添加顶点
if (i == 0)
{
vh.AddTriangle(0, n, 1);//第一次绘制最后一部分
}
else
{
vh.AddTriangle(0, i, i + 1);//依次绘制
}
}
}
}
}
画出圆的效果
绘制雷达图
根据绘制圆我们可以发现,绘制雷达图是同理的,同样是添加一个圆心点并根据半径和弧度求出圆上的顶点,只是雷达图每个顶点的位置都跟雷达图中的数值有关。因此,我们只需要添加一个数组,并将画圆的代码稍作修改就可以了
以下是雷达图的绘制代码:
using UnityEngine;
using UnityEngine.UI;
public class RadarMap : Graphic
{
public Texture2D texture;
public Color _color = Color.white;
public float[] arr = new float[0];
public float r;
public override Texture mainTexture
{
get
{
if (texture != null)
{
return texture;//如果有外部精灵则返回外部精灵的texture
}
if (material != null && material.mainTexture != null)
{
return material.mainTexture;//如果有材质则返回材质上的texture
}
return s_WhiteTexture;//什么都没有的情况返回默认的texture
}
}
//生成无背景雷达图 这里的生成方法和生成圆的方法是一致的
protected override void OnPopulateMesh(VertexHelper vh)
{
Rect rect = rectTransform.rect;
int n = arr.Length;
//取当前最小的宽或高,取一半获得半径
r = rect.width < rect.height ? rect.width / 2 : rect.height / 2;
if (n >= 3)
{
vh.Clear();
//添加圆心点
vh.AddVert(Vector3.zero, color, new Vector2(0.5f, 0.5f));
float ang = 2 * Mathf.PI / n;
for (int i = 0; i < n; i++)
{
//通过数组中数据的值为雷达图赋值,最大值为半径
float x = Mathf.Sin(i * ang) * (arr[i] < r ? arr[i] : r);
float y = Mathf.Cos(i * ang) * (arr[i] < r ? arr[i] : r);
//通过圆上点+半径/直径求出uv坐标
float uvx = (x + r) / (2 * r);
float uvy = (y + r) / (2 * r);
//添加顶点
vh.AddVert(new Vector3(x, y, 0), color, new Vector3(uvx, uvy));
if (i == 0)
{
//第一次绘制最后一部分
vh.AddTriangle(0, n, 1);
}
else
{
//依次绘制
vh.AddTriangle(0, i, i + 1);
}
}
}
}
}
最后的效果如下
缓动则通过Mathf.Lerp
的差值函数实现,也可以直接使用公式( max - min ) * p + min
代码如下:
//缓动代码块,这里的数组和集合已经赋值过
public RadarMap radarMap;
bool isDrow = false;
List<float> arr = new List<float>();
float[] arry;
float MaxTime = 3f;//缓动最大时间
float nowTime = 0f;//缓动开始时间
private void Update()
{
if (isDrow)
{
nowTime += Time.deltaTime;
for (int i = 0; i < arr.Count; i++)
{
//差值函数,始终在当前点和目标点中间取一个参数
arry[i] = Mathf.Lerp(0, arr[i], nowTime / MaxTime);
//当达到了这个值以后,循环结束,清空缓存原始数据的集合
if (i == arr.Count - 1 && arr[i] - arry[i] <= 0.1f)
{
Mathf.Round(arry[i]);
arr.Clear();
isDrow = false;
nowTime = 0f;
}
}
//清除脏数据
radarMap.SetAllDirty();
//将每次算出的差值赋给RadarMap
radarMap.arr = arry;
}
}
Unity绘制圆和缓动雷达图的更多相关文章
- konva canvas插件写雷达图示例
最近,做了一个HTML5的项目,里面涉及到了雷达图效果,这里,我将react实战项目中,用到的雷达图单拎出来写一篇博客,供大家学习. 以下内容涉及的代码在我的gitlab仓库中:Konva canva ...
- Mesh绘制雷达图(UGUI)
参考资料:http://www.cnblogs.com/jeason1997/p/5130413.html ** 描述:雷达图 刷新 radarDate.SetVerticesDirty(); usi ...
- Python绘制雷达图(俗称六芒星)
原文链接:https://blog.csdn.net/Just_youHG/article/details/83904618 背景 <Python数据分析与挖掘实战> 案例2–航空公司客户 ...
- Tableau绘制K线图、布林线、圆环图、雷达图
Tableau绘制K线图.布林线.圆环图.雷达图 本文首发于博客冰山一树Sankey,去博客浏览效果更好.直接右上角搜索该标题即可 一. K线图 1.1 导入数据源 1.2 拖拽字段 将[日期]托到列 ...
- MATLAB中绘制质点轨迹动图并保存成GIF
工作需要在MATLAB中绘制质点轨迹并保存成GIF以便展示. 绘制质点轨迹动图可用comet和comet3命令,使用例子如下: t = 0:.01:2*pi;x = cos(2*t).*(cos(t) ...
- 利用d3.js绘制雷达图
利用d3,js将数据可视化,能够做到数据与代码的分离.方便以后改动数据. 这次利用d3.js绘制了一个五维的雷达图.即将多个对象的五种属性在一张图上对照. 数据写入data.csv.数据类型写入typ ...
- 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图
对于第三方框架Charts(Swift版本,在OC项目中需要添加桥接头文件),首先要解决在项目中集成的问题,集成步骤: 一.下载Charts框架 下载地址:https://github.com/dan ...
- 【带着canvas去流浪(6)】绘制雷达图
目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...
- Emgu-WPF 激光雷达研究-绘制雷达图
原文:Emgu-WPF 激光雷达研究-绘制雷达图 硬件:Hokuyo URG04LX 环境:VS2017- win10- 64 Emgu_3.2.0.2682 语言:C# WPF 数据解析参考 ...
- 带着canvas去流浪系列之六 绘制雷达图
[摘要] 用canvas原生API实现百度Echarts基本图表. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvas ...
随机推荐
- ZSTUOJ平台刷题⑤:Problem G.--深入浅出学算法023-旋转数阵
Problem G: 深入浅出学算法023-旋转数阵 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 4794 Solved: 955 Descripti ...
- Oracle添加约束
约束 -contraint Oracle中约束类型:主键约束,唯一约束,非空约束,外键约束,check约束,下述主要是alter的方法去添加约束,也可以在建表时直接添加约束 主键约束 alter ta ...
- 10 soundJs 初体验
最近想做一个h5的小游戏所以用上了soundjs. 还在开发中 http://www.hetenglife.com/mouse/game.html 刚刚把控制做完. 首先是要导入这个文件 <s ...
- linux 基线检查
1 检查用户缺省UMASK #cat /etc/profile|sed '/^#/d'|sed '/^$/d'|grep -i "umask" 修改umask vi /etc/pr ...
- hdu4585 Treap与名次树/STL map(C/C++)
hdu4585 题目地址:https://acm.dingbacode.com/showproblem.php?pid=4585 Shaolin Time Limit: 3000/1000 MS (J ...
- elelment中el-cascader怎样自定义显示的lable 与value
1.后端返回的数据类型 2.页面代码 3.重点在于 :props="{ value: 'id',label: 'className',children: 'childNode'}" ...
- python Elementtree 生成带缩进格式的xml文件
示例 之前拿ET写xml,直接对root节点调用write函数,会出现产生的xml字符串没有缩进,是干巴巴的一行,可读性比较差,就像下面这样: <annotation><filena ...
- 数据库之【常用sql语句归纳】
一.数据库操作: 1.创建数据库 create database dbname; 2.创建库是否存在,不存在就创建 create database if not exists dbname; 3.查看 ...
- 2.5基本算法之搜索 156:LETTERS
#include<iostream>#include<cstdio>using namespace std;char a[21][21];bool b[26]; int X[4 ...
- JAVA设计模式及其设计原则
设计模式: 设计模式是一套被反复使用的.多数人知晓的.经过分类编目的.代码设计经验的总结. 单例模式:在一个jvm虚拟机,要创建的对象控制成独一份:举例:统计单台虚拟机内的用户在线数 package ...