UIRadar.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using DG.Tweening;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. public class UIRadar : MaskableGraphic
  5. {
  6. public GraphData[] _datas;
  7. public int _rulingCount = 4;//刻度数
  8. public float _lineWidth = 1f;//背景线宽度
  9. public float _radarLineWidth = 1f;//雷达边框宽度
  10. public Color _lineColor = Color.gray;//背景线颜色
  11. public Color _radarLineColor = Color.blue;//雷达边框颜色
  12. public UIRadarGraphic _radarGraphic;//雷达图
  13. public Text _descPrefab;//描述Prefab
  14. public Transform _descContent;//描述Content
  15. public float _tweenTime = 1f;//动画事件
  16. private Vector2[] _vertexs;//顶点
  17. private float _radius;//半径
  18. private float _perRadian;//弧度
  19. private float _descSpace;//描述间隔
  20. protected override void Awake()
  21. {
  22. base.Awake();
  23. _radius = Mathf.Min(rectTransform.sizeDelta.x, rectTransform.sizeDelta.y) / 2;
  24. _descSpace = Mathf.Max(_descPrefab.rectTransform.sizeDelta.x, _descPrefab.rectTransform.sizeDelta.y) / 5;
  25. }
  26. /// <summary>
  27. /// 刷新雷达图
  28. /// </summary>
  29. /// <param name="datas"></param>
  30. public void RefeshRadarGraph(GraphData[] datas)
  31. {
  32. _datas = datas;
  33. ClearTransform(_descContent);
  34. ClearTransform(_radarGraphic._pointContent);
  35. DrawDesc();
  36. SetAllDirty();//设置Layout布局、Vertices顶点和Material材质为Dirty;当一个Canvas被标记为包含需要被rebatch的几何图形,那这个Canvas被认为dirty。
  37. _radarGraphic.transform.localScale = Vector3.zero;
  38. _radarGraphic.Init(datas, _radius, _radarLineWidth, _radarLineColor);
  39. _radarGraphic.transform.DOScale(Vector3.one, _tweenTime);
  40. _radarGraphic.DrawValuePoint();
  41. }
  42. /// <summary>
  43. /// UI生成顶点时调用
  44. /// </summary>
  45. /// <param name="vh"></param>
  46. protected override void OnPopulateMesh(VertexHelper vh)
  47. {
  48. if (_datas == null || _datas.Length <= 2)//不可能存在边树小于三的多边形
  49. {
  50. base.OnPopulateMesh(vh);
  51. return;
  52. }
  53. vh.Clear();
  54. //DrawAxis(vh);
  55. DrawRuling(vh);
  56. }
  57. /// <summary>
  58. /// 画坐标轴
  59. /// </summary>
  60. /// <param name="vh"></param>
  61. private void DrawAxis(VertexHelper vh)
  62. {
  63. GetVertexs();
  64. for (int i = 0; i < _vertexs.Length; i++)
  65. {
  66. vh.AddUIVertexQuad(GetQuad(Vector2.zero, _vertexs[i], _lineColor, _lineWidth));
  67. }
  68. }
  69. /// <summary>
  70. /// 画刻度
  71. /// </summary>
  72. private void DrawRuling(VertexHelper vh)
  73. {
  74. float perRadius = _radius / (_rulingCount - 1);//原点不需要画
  75. for (int i = 1; i < _rulingCount; i++)
  76. {
  77. for (int j = 0; j < _datas.Length; j++)
  78. {
  79. float startRadian = _perRadian * j + 90 * Mathf.Deg2Rad;
  80. float endRadian = _perRadian * (j + 1) + 90 * Mathf.Deg2Rad;
  81. Vector2 startPos = new Vector2(Mathf.Cos(startRadian), Mathf.Sin(startRadian)) * perRadius * i;
  82. Vector2 endPos = new Vector2(Mathf.Cos(endRadian), Mathf.Sin(endRadian)) * perRadius * i;
  83. UIVertex[] newVertexs = GetQuad(startPos, endPos, _lineColor, _lineWidth);
  84. vh.AddUIVertexQuad(newVertexs);
  85. }
  86. }
  87. }
  88. /// <summary>
  89. /// 描述
  90. /// </summary>
  91. private void DrawDesc()
  92. {
  93. GetVertexs();
  94. for (int i = 0; i < _vertexs.Length; i++)
  95. {
  96. Text desc = Instantiate<GameObject>(_descPrefab.gameObject).GetComponent<Text>();
  97. desc.transform.SetParent(_descContent);
  98. desc.transform.localScale = Vector3.one;
  99. //Text desc = ObjectPool.Instance.GetObject(DESCPOOL, _descContent).GetComponent<Text>();
  100. desc.text = _datas[i]._desc;
  101. Vector2 pos = _vertexs[i];
  102. if (Mathf.Abs(pos.x) >= 0.1f)
  103. pos.x += _descSpace * (pos.x > 0 ? 1 : -1);
  104. if (Mathf.Abs(pos.y) >= 0.1f)
  105. pos.y += _descSpace * (pos.y > 0 ? 1 : -1);
  106. desc.rectTransform.localPosition = pos;
  107. desc.gameObject.SetActive(true);
  108. }
  109. }
  110. /// <summary>
  111. /// 获取顶点
  112. /// </summary>
  113. /// <returns></returns>
  114. private void GetVertexs()
  115. {
  116. _perRadian = Mathf.PI * 2 / _datas.Length;
  117. _vertexs = new Vector2[_datas.Length];
  118. for (int i = 0; i < _datas.Length; i++)
  119. {
  120. float radian = _perRadian * i + 90 * Mathf.Deg2Rad;
  121. Vector2 endPos = new Vector2(Mathf.Cos(radian), Mathf.Sin(radian)) * _radius;
  122. _vertexs[i] = endPos;
  123. }
  124. }
  125. /// <summary>
  126. /// 获取一条线的四个顶点
  127. /// </summary>
  128. /// <param name="startPos"></param>
  129. /// <param name="endPos"></param>
  130. /// <returns></returns>
  131. private UIVertex[] GetQuad(Vector2 startPos, Vector2 endPos, Color color, float width)
  132. {
  133. float dis = Vector2.Distance(startPos, endPos);
  134. float x = width / 2 * (endPos.y - startPos.y) / dis;//sin
  135. float y = width / 2 * (endPos.x - startPos.x) / dis;//cos
  136. if (y <= 0) y = -y;
  137. else x = -x;
  138. UIVertex[] vertex = new UIVertex[4];
  139. vertex[0].position = new Vector3(startPos.x + x, startPos.y + y);
  140. vertex[1].position = new Vector3(endPos.x + x, endPos.y + y);
  141. vertex[2].position = new Vector3(endPos.x - x, endPos.y - y);
  142. vertex[3].position = new Vector3(startPos.x - x, startPos.y - y);
  143. for (int i = 0; i < vertex.Length; i++)
  144. vertex[i].color = color;
  145. return vertex;
  146. }
  147. /// <summary>
  148. /// 入池
  149. /// </summary>
  150. /// <param name="trans"></param>
  151. /// <param name="pool"></param>
  152. private void ClearTransform(Transform parent)
  153. {
  154. for (int i = 1; i < parent.childCount; i++)
  155. {
  156. GameObject.Destroy(parent.GetChild(i).gameObject);
  157. }
  158. }
  159. }