UIRadarGraphic.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. public class UIRadarGraphic : MaskableGraphic
  4. {
  5. [HideInInspector]
  6. public GraphData[] _datas;
  7. [HideInInspector]
  8. public float _radius;
  9. [HideInInspector]
  10. public float _lineWidth;
  11. [HideInInspector]
  12. public Color _lineColor;
  13. private float _perRadian;//弧度
  14. public Transform _pointContent;
  15. public Image pointPrefab;
  16. /// <summary>
  17. /// 初始化
  18. /// </summary>
  19. /// <param name="datas"></param>
  20. /// <param name="radius"></param>
  21. /// <param name="lineWidth"></param>
  22. /// <param name="lineColor"></param>
  23. public void Init(GraphData[] datas, float radius, float lineWidth, Color lineColor)
  24. {
  25. _datas = datas;
  26. _radius = radius;
  27. _lineWidth = lineWidth;
  28. _lineColor = lineColor;
  29. _perRadian = Mathf.PI * 2 / _datas.Length;
  30. SetAllDirty();//设置Layout布局、Vertices顶点和Material材质为Dirty;我认为是重新绘制
  31. }
  32. /// <summary>
  33. /// 填充网格
  34. /// </summary>
  35. /// <param name="vh"></param>
  36. protected override void OnPopulateMesh(VertexHelper vh)
  37. {
  38. if (_datas == null || _datas.Length <= 2)//不可能存在边数小于三的多边形
  39. {
  40. base.OnPopulateMesh(vh);
  41. return;
  42. }
  43. vh.Clear();
  44. _perRadian = Mathf.PI * 2 / _datas.Length;
  45. DrawRadar(vh);
  46. DrawLine(vh);
  47. }
  48. /// <summary>
  49. /// 画雷达图
  50. /// </summary>
  51. /// <param name="vh"></param>
  52. private void DrawRadar(VertexHelper vh)
  53. {
  54. int edgeCount = _datas.Length;//边数量
  55. //画雷达三角面
  56. for (int i = 0; i < edgeCount; i++)
  57. {
  58. DrawTriangle(vh, GetVertex(i), i);
  59. }
  60. }
  61. /// <summary>
  62. /// 画雷达图边框
  63. /// </summary>
  64. /// <param name="vh"></param>
  65. private void DrawLine(VertexHelper vh)
  66. {
  67. int edgeCount = _datas.Length;//边数量
  68. //画雷达三角面
  69. for (int i = 0; i < edgeCount; i++)
  70. {
  71. DrawLine(vh, GetVertex(i));
  72. }
  73. }
  74. /// <summary>
  75. /// 画三角面
  76. /// </summary>
  77. /// <param name="vh"></param>
  78. /// <param name="index"></param>
  79. /// <param name="deltaAngle"></param>
  80. private void DrawTriangle(VertexHelper vh, Vector3[] poses, int index)
  81. {
  82. Color color = _lineColor;
  83. color.a = 0.2f;
  84. vh.AddVert(Vector3.zero, color, Vector2.zero);//中心点
  85. vh.AddVert(poses[0], color, Vector2.zero);
  86. vh.AddVert(poses[1], color, Vector2.zero);//UI的法线可以随便设置
  87. vh.AddTriangle(index * 3, index * 3 + 1, index * 3 + 2);//将三角面加入UI绘制缓冲区。参数是三角面的三个顶点索引//所以绘制n边形需要绘制3n的顶点
  88. }
  89. /// <summary>
  90. /// 画线
  91. /// </summary>
  92. /// <param name="vh"></param>
  93. /// <param name="index"></param>
  94. private void DrawLine(VertexHelper vh, Vector3[] poses)
  95. {
  96. //画线
  97. UIVertex[] newVertexs = GetQuad(poses[0], poses[1], _lineColor, _lineWidth);
  98. vh.AddUIVertexQuad(newVertexs);
  99. }
  100. /// <summary>
  101. /// 获取一个弧度的两个顶点
  102. /// </summary>
  103. /// <param name="index"></param>
  104. /// <returns></returns>
  105. private Vector3[] GetVertex(int index)
  106. {
  107. int nextIndex = index + 1 >= _datas.Length ? 0 : index + 1;
  108. float radian1 = index * _perRadian + 90 * Mathf.Deg2Rad;
  109. float radian2 = nextIndex * _perRadian + 90 * Mathf.Deg2Rad;
  110. float radius1 = _datas[index].Rate * _radius;
  111. float radius2 = _datas[nextIndex].Rate * _radius;
  112. //两边顶点
  113. Vector3 p1 = new Vector3(radius1 * Mathf.Cos(radian1), radius1 * Mathf.Sin(radian1));
  114. Vector3 p2 = new Vector3(radius2 * Mathf.Cos(radian2), radius2 * Mathf.Sin(radian2));
  115. return new Vector3[] { p1, p2 };
  116. }
  117. public void DrawValuePoint()
  118. {
  119. for (int i = 0; i < _datas.Length; i++)
  120. {
  121. float radian = i * _perRadian + 90 * Mathf.Deg2Rad;
  122. float radius = _datas[i].Rate * _radius;
  123. Vector3 pos = new Vector3(radius * Mathf.Cos(radian), radius * Mathf.Sin(radian));
  124. GameObject obj = Instantiate<GameObject>(pointPrefab.gameObject);
  125. obj.transform.SetParent(_pointContent);
  126. obj.transform.localScale = Vector3.one;
  127. obj.transform.localPosition = pos;
  128. obj.gameObject.SetActive(true);
  129. }
  130. }
  131. /// <summary>
  132. /// 获取一条线的四个顶点
  133. /// </summary>
  134. /// <param name="startPos"></param>
  135. /// <param name="endPos"></param>
  136. /// <returns></returns>
  137. private UIVertex[] GetQuad(Vector2 startPos, Vector2 endPos, Color color, float width)
  138. {
  139. float dis = Vector2.Distance(startPos, endPos);
  140. float x = width / 2 * (endPos.y - startPos.y) / dis;//sin
  141. float y = width / 2 * (endPos.x - startPos.x) / dis;//cos
  142. if (y <= 0) y = -y;
  143. else x = -x;
  144. UIVertex[] vertex = new UIVertex[4];
  145. vertex[0].position = new Vector3(startPos.x + x, startPos.y + y);
  146. vertex[1].position = new Vector3(endPos.x + x, endPos.y + y);
  147. vertex[2].position = new Vector3(endPos.x - x, endPos.y - y);
  148. vertex[3].position = new Vector3(startPos.x - x, startPos.y - y);
  149. for (int i = 0; i < vertex.Length; i++)
  150. vertex[i].color = color;
  151. return vertex;
  152. }
  153. }