用UGUI的Image画面积图
程序员文章站
2022-03-11 10:28:34
...
使用UGUI的Image画面积图
哈哈,本大猫又回来了,新的工作,新的生活。愿自己和看到这段话的你们,生活越来越辛福美满!
唔,先上图:
1. 参考引用:
[1] https://www.cnblogs.com/jeason1997/p/5130413.html 在Unity中使用UGUI修改Mesh绘制几何图形 (作者:Jeason1997)
2. 实现思路:
UGUI的Image实现方式和一般的Mesh一样,都是通过顶点描绘出来的。通过察看Image这个类的代码,发现它提供了虚函数,需要用到的关键函数是OnPopulateMesh(VertexHelper toFill)。
3. 好像也没啥需要多说的,就是给出顶点(位置,颜色,VU),然后一个一个三角形按照顺时针方向连起来。emmmm,上代码~
1)核心代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DrawAreaDiagram : Image {
private List<float> percentArray = new List<float>();//百分比数组
private float brokenLineWidth = 3f;//折线的宽度
private Vector3 origin;//绘图区域的原点
private Vector2 area;//宽高范围
private Color[] lineColors;//折线
private Color[] imageTopColors;//顶部
private Color[] imageButtomColors;//底部
private Vector3[] vertPositions;
private int times = 3;
private float pointQuadlength = 6f;//节点的边长
private Vector3[] pointQuadPositions;//节点的位置
private int quadSides = 4;//节点的边数
private void Update()
{
SetVerticesDirty();//刷新
}
protected override void OnPopulateMesh(VertexHelper toFill)
{
if (percentArray.Count == 0)
{
base.OnPopulateMesh(toFill);
}
else
{
toFill.Clear();
for (int i = 0; i < percentArray.Count; i++)
{
toFill.AddVert(vertPositions[i * times], imageButtomColors[i], new Vector2((float)i / percentArray.Count, 0));//下
toFill.AddVert(vertPositions[i * times + 1], imageTopColors[i], new Vector2((float)i / percentArray.Count, 0.25f));//上
toFill.AddVert(vertPositions[i * times + 1], lineColors[i], new Vector2((float)i / percentArray.Count, 0.25f));//上
toFill.AddVert(vertPositions[i * times + 2], lineColors[i], new Vector2((float)i / percentArray.Count, 0.5f));//顶
}
for (int i = 0; i < percentArray.Count; i++)
{
toFill.AddVert(pointQuadPositions[i * quadSides], lineColors[i], new Vector2((float)i / percentArray.Count, 0.5f));//下
toFill.AddVert(pointQuadPositions[i * quadSides + 1], lineColors[i], new Vector2((float)i / percentArray.Count, 1f));//上
toFill.AddVert(pointQuadPositions[i * quadSides + 2], lineColors[i], new Vector2((float)i / percentArray.Count, 0.5f));//上
toFill.AddVert(pointQuadPositions[i * quadSides + 3], lineColors[i], new Vector2((float)i / percentArray.Count, 1f));//顶
}
for (int i = 0; i < percentArray.Count - 1; i++)
{
toFill.AddTriangle(i * 4 + 0, i * 4 + 1, i * 4 + 4);
toFill.AddTriangle(i * 4 + 1, i * 4 + 5, i * 4 + 4);
toFill.AddTriangle(i * 4 + 2, i * 4 + 3, i * 4 + 6);
toFill.AddTriangle(i * 4 + 3, i * 4 + 7, i * 4 + 6);
}
for (int i = percentArray.Count; i < percentArray.Count * 2; i++)
{
toFill.AddTriangle(i * 4 + 0, i * 4 + 1, i * 4 + 2);
toFill.AddTriangle(i * 4 + 1, i * 4 + 3, i * 4 + 2);
}
}
}
public void InitDrawingParam(float _pointQuadlength,float buttomAlpha,float topAplha, float lineWidth,Color[] colors,List<float> _percentArray)
{
if (colors.Length != _percentArray.Count)
{
Debug.LogError("ArrayList is Wrong!");
return;
}
pointQuadlength = _pointQuadlength;
percentArray = _percentArray;//百分比数组
brokenLineWidth = lineWidth;//折线的宽
GetDrawArea();//得到绘图区域
CreateVertPositions(_percentArray);//获取到每个顶点的坐标
lineColors = new Color[colors.Length];
imageTopColors = new Color[colors.Length];
imageButtomColors = new Color[colors.Length];
//颜色
for (int i = 0; i < colors.Length; i++)
{
lineColors[i] = colors[i];
imageTopColors[i] = colors[i];
imageButtomColors[i] = colors[i];
//透明度
lineColors[i].a = 1;
imageTopColors[i].a = _percentArray[i] * topAplha;
imageButtomColors[i].a = buttomAlpha;
}
}
private void CreateVertPositions(List<float> _percentArray)
{
vertPositions = new Vector3[_percentArray.Count * times];//折线顶,折线底,图片底
pointQuadPositions = new Vector3[_percentArray.Count * quadSides];//节点
int arrayCount = _percentArray.Count - 1;
for (int i = 0; i < arrayCount + 1; i++)
{
vertPositions[times * i] = origin + new Vector3(area.x * i / arrayCount, 0, 0);//图片底
vertPositions[times * i + 1] = vertPositions[times * i] + new Vector3(0, area.y * _percentArray[i] - brokenLineWidth / 2);//折线底
vertPositions[times * i + 2] = vertPositions[times * i + 1] + new Vector3(0, brokenLineWidth);//折线顶
pointQuadPositions[quadSides * i] = origin + new Vector3(area.x * i / arrayCount - pointQuadlength / 2, area.y * _percentArray[i] - pointQuadlength / 2);//节点左下
pointQuadPositions[quadSides * i + 1] = origin + new Vector3(area.x * i / arrayCount - pointQuadlength / 2, area.y * _percentArray[i] + pointQuadlength / 2);//节点左上
pointQuadPositions[quadSides * i + 2] = origin + new Vector3(area.x * i / arrayCount + pointQuadlength / 2, area.y * _percentArray[i] - pointQuadlength / 2);//节点右下
pointQuadPositions[quadSides * i + 3] = origin + new Vector3(area.x * i / arrayCount + pointQuadlength / 2, area.y * _percentArray[i] + pointQuadlength / 2);//节点右上
}
}
//原点,宽,高
private void GetDrawArea()
{
area = rectTransform.rect.size;
origin = -(Vector3)area / 2;
}
}
2)测试代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DrawTest : MonoBehaviour {
private DrawAreaDiagram areaDiagram;
# region 测试代码
protected void Start()
{
areaDiagram = GetComponentInChildren<DrawAreaDiagram>(true);
StartCoroutine(FreshImage());
}
IEnumerator FreshImage()
{
while (true)
{
yield return new WaitForSeconds(0.9f);
Test();
}
}
protected void Test()
{
Color[] colors = new Color[19];
List<float> _percentArray = new List<float>();
for (int i = 0; i < colors.Length; i++)
{
colors[i] = new Color(Random.Range(0.1f, 1f), Random.Range(0.1f, 1f), Random.Range(0.1f, 1f), 1);
_percentArray.Add(Random.Range(0.1f, 1f));
}
areaDiagram.InitDrawingParam(29f, 0f, 0.9f, 5f, colors, _percentArray);
}
#endregion
}
4. 使用大概是这样子的:(父节点挂测试代码)
上一篇: 19、GIF动图显示
推荐阅读
-
用Python画的,5 种非传统的可视化技术,超炫酷的动态图
-
用python的seaborn画数值箱型图
-
用什么画流程图,分享一个简单又高效的方法
-
如何使用eclipse画UML用例图?使用eclipse画UML用例图的方法
-
Unity学习笔记(09):UGUI的Image节点和Sprite精灵图、实现进度条加载动画
-
用matplotlib画双柱形图,并画出横纵轴的箭头
-
给你一个画饼图的,画直方图直接用img控制其宽高就可实现吧_PHP
-
给你一个画饼图的,画直方图直接用img控制其宽高就可实现吧_PHP
-
用UGUI的Image画面积图
-
用Python画的,5 种非传统的可视化技术,超炫酷的动态图