美文网首页
Unity雷达图(双层图带描边带背景)

Unity雷达图(双层图带描边带背景)

作者: 神大人korose | 来源:发表于2022-05-11 08:43 被阅读0次

效果大致如下:


代码如下:

using System.Collections;
using System.Collections.Generic;
using System.Linq;//.Max()属于该命名空间
using UnityEngine;
using UnityEngine.UI;

//继承绘制
public class RadarChart : Graphic
{
    public Texture texture;//背景图
    public float[] arr;
    public Color backColor;
    public float padding = 0;//边距
    public float thick = 1;//描边的粗细
    public Color sideColor;//描边的颜色
    public float[] arr2;
    public Color arr2Color;
    public Color side2Color;//描边的颜色

    //重新绘制,每次改变数组中数值后调用
    public override void SetVerticesDirty()
    {
        base.SetVerticesDirty();
    }

    //重新图片读取
    public override Texture mainTexture {
        get
        {
            if (texture == null)
            {
                if (material != null && material.mainTexture != null)
                {
                    return material.mainTexture;
                }
                return s_WhiteTexture;
            }
            return texture;
        }
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        //清理网格
        vh.Clear();
        //获取ui的大小,相当于rectTransform.rect
        Rect rect = GetPixelAdjustedRect();
        //绘制背景图
        Vector4 v = new Vector4(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
        vh.AddVert(new Vector3(v.x, v.y), backColor, new Vector2(0f, 0.15f));
        vh.AddVert(new Vector3(v.x, v.w), backColor, new Vector2(0f, 0.9f));
        vh.AddVert(new Vector3(v.z, v.w), backColor, new Vector2(1f, 0.9f));
        vh.AddVert(new Vector3(v.z, v.y), backColor, new Vector2(1f, 0.15f));
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);

        //计算半径最大值
        //半径的最大值 = 变宽最小值的一半
        float rMax;
        if (rect.width < rect.height)
        {
            rMax = (rect.width - padding) / 2;
        }
        else
        {
            rMax = (rect.height - padding) / 2;
        }
        //计算半径与传入的最大值的比值
        float per = rMax / arr.Max();

        //计算每个角的弧度
        float ang = Mathf.PI * 2 / arr.Length;
        //添加圆心顶点
        vh.AddVert(new Vector3(0, 0, 0), color, Vector4.zero);
        for (int i = 0; i < arr.Length; i++)
        {
            float x = Mathf.Sin(ang * i) * arr[i] * per;
            float y = Mathf.Cos(ang * i) * arr[i] * per;
            //添加顶点
            vh.AddVert(new Vector3(x, y, 0), color, Vector4.zero);
        }
        //描边顶点
        for (int i = 0; i < arr.Length; i++)
        {
            float x = Mathf.Sin(ang * i) * arr[i] * per;
            float y = Mathf.Cos(ang * i) * arr[i] * per;
            //添加顶点
            vh.AddVert(new Vector3(x, y, 0), sideColor, Vector4.zero);

            float x1 = Mathf.Sin(ang * i) * (arr[i] * per - thick);
            float y1 = Mathf.Cos(ang * i) * (arr[i] * per - thick);
            //添加顶点
            vh.AddVert(new Vector3(x1, y1, 0), sideColor, Vector4.zero);
        }
        //前4个顶点被用来绘制背景图了
        //所以全部+4
        //设置雷达图渲染顺序
        for (int i = 0; i < arr.Length; i++)
        {
            if (i == 0)//0的时候算最后一个
            {
                vh.AddTriangle(0 + 4, arr.Length + 4, 1 + 4);
            }
            else
            {
                vh.AddTriangle(0 + 4, i + 4, (i + 1) + 4);
            }
        }
        //前边有雷达图
        //所以全部+4 + arr.Length
        //设置描边渲染顺序
        for (int i = 0; i < arr.Length; i++)
        {
            if (i == 0)//0的时候算最后一个
            {
                //9,1,2
                vh.AddTriangle((arr.Length * 2 - 1) + 4 + arr.Length, 1 + 4 + arr.Length, 1 * 2 + 4 + arr.Length);
                //9,2,10
                vh.AddTriangle((arr.Length * 2 - 1) + 4 + arr.Length, 1 * 2 + 4 + arr.Length, (arr.Length * 2) + 4 + arr.Length);
            }
            else
            {
                vh.AddTriangle((i * 2 - 1) + 4 + arr.Length, ((i + 1) * 2 - 1) + 4 + arr.Length, ((i + 1) * 2) + 4 + arr.Length);
                vh.AddTriangle((i * 2 - 1) + 4 + arr.Length, ((i + 1) * 2) + 4 + arr.Length, (i * 2) + 4 + arr.Length);
            }
        }


        //计算半径与传入的最大值的比值
        float per2 = rMax / arr2.Max();
        //计算每个角的弧度
        float ang2 = Mathf.PI * 2 / arr2.Length;
        //添加圆心顶点
        vh.AddVert(new Vector3(0, 0, 0), arr2Color, Vector4.zero);
        for (int i = 0; i < arr2.Length; i++)
        {
            float x = Mathf.Sin(ang2 * i) * arr2[i] * per2;
            float y = Mathf.Cos(ang2 * i) * arr2[i] * per2;
            //添加顶点
            vh.AddVert(new Vector3(x, y, 0), arr2Color, Vector4.zero);
        }
        //描边顶点
        for (int i = 0; i < arr2.Length; i++)
        {
            float x = Mathf.Sin(ang2 * i) * arr2[i] * per2;
            float y = Mathf.Cos(ang2 * i) * arr2[i] * per2;
            //添加顶点
            vh.AddVert(new Vector3(x, y, 0), side2Color, Vector4.zero);

            float x1 = Mathf.Sin(ang2 * i) * (arr2[i] * per2 - thick);
            float y1 = Mathf.Cos(ang2 * i) * (arr2[i] * per2 - thick);
            //添加顶点
            vh.AddVert(new Vector3(x1, y1, 0), side2Color, Vector4.zero);
        }
        //前4个顶点被用来绘制背景图了
        //所以全部+4 + arr.Length * 3
        int n = 5 + arr.Length * 3;
        //设置雷达图渲染顺序
        for (int i = 0; i < arr2.Length; i++)
        {
            if (i == 0)//0的时候算最后一个
            {
                vh.AddTriangle(0 + n, arr2.Length + n, 1 + n);
            }
            else
            {
                vh.AddTriangle(0 + n, i + n, (i + 1) + n);
            }
        }
        //前边有雷达图
        //所以全部+4 + arr2.Length + arr.Length * 3
        int m = 5 + arr2.Length + arr.Length * 3;
        //设置描边渲染顺序
        for (int i = 0; i < arr2.Length; i++)
        {
            if (i == 0)//0的时候算最后一个
            {
                //例如:9,1,2
                vh.AddTriangle((arr2.Length * 2 - 1) + m, 1 + m, 1 * 2 + m);
                //例如:9,2,10
                vh.AddTriangle((arr2.Length * 2 - 1) + m, 1 * 2 + m, (arr2.Length * 2) + m);
            }
            else
            {
                vh.AddTriangle((i * 2 - 1) + m, ((i + 1) * 2 - 1) + m, ((i + 1) * 2) + m);
                vh.AddTriangle((i * 2 - 1) + m, ((i + 1) * 2) + m, (i * 2) + m);
            }
        }
    }
}

