Line.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. public void SetLine(List<Vector2> screenPositions)
  17. {
  18. this.screenPositions = screenPositions;
  19. SetVerticesDirty();
  20. }
  21. protected override void OnPopulateMesh(VertexHelper vh)
  22. {
  23. vh.Clear();
  24. SetVertex(vh);
  25. SetTriangles(vh);
  26. }
  27. private void SetVertex(VertexHelper vh)
  28. {
  29. UIVertex vert = UIVertex.simpleVert;
  30. vert.color = color;
  31. if (screenPositions.Count < 2)
  32. return;
  33. List<Vector2> _screenPositions = screenPositions.ToList();
  34. if (loop) {
  35. //添加多两个顶点。形成闭环
  36. _screenPositions.Add(screenPositions[0]);
  37. _screenPositions.Add(screenPositions[1]);
  38. }
  39. float lastAngle = 0;
  40. for (int i = 1; i < _screenPositions.Count; i++)
  41. {
  42. Vector2 previousPos = _screenPositions[i - 1];
  43. Vector2 currentPos = _screenPositions[i];
  44. Vector2 dif = currentPos - previousPos;
  45. float angle = Vector2.SignedAngle(Vector2.right, dif);
  46. if (i > 1)
  47. {
  48. float anglePerRound = (angle - lastAngle) / roundCount;
  49. for (int j = 0; j < roundCount; j++)
  50. {
  51. float ang = lastAngle + anglePerRound * j;
  52. Vector2 roundOffset = Quaternion.Euler(0, 0, ang) * Vector2.up * thickness;
  53. vert.position = previousPos - roundOffset;
  54. vh.AddVert(vert);
  55. vert.position = previousPos + roundOffset;
  56. vh.AddVert(vert);
  57. }
  58. }
  59. lastAngle = angle;
  60. Vector2 offset = (Vector2)(Quaternion.Euler(0, 0, angle) * Vector3.up * thickness);
  61. vert.position = previousPos - offset;
  62. vh.AddVert(vert);
  63. vert.position = previousPos + offset;
  64. vh.AddVert(vert);
  65. vert.position = currentPos - offset;
  66. vh.AddVert(vert);
  67. vert.position = currentPos + offset;
  68. vh.AddVert(vert);
  69. }
  70. }
  71. private static void SetTriangles(VertexHelper vh)
  72. {
  73. for (int i = 0; i < vh.currentVertCount - 2; i += 2)
  74. {
  75. int index = i;
  76. vh.AddTriangle(index, index + 1, index + 3);
  77. vh.AddTriangle(index + 3, index + 2, index);
  78. }
  79. }
  80. }
  81. }