带描边雷达图的另一种思路

本文介绍了使用Unity开发的动态描边雷达图,通过不同GameObjects间的脚本交互,实现边数、颜色和层级效果的自定义。关键代码展示了如何利用CanvasRenderer生成可变的雷达图并调整边缘线宽。
摘要由CSDN通过智能技术生成

先看效果:

效果和正常绘制内、外顶点那种是一样的。 但是思路不同。

链接:http://t.csdnimg.cn/SFVJO

本篇文章代码没有注释,注释版本在上面链接中。

实现方法:

颜色单词对应上面雷达图底图颜色和相应游戏对象身上的脚本名称。

Pink雷达图游戏对象呈现的效果就是描边效果。

属性说明:

  • 每个游戏对象身上的RectTransform组件中的Scale缩放不同,实现层级效果
  • 脚本中的Num字段为多边形的边数
  • Pink游戏对象脚本中的关联脚本为Green脚本,通过调用Green脚本中封装好的方法(本案例中为ChangeValue方法)给Green脚本中的集合传值,因为当Pink的Scale缩放改变时,Green的Scale缩放也要进行相同的改变方能实现描边效果
  • Green中的Board字段为描边用线的线宽

代码如下:

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class Blue : MaskableGraphic
{
    List<float> m_List = new List<float>();
    public int m_Num;
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);
        if (m_Num <= 2)
        {
            return;
        }
        for (int i = 0; i < m_Num; i++)
        {
            m_List.Add(50);
        }
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector2.zero);
        float rad=2*Mathf.PI/ m_Num;
        float w=GetComponent<RectTransform>().rect.width;
        float h=GetComponent<RectTransform>().rect.height;
        float r=w<h ? w/2 : h/2;
        float ratio = r / m_List.Max();
        for (int i = 0; i < m_Num; i++)
        {
            float x = Mathf.Sin(i* rad) * ratio * m_List[i];
            float y = Mathf.Cos(i* rad) * ratio * m_List[i];
            vh.AddVert(new Vector3(x,y,0),color,Vector2.zero);
            if (i==0)
            {
                vh.AddTriangle(0, m_Num, 1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);
            }
        }
        Mesh mesh = new Mesh();
        vh.FillMesh(mesh);
    }
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class Pink : MaskableGraphic
{
    public Button btn;
    List<float> m_List = new List<float>();
    public int m_Num;
    public Green radarMap;
    protected override void Start()
    {
        //按钮点击改变Pink中集合的值
        btn.onClick.AddListener(() =>
        {
            for (int i = 0; i < m_List.Count; i++)
            {
                m_List[i] = Random.Range(50,100);
            }
            //改变Pink中集合的值后,传给Green中的集合
            radarMap.ChangeValue(m_List);
            SetVerticesDirty();
        });
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);
        if (m_Num <= 2)
        {
            return;
        }
        for (int i = 0; i < m_Num; i++)
        {
            m_List.Add(50);
        }
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector2.zero);
        float rad=2*Mathf.PI/ m_Num;
        float w=GetComponent<RectTransform>().rect.width;
        float h=GetComponent<RectTransform>().rect.height;
        float r=w<h ? w/2 : h/2;
        float ratio = r / m_List.Max();
        for (int i = 0; i < m_Num; i++)
        {
            float x = Mathf.Sin(i* rad) * ratio * m_List[i];
            float y = Mathf.Cos(i* rad) * ratio * m_List[i];
            vh.AddVert(new Vector3(x,y,0),color,Vector2.zero);
            if (i==0)
            {
                vh.AddTriangle(0, m_Num, 1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);
            }
        }
        Mesh mesh = new Mesh();
        vh.FillMesh(mesh);
    }
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class Green : MaskableGraphic
{
    List<float> m_List = new List<float>();
    public int m_Num;
    public float board;
    /// <summary>
    /// 接收Pink中传过来的集合,修改Green中的集合
    /// </summary>
    /// <param name="_list"></param>
    public void ChangeValue(List<float> _list)
    {
        m_List= _list;
        SetVerticesDirty();
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);
        if (m_Num <= 2)
        {
            return;
        }
        for (int i = 0; i < m_Num; i++)
        {
            m_List.Add(50);
        }
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector2.zero);
        float rad = 2 * Mathf.PI / m_Num;
        float w = GetComponent<RectTransform>().rect.width;
        float h = GetComponent<RectTransform>().rect.height;
        float r = w < h ? w / 2 : h / 2;
        float ratio = r / m_List.Max();
        for (int i = 0; i < m_Num; i++)
        {
            float x = Mathf.Sin(i * rad) * ratio * m_List[i];
            float y = Mathf.Cos(i * rad) * ratio * m_List[i];
            vh.AddVert(new Vector3(x, y, 0), color, Vector2.zero);
            if (i == 0)
            {
                vh.AddTriangle(0, m_Num, 1);
            }
            else
            {
                vh.AddTriangle(0, i, i + 1);
            }
        }


        //描边
        //int n = m_Num + 1;
        //for (int i = 0; i < m_Num; i++)
        //{
        //    float xN = Mathf.Sin(i * rad) * (ratio * m_List[i] - board);
        //    float yN = Mathf.Cos(i * rad) * (ratio * m_List[i] - board);
        //    vh.AddVert(new Vector3(xN, yN, 0), boardColor, Vector2.zero);//添加内顶点

        //    float xW = Mathf.Sin(i * rad) * ratio * m_List[i];
        //    float yW = Mathf.Cos(i * rad) * ratio * m_List[i];
        //    vh.AddVert(new Vector3(xW, yW, 0), boardColor, Vector2.zero);//添加外顶点
        //    if (i == m_Num - 1)
        //    {
        //        //五边形   n=6     i=4
        //        vh.AddTriangle(i + 2, 2 * i + n, 2 * n + i - 1);//6 14  15
        //        vh.AddTriangle(i + 2, 2 * n + i - 1, n + 1);//6 15  7
        //    }
        //    else
        //    {
        //        vh.AddTriangle(i * 2 + n, i * 2 + 1 + n, (i + 1) * 2 + n);
        //        vh.AddTriangle(i * 2 + 1 + n, (i + 1) * 2 + 1 + n, (i + 1) * 2 + n);
        //    }
        //}

        Mesh mesh = new Mesh();
        vh.FillMesh(mesh);
    }
}


