diff --git a/Runtime/Scripts/Primitives/UILineRendererFIFO.cs b/Runtime/Scripts/Primitives/UILineRendererFIFO.cs new file mode 100644 index 0000000..9fa3f7a --- /dev/null +++ b/Runtime/Scripts/Primitives/UILineRendererFIFO.cs @@ -0,0 +1,146 @@ +/// Credit Steve Westhoff, jack.sydorenko, firagon +/// Sourced from - https://bitbucket.org/UnityUIExtensions/unity-ui-extensions/issues/324 +/// Refactored and updated for performance from UILineRenderer by Steve Westhoff + +using System.Collections.Generic; + +namespace UnityEngine.UI.Extensions +{ + [AddComponentMenu("UI/Extensions/Primitives/UILineRendererFIFO")] + [RequireComponent(typeof(RectTransform))] + public class UILineRendererFIFO : UIPrimitiveBase + { + private static readonly Vector2[] middleUvs = new[] { new Vector2(0.5f, 0), new Vector2(0.5f, 1), new Vector2(0.5f, 1), new Vector2(0.5f, 0) }; + private List addedPoints = new List(); + private bool needsResize; + + [SerializeField, Tooltip("Thickness of the line")] + private float lineThickness = 1; + + [SerializeField, Tooltip("Points to draw lines between\n Can be improved using the Resolution Option")] + private List points = new List(); + + [SerializeField, Tooltip("Segments to be drawn\n This is a list of arrays of points")] + private List segments = new List(); + + /// + /// Thickness of the line + /// + public float LineThickness + { + get { return lineThickness; } + set { lineThickness = value; SetAllDirty(); } + } + + /// + /// Points to be drawn in the line. + /// + /// Don't add points to the list directly, use the add / remove functions + public List Points + { + get + { + return points; + } + + set + { + if (points == value) + return; + points = value; + SetAllDirty(); + } + } + + /// + /// Adds to head + /// + /// + public void AddPoint(Vector2 point) { + points.Add(point); + addedPoints.Add(point); + } + + /// + /// Removes from tail (FIFO) + /// + public void RemovePoint() { + points.RemoveAt(0); + needsResize = true; + } + + /// + /// Clear all the points from the LineRenderer + /// + public void ClearPoints() + { + segments.Clear(); + points.Clear(); + addedPoints.Clear(); + needsResize = false; + } + + public void Resize() { + needsResize = true; + } + + protected override void OnPopulateMesh(VertexHelper vertexHelper) { + vertexHelper.Clear(); + if(needsResize) { + needsResize = false; + segments.Clear(); + addedPoints = new List(points); + } + int count = addedPoints.Count; + if(count > 1) { + PopulateMesh(addedPoints, vertexHelper); + if(count % 2 == 0) { + addedPoints.Clear(); + } else { + Vector2 extraPoint = addedPoints[count - 1]; + addedPoints.Clear(); + addedPoints.Add(extraPoint); + } + } + } + + void PopulateMesh(List pointsToDraw, VertexHelper vertexHelper) { + if(ImproveResolution != ResolutionMode.None) { + pointsToDraw = IncreaseResolution(pointsToDraw); + } + float sizeX = rectTransform.rect.width; + float sizeY = rectTransform.rect.height; + float offsetX = -rectTransform.pivot.x * sizeX; + float offsetY = -rectTransform.pivot.y * sizeY; + for(int i = 1; i < pointsToDraw.Count; i += 2) { + Vector2 start = pointsToDraw[i - 1]; + Vector2 end = pointsToDraw[i]; + start = new Vector2(start.x * sizeX + offsetX, start.y * sizeY + offsetY); + end = new Vector2(end.x * sizeX + offsetX, end.y * sizeY + offsetY); + UIVertex[] segment = CreateLineSegment(start, end, segments.Count > 1 ? segments[segments.Count - 2] : null); + segments.Add(segment); + } + for(int i = 0; i < segments.Count; i++) { + vertexHelper.AddUIVertexQuad(segments[i]); + } + if(vertexHelper.currentVertCount > 64000) { + Debug.LogError("Max Verticies size is 64000, current mesh vertcies count is [" + vertexHelper.currentVertCount + "] - Cannot Draw"); + vertexHelper.Clear(); + } + } + + UIVertex[] CreateLineSegment(Vector2 start, Vector2 end, UIVertex[] previousVert = null) { + Vector2 offset = new Vector2(start.y - end.y, end.x - start.x).normalized * lineThickness * 0.5f; + Vector2 v1; + Vector2 v2; + if(previousVert != null) { + v1 = new Vector2(previousVert[3].position.x, previousVert[3].position.y); + v2 = new Vector2(previousVert[2].position.x, previousVert[2].position.y); + } else { + v1 = start - offset; + v2 = start + offset; + } + return SetVbo(new[] { v1, v2, end + offset, end - offset }, middleUvs); + } + } +} \ No newline at end of file diff --git a/Runtime/Scripts/Primitives/UILineRendererFIFO.cs.meta b/Runtime/Scripts/Primitives/UILineRendererFIFO.cs.meta new file mode 100644 index 0000000..730d32b --- /dev/null +++ b/Runtime/Scripts/Primitives/UILineRendererFIFO.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a3a91607af301f241b9f0a860c720b21 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/Scripts/Primitives/UILineRendererList.cs b/Runtime/Scripts/Primitives/UILineRendererList.cs index 3927215..bf75976 100644 --- a/Runtime/Scripts/Primitives/UILineRendererList.cs +++ b/Runtime/Scripts/Primitives/UILineRendererList.cs @@ -118,24 +118,6 @@ namespace UnityEngine.UI.Extensions } } - // /// - // /// List of Segments to be drawn. - // /// - // public List Segments - //{ - // get - // { - // return m_segments; - // } - - // set - // { - // m_segments = value; - // SetAllDirty(); - // } - //} - - public void AddPoint(Vector2 pointToAdd) { m_points.Add(pointToAdd); @@ -298,15 +280,6 @@ namespace UnityEngine.UI.Extensions PopulateMesh (vh, m_points); } - //else if (m_segments != null && m_segments.Count > 0) { - // GeneratedUVs (); - // vh.Clear (); - - // for (int s = 0; s < m_segments.Count; s++) { - // Vector2[] pointsToDraw = m_segments [s]; - // PopulateMesh (vh, pointsToDraw); - // } - //} } private UIVertex[] CreateLineCap(Vector2 start, Vector2 end, SegmentType type)