Line.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. namespace LineUI
  6. {
  7. [RequireComponent(typeof(CanvasRenderer))]
  8. [RequireComponent(typeof(RectTransform))]
  9. public class Line : Graphic
  10. {
  11. [SerializeField] private bool loop = false;
  12. [SerializeField] private float thickness = 1f;
  13. [SerializeField] private int roundCount = 0;
  14. [SerializeField] private List<Vector2> screenPositions = new List<Vector2>();
  15. public RectTransform RectTr { get => rectTransform; }
  16. //调用的话最少10宽度
  17. public float MyThickness
  18. {
  19. get { return thickness; }
  20. set {
  21. if (value >= 10)
  22. {
  23. thickness = value;
  24. }
  25. }
  26. }
  27. public void SetLine(List<Vector2> screenPositions)
  28. {
  29. this.screenPositions = screenPositions;
  30. SetVerticesDirty();
  31. }
  32. protected override void OnPopulateMesh(VertexHelper vh)
  33. {
  34. vh.Clear();
  35. SetVertex(vh);
  36. SetTriangles(vh);
  37. }
  38. private void SetVertex(VertexHelper vh)
  39. {
  40. UIVertex vert = UIVertex.simpleVert;
  41. vert.color = color;
  42. if (screenPositions.Count < 2)
  43. return;
  44. List<Vector2> _screenPositions = screenPositions.ToList();
  45. if (loop) {
  46. //添加多两个顶点。形成闭环
  47. _screenPositions.Add(screenPositions[0]);
  48. _screenPositions.Add(screenPositions[1]);
  49. }
  50. float lastAngle = 0;
  51. for (int i = 1; i < _screenPositions.Count; i++)
  52. {
  53. Vector2 previousPos = _screenPositions[i - 1];
  54. Vector2 currentPos = _screenPositions[i];
  55. Vector2 dif = currentPos - previousPos;
  56. float angle = Vector2.SignedAngle(Vector2.right, dif);
  57. if (i > 1)
  58. {
  59. float anglePerRound = (angle - lastAngle) / roundCount;
  60. for (int j = 0; j < roundCount; j++)
  61. {
  62. float ang = lastAngle + anglePerRound * j;
  63. Vector2 roundOffset = Quaternion.Euler(0, 0, ang) * Vector2.up * thickness;
  64. vert.position = previousPos - roundOffset;
  65. vh.AddVert(vert);
  66. vert.position = previousPos + roundOffset;
  67. vh.AddVert(vert);
  68. }
  69. }
  70. lastAngle = angle;
  71. Vector2 offset = (Vector2)(Quaternion.Euler(0, 0, angle) * Vector3.up * thickness);
  72. vert.position = previousPos - offset;
  73. vh.AddVert(vert);
  74. vert.position = previousPos + offset;
  75. vh.AddVert(vert);
  76. vert.position = currentPos - offset;
  77. vh.AddVert(vert);
  78. vert.position = currentPos + offset;
  79. vh.AddVert(vert);
  80. }
  81. }
  82. private static void SetTriangles(VertexHelper vh)
  83. {
  84. for (int i = 0; i < vh.currentVertCount - 2; i += 2)
  85. {
  86. int index = i;
  87. vh.AddTriangle(index, index + 1, index + 3);
  88. vh.AddTriangle(index + 3, index + 2, index);
  89. }
  90. }
  91. }
  92. }