Unity雷達(dá)制作(一)


非常好用的一款雷達(dá)圖,直接把代碼分享給大家。
UIRadarGraphManager.cs
using UnityEngine;
using UnityEngine.UI;
[System.Serializable]
public struct GraphData
{
? ? public string _desc;
? ? [Range(0, 100)]
? ? public float _value;
? ? public float Rate
? ? {
? ? ? ? get
? ? ? ? {
? ? ? ? ? ? return _value / 100;
? ? ? ? }
? ? }
? ? public GraphData(string desc, float value)
? ? {
? ? ? ? _desc = desc;
? ? ? ? _value = value;
? ? }
}
public class UIRadarGraphManager : MaskableGraphic
{
? ? public GraphData[] _datas;
? ? public int _rulingCount = 4;//刻度數(shù)
? ? public float _lineWidth = 1f;//背景線寬度
? ? public float _radarLineWidth = 1f;//雷達(dá)邊框?qū)挾?/p>
? ? public Color _lineColor = Color.gray;//背景線顏色
? ? public Color _radarLineColor = Color.blue;//雷達(dá)邊框顏色
? ? public UIRadarImage _radarImage;//雷達(dá)圖
? ? public float _tweenTime = 1f;//動(dòng)畫(huà)事件
? ? private Vector2[] _vertexs;//頂點(diǎn)
? ? private float _radius;//半徑
? ? private float _perRadian;//弧度
? ? protected override void Awake()
? ? {
? ? ? ? base.Awake();
? ? ? ? _radius = Mathf.Min(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y) / 2;
? ? }
? ? /// <summary>
? ? /// 刷新雷達(dá)圖
? ? /// </summary>
? ? /// <param name="datas"></param>
? ? public void RefeshRadarGraph(GraphData[] datas)
? ? {
? ? ? ? _datas = datas;
? ? ? ? SetAllDirty();//設(shè)置Layout布局、Vertices頂點(diǎn)和Material材質(zhì)為Dirty;當(dāng)一個(gè)Canvas被標(biāo)記為包含需要被rebatch的幾何圖形,那這個(gè)Canvas被認(rèn)為dirty。
? ? ? ? _radarImage.transform.localScale = Vector3.zero;
? ? ? ? _radarImage.Init(datas, _radius, _radarLineWidth, _radarLineColor);
? ? ? ? _radarImage.transform.localScale = Vector3.one;
? ? }
? ? /// <summary>
? ? /// UI生成頂點(diǎn)時(shí)調(diào)用
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? protected override void OnPopulateMesh(VertexHelper vh)
? ? {
? ? ? ? if (_datas == null || _datas.Length <= 2)//不可能存在邊樹(shù)小于三的多邊形
? ? ? ? {
? ? ? ? ? ? base.OnPopulateMesh(vh);
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? vh.Clear();
? ? ? ? DrawAxis(vh);
? ? ? ? DrawRuling(vh);
? ? }
? ? /// <summary>
? ? /// 畫(huà)坐標(biāo)軸
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? private void DrawAxis(VertexHelper vh)
? ? {
? ? ? ? GetVertexs();
? ? ? ? for (int i = 0; i < _vertexs.Length; i++)
? ? ? ? {
? ? ? ? ? ? vh.AddUIVertexQuad(GetQuad(Vector2.zero, _vertexs[i], _lineColor, _lineWidth));
? ? ? ? }
? ? }
? ? /// <summary>
? ? /// 畫(huà)刻度
? ? /// </summary>
? ? private void DrawRuling(VertexHelper vh)
? ? {
? ? ? ? float perRadius = _radius / (_rulingCount - 1);//原點(diǎn)不需要畫(huà)
? ? ? ? for (int i = 1; i < _rulingCount; i++)
? ? ? ? {
? ? ? ? ? ? for (int j = 0; j < _datas.Length; j++)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? float startRadian = _perRadian * j + 90 * Mathf.Deg2Rad;
? ? ? ? ? ? ? ? float endRadian = _perRadian * (j + 1) + 90 * Mathf.Deg2Rad;
? ? ? ? ? ? ? ? Vector2 startPos = new Vector2(Mathf.Cos(startRadian), Mathf.Sin(startRadian)) * perRadius * i;
? ? ? ? ? ? ? ? Vector2 endPos = new Vector2(Mathf.Cos(endRadian), Mathf.Sin(endRadian)) * perRadius * i;
? ? ? ? ? ? ? ? UIVertex[] newVertexs = GetQuad(startPos, endPos, _lineColor, _lineWidth);
? ? ? ? ? ? ? ? vh.AddUIVertexQuad(newVertexs);
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ??
? ? /// <summary>
? ? /// 獲取頂點(diǎn)
? ? /// </summary>
? ? /// <returns></returns>
? ? private void GetVertexs()
? ? {
? ? ? ? _perRadian = Mathf.PI * 2 / _datas.Length;
? ? ? ? _vertexs = new Vector2[_datas.Length];
? ? ? ? for (int i = 0; i < _datas.Length; i++)
? ? ? ? {
? ? ? ? ? ? float radian = _perRadian * i + 90 * Mathf.Deg2Rad;
? ? ? ? ? ? Vector2 endPos = new Vector2(Mathf.Cos(radian), Mathf.Sin(radian)) * _radius;
? ? ? ? ? ? _vertexs[i] = endPos;
? ? ? ? }
? ? }
? ? /// <summary>
? ? /// 獲取一條線的四個(gè)頂點(diǎn)
? ? /// </summary>
? ? /// <param name="startPos"></param>
? ? /// <param name="endPos"></param>
? ? /// <returns></returns>
? ? private UIVertex[] GetQuad(Vector2 startPos, Vector2 endPos, Color color, float width)
? ? {
? ? ? ? float dis = Vector2.Distance(startPos, endPos);
? ? ? ? float x = width / 2 * (endPos.y - startPos.y) / dis;//sin
? ? ? ? float y = width / 2 * (endPos.x - startPos.x) / dis;//cos
? ? ? ? if (y <= 0) y = -y;
? ? ? ? else x = -x;
? ? ? ? UIVertex[] vertex = new UIVertex[4];
? ? ? ? vertex[0].position = new Vector3(startPos.x + x, startPos.y + y);
? ? ? ? vertex[1].position = new Vector3(endPos.x + x, endPos.y + y);
? ? ? ? vertex[2].position = new Vector3(endPos.x - x, endPos.y - y);
? ? ? ? vertex[3].position = new Vector3(startPos.x - x, startPos.y - y);
? ? ? ? for (int i = 0; i < vertex.Length; i++)
? ? ? ? ? ? vertex[i].color = color;
? ? ? ? return vertex;
? ? }
}
UIRadarImage.cs
using UnityEngine;
using UnityEngine.UI;
public class UIRadarImage : MaskableGraphic
{
? ? [HideInInspector]
? ? public GraphData[] _datas;
? ? [HideInInspector]
? ? public float _radius;
? ? [HideInInspector]
? ? public float _lineWidth;
? ? [HideInInspector]
? ? public Color _lineColor;
? ? private float _perRadian;//弧度
? ? /// <summary>
? ? /// 初始化
? ? /// </summary>
? ? /// <param name="datas"></param>
? ? /// <param name="radius"></param>
? ? /// <param name="lineWidth"></param>
? ? /// <param name="lineColor"></param>
? ? public void Init(GraphData[] datas, float radius, float lineWidth, Color lineColor)
? ? {
? ? ? ? _datas = datas;
? ? ? ? _radius = radius;
? ? ? ? _lineWidth = lineWidth;
? ? ? ? _lineColor = lineColor;
? ? ? ? SetAllDirty();//設(shè)置Layout布局、Vertices頂點(diǎn)和Material材質(zhì)為Dirty;我認(rèn)為是重新繪制
? ? }
? ? /// <summary>
? ? /// 填充網(wǎng)格
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? protected override void OnPopulateMesh(VertexHelper vh)
? ? {
? ? ? ? if (_datas == null || _datas.Length <= 2)//不可能存在邊數(shù)小于三的多邊形
? ? ? ? {
? ? ? ? ? ? base.OnPopulateMesh(vh);
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? vh.Clear();
? ? ? ? _perRadian = Mathf.PI * 2 / _datas.Length;
? ? ? ? DrawRadar(vh);
? ? ? ? DrawLine(vh);
? ? }
? ? /// <summary>
? ? /// 畫(huà)雷達(dá)圖
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? private void DrawRadar(VertexHelper vh)
? ? {
? ? ? ? int edgeCount = _datas.Length;//邊數(shù)量
? ? ? ? //畫(huà)雷達(dá)三角面
? ? ? ? for (int i = 0; i < edgeCount; i++)
? ? ? ? {
? ? ? ? ? ? DrawTriangle(vh, GetVertex(i), i);
? ? ? ? }
? ? }
? ? /// <summary>
? ? /// 畫(huà)雷達(dá)圖邊框
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? private void DrawLine(VertexHelper vh)
? ? {
? ? ? ? int edgeCount = _datas.Length;//邊數(shù)量
? ? ? ? //畫(huà)雷達(dá)三角面
? ? ? ? for (int i = 0; i < edgeCount; i++)
? ? ? ? {
? ? ? ? ? ? DrawLine(vh, GetVertex(i));
? ? ? ? }
? ? }
? ? /// <summary>
? ? /// 畫(huà)三角面
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? /// <param name="index"></param>
? ? /// <param name="deltaAngle"></param>
? ? private void DrawTriangle(VertexHelper vh, Vector3[] poses, int index)
? ? {
? ? ? ? Color color = _lineColor;
? ? ? ? color.a = 0.5f;
? ? ? ? vh.AddVert(Vector3.zero, color, Vector2.zero);//中心點(diǎn)
? ? ? ? vh.AddVert(poses[0], color, Vector2.zero);
? ? ? ? vh.AddVert(poses[1], color, Vector2.zero);//UI的法線可以隨便設(shè)置
? ? ? ? vh.AddTriangle(index * 3, index * 3 + 1, index * 3 + 2);//將三角面加入U(xiǎn)I繪制緩沖區(qū)。參數(shù)是三角面的三個(gè)頂點(diǎn)索引//所以繪制n邊形需要繪制3n的頂點(diǎn)
? ? }
? ? /// <summary>
? ? /// 畫(huà)線
? ? /// </summary>
? ? /// <param name="vh"></param>
? ? /// <param name="index"></param>
? ? private void DrawLine(VertexHelper vh, Vector3[] poses)
? ? {
? ? ? ? //畫(huà)線
? ? ? ? UIVertex[] newVertexs = GetQuad(poses[0], poses[1], _lineColor, _lineWidth);
? ? ? ? vh.AddUIVertexQuad(newVertexs);
? ? }
? ? /// <summary>
? ? /// 獲取一個(gè)弧度的兩個(gè)頂點(diǎn)
? ? /// </summary>
? ? /// <param name="index"></param>
? ? /// <returns></returns>
? ? private Vector3[] GetVertex(int index)
? ? {
? ? ? ? int nextIndex = index + 1 >= _datas.Length ? 0 : index + 1;
? ? ? ? float radian1 = index * _perRadian + 90 * Mathf.Deg2Rad;
? ? ? ? float radian2 = nextIndex * _perRadian + 90 * Mathf.Deg2Rad;
? ? ? ? float radius1 = _datas[index].Rate * _radius;
? ? ? ? float radius2 = _datas[nextIndex].Rate * _radius;
? ? ? ? //兩邊頂點(diǎn)
? ? ? ? Vector3 p1 = new Vector3(radius1 * Mathf.Cos(radian1), radius1 * Mathf.Sin(radian1));
? ? ? ? Vector3 p2 = new Vector3(radius2 * Mathf.Cos(radian2), radius2 * Mathf.Sin(radian2));
? ? ? ? return new Vector3[] { p1, p2 };
? ? }
? ? /// <summary>
? ? /// 獲取一條線的四個(gè)頂點(diǎn)
? ? /// </summary>
? ? /// <param name="startPos"></param>
? ? /// <param name="endPos"></param>
? ? /// <returns></returns>
? ? private UIVertex[] GetQuad(Vector2 startPos, Vector2 endPos, Color color, float width)
? ? {
? ? ? ? float dis = Vector2.Distance(startPos, endPos);
? ? ? ? float x = width / 2 * (endPos.y - startPos.y) / dis;//sin
? ? ? ? float y = width / 2 * (endPos.x - startPos.x) / dis;//cos
? ? ? ? if (y <= 0) y = -y;
? ? ? ? else x = -x;
? ? ? ? UIVertex[] vertex = new UIVertex[4];
? ? ? ? vertex[0].position = new Vector3(startPos.x + x, startPos.y + y);
? ? ? ? vertex[1].position = new Vector3(endPos.x + x, endPos.y + y);
? ? ? ? vertex[2].position = new Vector3(endPos.x - x, endPos.y - y);
? ? ? ? vertex[3].position = new Vector3(startPos.x - x, startPos.y - y);
? ? ? ? for (int i = 0; i < vertex.Length; i++)
? ? ? ? ? ? vertex[i].color = color;
? ? ? ? return vertex;
? ? }
}
直接傳入數(shù)據(jù)即可
? ? ?GetComponent<UIRadarGraphManager>().RefeshRadarGraph(graphDatas);
此代碼是之前網(wǎng)上學(xué)到的,原鏈接找不到啦,不過(guò)非常具有學(xué)習(xí)價(jià)值。