先看效果:
效果和正常绘制内、外顶点那种是一样的。 但是思路不同。
本篇文章代码没有注释,注释版本在上面链接中。
实现方法:
颜色单词对应上面雷达图底图颜色和相应游戏对象身上的脚本名称。
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);
}
}
}
}
一个可变的描边雷达图就完成啦!