调用方法大致如下:

public void OnBtnAttributes()
    {
        radarChart.arr = radarChart.arr2;
        float[] newarr = new float[5];
        for (int i = 0; i < 5; i++)
        {
            newarr[i] = Random.Range(0, 100);
            attr.GetComponentsInChildren<Text>()[i].text = "属性" + i + ":" + newarr[i];
        }
        radarChart.arr2 = newarr;
        radarChart.SetVerticesDirty();
    }

相关文章

  • Unity雷达图(双层图带描边带背景)

    效果大致如下: 代码如下: 调用方法大致如下:

  • Unity中绘制属性雷达图《二》

    上一篇文章中介绍了雷达图的顶点计算 炉石不传说:Unity中绘制属性雷达图《一》​zhuanlan.zhihu.c...

  • unity 绘制雷达图

    雷达图一般都是显示在UGUI上,但在开始写时创建出来的是3D物体,走了点弯路才发现CanvasRenderer。C...

  • Unity 展示雷达图效果

    游戏中难免会展示英雄的各个属性值,雷达图是比较简洁直观并且符合用户习惯的展示方式之一。3D中生成的任何面都是由一个...

  • R实战| 雷达图(Radar Chart)

    R实战| 雷达图(Radar Chart) 雷达图(radar chart),又称蜘蛛网图(spider plot...

  • R语言可视化(二十一):雷达图绘制

    21. 雷达图绘制 清除当前环境中的变量 设置工作目录 使用fmsb包绘制雷达图 使用ggradar包绘制雷达图

  • 带刻度的雷达图

    把polar图和radar图合并,显示刻度

  • 带刻度的雷达图

    这么一个options,也能雷达图带刻度。卧槽,翻半天文档,都没看到说indicator都能axisLabel,s...

  • 数据雷达图

    最近公司项目,需要用到雷达图的效果,echarts的雷达图不太符合公司的需求,所以自己用canvas写了个雷达图的...

  • pyecharts--雷达图

    数据准备 普通雷达图 雷达图的基本框架出来以后,就需要精细的调整,包括颜色填充,线条调整,以及字体放大等等 雷达图...

网友评论

      本文标题:Unity雷达图(双层图带描边带背景)

      本文链接:https://www.haomeiwen.com/subject/jrcdurtx.html