效果:

描边雷达图

注意是在最外层RadarMap_BG的属性中修改边线数量 !

 层级:

属性: 

 

 附上代码:

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class RadarMap_BG : MaskableGraphic
{
    [Header("边数")]
    public int m_Num;
    public RadarMap_Outline outline;
    public RadarMap radarMap;
    protected override void Start()
    {
        CanvasRenderer cr;
        if (gameObject.TryGetComponent(out cr))
        {
            return;
        }
        gameObject.AddComponent<CanvasRenderer>();
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        outline.m_Num = m_Num;
        radarMap.m_Num = m_Num;
        base.OnPopulateMesh(vh);
        if (m_Num<=2)
        {
            return;
        }
        List<float> values = new List<float>();
        for (int i = 0; i < m_Num; i++)
        {
            values.Add(50);
        }
        float m_Rad = 2 * Mathf.PI / m_Num;
        float w=GetComponent<RectTransform>().rect.width;
        float h=GetComponent<RectTransform>().rect.height;
        float radius=w<h ? w/2 : h/2;
        float ratio = radius / values.Max();
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector2.zero);
        for (int i = 0;i < m_Num;i++)
        {
            float x = Mathf.Sin(i * m_Rad) * values[i]*ratio;
            float y = Mathf.Cos(i * m_Rad) * values[i]*ratio;
            vh.AddVert(new Vector3(x,y,0), color, Vector2.zero);
            if (i==0)
            {
                vh.AddTriangle(0,m_Num,1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class RadarMap_Outline : MaskableGraphic
{
    public int m_Num;
    public Button btn;
    public RadarMap radarMap;

    List<float> values = new List<float>();
    protected override void Start()
    {
        btn.onClick.AddListener(() =>
        {
            for (int i = 0; i < m_Num; i++)
            {
                values[i]=Random.Range(50,100);
            }
            radarMap.ChangeValue(values);
            SetVerticesDirty();
        });
        CanvasRenderer cr;
        if (gameObject.TryGetComponent(out cr))
        {
            return;
        }
        gameObject.AddComponent<CanvasRenderer>();
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);
        if (m_Num<=2)
        {
            return;
        }
        for (int i = 0; i < m_Num; i++)
        {
            if (values.Count<=i)
            {
                values.Add(50);
            }
        }
        float m_Rad = 2 * Mathf.PI / m_Num;
        float w=GetComponent<RectTransform>().rect.width;
        float h=GetComponent<RectTransform>().rect.height;
        float radius=w<h ? w/2 : h/2;
        float ratio = radius / values.Max();
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector2.zero);
        for (int i = 0;i < m_Num;i++)
        {
            float x = Mathf.Sin(i * m_Rad) * values[i]*ratio;
            float y = Mathf.Cos(i * m_Rad) * values[i]*ratio;
            vh.AddVert(new Vector3(x,y,0), color, Vector2.zero);
            if (i==0)
            {
                vh.AddTriangle(0,m_Num,1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);
            }
        }
    }
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class RadarMap : MaskableGraphic
{
    public int m_Num;
    public List<float> values = new List<float>();
    public void ChangeValue(List<float> _list)
    {
        values = _list;
        SetVerticesDirty();
    }
    protected override void Start()
    {
        CanvasRenderer cr;
        if (gameObject.TryGetComponent(out cr))
        {
            return;
        }
        gameObject.AddComponent<CanvasRenderer>();
    }
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        base.OnPopulateMesh(vh);
        if (m_Num<=2)
        {
            return;
        }
        for (int i = 0; i < m_Num; i++)
        {
            if (values.Count<=i)
            {
                values.Add(50);
            }
        }
        float m_Rad = 2 * Mathf.PI / m_Num;
        float w=GetComponent<RectTransform>().rect.width;
        float h=GetComponent<RectTransform>().rect.height;
        float radius=w<h ? w/2 : h/2;
        float ratio = radius / values.Max();
        vh.Clear();
        vh.AddVert(Vector3.zero, color, Vector2.zero);
        for (int i = 0;i < m_Num;i++)
        {
            float x = Mathf.Sin(i * m_Rad) * values[i]*ratio;
            float y = Mathf.Cos(i * m_Rad) * values[i]*ratio;
            vh.AddVert(new Vector3(x,y,0), color, Vector2.zero);
            if (i==0)
            {
                vh.AddTriangle(0,m_Num,1);
            }
            else
            {
                vh.AddTriangle(0, i, i+1);
            }
        }
    }
}

一个可变的描边雷达图就完成啦! 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值