using UnityEngine; using UnityEngine.UI; public class UIRadarGraphic : MaskableGraphic { [HideInInspector] public GraphData[] _datas; [HideInInspector] public float _radius; [HideInInspector] public float _lineWidth; [HideInInspector] public Color _lineColor; private float _perRadian;//弧度 public Transform _pointContent; public Image pointPrefab; /// /// 初始化 /// /// /// /// /// public void Init(GraphData[] datas, float radius, float lineWidth, Color lineColor) { _datas = datas; _radius = radius; _lineWidth = lineWidth; _lineColor = lineColor; _perRadian = Mathf.PI * 2 / _datas.Length; SetAllDirty();//设置Layout布局、Vertices顶点和Material材质为Dirty;我认为是重新绘制 } /// /// 填充网格 /// /// protected override void OnPopulateMesh(VertexHelper vh) { if (_datas == null || _datas.Length <= 2)//不可能存在边数小于三的多边形 { base.OnPopulateMesh(vh); return; } vh.Clear(); _perRadian = Mathf.PI * 2 / _datas.Length; DrawRadar(vh); DrawLine(vh); } /// /// 画雷达图 /// /// private void DrawRadar(VertexHelper vh) { int edgeCount = _datas.Length;//边数量 //画雷达三角面 for (int i = 0; i < edgeCount; i++) { DrawTriangle(vh, GetVertex(i), i); } } /// /// 画雷达图边框 /// /// private void DrawLine(VertexHelper vh) { int edgeCount = _datas.Length;//边数量 //画雷达三角面 for (int i = 0; i < edgeCount; i++) { DrawLine(vh, GetVertex(i)); } } /// /// 画三角面 /// /// /// /// private void DrawTriangle(VertexHelper vh, Vector3[] poses, int index) { Color color = _lineColor; color.a = 0.2f; vh.AddVert(Vector3.zero, color, Vector2.zero);//中心点 vh.AddVert(poses[0], color, Vector2.zero); vh.AddVert(poses[1], color, Vector2.zero);//UI的法线可以随便设置 vh.AddTriangle(index * 3, index * 3 + 1, index * 3 + 2);//将三角面加入UI绘制缓冲区。参数是三角面的三个顶点索引//所以绘制n边形需要绘制3n的顶点 } /// /// 画线 /// /// /// private void DrawLine(VertexHelper vh, Vector3[] poses) { //画线 UIVertex[] newVertexs = GetQuad(poses[0], poses[1], _lineColor, _lineWidth); vh.AddUIVertexQuad(newVertexs); } /// /// 获取一个弧度的两个顶点 /// /// /// 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; //两边顶点 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 }; } public void DrawValuePoint() { for (int i = 0; i < _datas.Length; i++) { float radian = i * _perRadian + 90 * Mathf.Deg2Rad; float radius = _datas[i].Rate * _radius; Vector3 pos = new Vector3(radius * Mathf.Cos(radian), radius * Mathf.Sin(radian)); GameObject obj = Instantiate(pointPrefab.gameObject); obj.transform.SetParent(_pointContent); obj.transform.localScale = Vector3.one; obj.transform.localPosition = pos; obj.gameObject.SetActive(true); } } /// /// 获取一条线的四个顶点 /// /// /// /// 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; } }