diff --git a/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs b/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs index 5ef840c2..8063906c 100644 --- a/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs +++ b/Runtime/Scripts/Controls/ReorderableList/ReorderableList.cs @@ -32,6 +32,9 @@ public class ReorderableList : MonoBehaviour [Tooltip("Should items being dragged over this list have their sizes equalized?")] public bool EqualizeSizesOnDrag = false; + [Tooltip("Should items keep the original rotation?")] + public bool KeepItemRotation = false; + [Tooltip("Maximum number of items this container can hold")] public int maxItems = int.MaxValue; diff --git a/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs b/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs index eb1484cd..8a09c32b 100644 --- a/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs +++ b/Runtime/Scripts/Controls/ReorderableList/ReorderableListElement.cs @@ -266,7 +266,10 @@ private void displaceElement(int targetIndex, Transform displaced) _displacedObjectLE.preferredWidth = _draggingObjectOriginalSize.x; _displacedObjectLE.preferredHeight = _draggingObjectOriginalSize.y; _displacedObject.SetParent(_reorderableList.Content, false); - _displacedObject.rotation = _reorderableList.transform.rotation; + if (!_reorderableList.KeepItemRotation) + { + _displacedObject.rotation = _reorderableList.transform.rotation; + } _displacedObject.SetSiblingIndex(_fromIndex); // Force refreshing both lists because otherwise we get inappropriate FromList in ReorderableListEventStruct _reorderableList.Refresh(); @@ -310,7 +313,10 @@ private void revertDisplacedElement() _displacedObjectLE.preferredWidth = _displacedObjectOriginalSize.x; _displacedObjectLE.preferredHeight = _displacedObjectOriginalSize.y; _displacedObject.SetParent(_displacedObjectOriginList.Content, false); - _displacedObject.rotation = _displacedObjectOriginList.transform.rotation; + if (!_reorderableList.KeepItemRotation) + { + _displacedObject.rotation = _displacedObjectOriginList.transform.rotation; + } _displacedObject.SetSiblingIndex(_displacedFromIndex); _displacedObject.gameObject.SetActive(true); @@ -382,7 +388,10 @@ public void OnEndDrag(PointerEventData eventData) RefreshSizes(); _draggingObject.SetParent(_currentReorderableListRaycasted.Content, false); - _draggingObject.rotation = _currentReorderableListRaycasted.transform.rotation; + if (!_reorderableList.KeepItemRotation) + { + _draggingObject.rotation = _currentReorderableListRaycasted.transform.rotation; + } _draggingObject.SetSiblingIndex(_fakeElement.GetSiblingIndex()); //If the item is transferable, it can be dragged out again @@ -474,7 +483,10 @@ private void CancelDrag() { RefreshSizes(); _draggingObject.SetParent(_reorderableList.Content, false); - _draggingObject.rotation = _reorderableList.Content.transform.rotation; + if (!_reorderableList.KeepItemRotation) + { + _draggingObject.rotation = _reorderableList.Content.transform.rotation; + } _draggingObject.SetSiblingIndex(_fromIndex); diff --git a/Runtime/Scripts/Effects/Gradient2.cs b/Runtime/Scripts/Effects/Gradient2.cs index 624326a2..cbb0485d 100644 --- a/Runtime/Scripts/Effects/Gradient2.cs +++ b/Runtime/Scripts/Effects/Gradient2.cs @@ -9,6 +9,12 @@ /// using System; using System.Collections.Generic; +#if UNITY_2021_2_OR_NEWER +using System.Buffers; +#endif +#if UNITY_2021_1_OR_NEWER +using UnityEngine.Pool; +#endif namespace UnityEngine.UI.Extensions { @@ -36,6 +42,9 @@ public class Gradient2 : BaseMeshEffect [SerializeField] UnityEngine.Gradient _effectGradient = new UnityEngine.Gradient() { colorKeys = new GradientColorKey[] { new GradientColorKey(Color.black, 0), new GradientColorKey(Color.white, 1) } }; + private GradientColorKey[] _colorKeys; + private GradientAlphaKey[] _alphaKeys; + #region Properties public Blend BlendMode { @@ -103,7 +112,11 @@ public override void ModifyMesh(VertexHelper helper) if (!IsActive() || helper.currentVertCount == 0) return; +#if UNITY_2021_1_OR_NEWER + List _vertexList = ListPool.Get(); +#else List _vertexList = new List(); +#endif helper.GetUIVertexStream(_vertexList); @@ -218,7 +231,7 @@ public override void ModifyMesh(VertexHelper helper) helper.AddVert(centralVertex); - for (int i = 1; i < steps; i++) helper.AddTriangle(i - 1, i, steps); + for (int i = 1; i < steps; i++) helper.AddTriangle(i, i-1, steps); helper.AddTriangle(0, steps - 1, steps); } @@ -238,6 +251,10 @@ public override void ModifyMesh(VertexHelper helper) } break; } + +#if UNITY_2021_1_OR_NEWER + ListPool.Release(_vertexList); +#endif } Rect GetBounds(List vertices) @@ -264,7 +281,11 @@ Rect GetBounds(List vertices) void SplitTrianglesAtGradientStops(List _vertexList, Rect bounds, float zoomOffset, VertexHelper helper) { - List stops = FindStops(zoomOffset, bounds); +#if UNITY_2021_1_OR_NEWER + List stops = FindStops(zoomOffset, bounds, ListPool.Get()); +#else + List stops = FindStops(zoomOffset, bounds, new List()); +#endif if (stops.Count > 0) { helper.Clear(); @@ -272,10 +293,23 @@ void SplitTrianglesAtGradientStops(List _vertexList, Rect bounds, floa int nCount = _vertexList.Count; for (int i = 0; i < nCount; i += 3) { - float[] positions = GetPositions(_vertexList, i); +#if UNITY_2021_2_OR_NEWER + var positions = ArrayPool.Shared.Rent(3); +#else + var positions = new float[3]; +#endif + + GetPositions(_vertexList, i, ref positions); + +#if UNITY_2021_1_OR_NEWER + List originIndices = ListPool.Get(); + List starts = ListPool.Get(); + List ends = ListPool.Get(); +#else List originIndices = new List(3); List starts = new List(3); List ends = new List(2); +#endif for (int s = 0; s < stops.Count; s++) { @@ -403,13 +437,24 @@ void SplitTrianglesAtGradientStops(List _vertexList, Rect bounds, floa int vertexCount = helper.currentVertCount; helper.AddTriangle(vertexCount - 3, vertexCount - 2, vertexCount - 1); } + +#if UNITY_2021_2_OR_NEWER + ArrayPool.Shared.Return(positions); +#endif +#if UNITY_2021_1_OR_NEWER + ListPool.Release(originIndices); + ListPool.Release(starts); + ListPool.Release(ends); +#endif } } +#if UNITY_2021_1_OR_NEWER + ListPool.Release(stops); +#endif } - float[] GetPositions(List _vertexList, int index) + void GetPositions(List _vertexList, int index, ref float[] positions) { - float[] positions = new float[3]; if (GradientType == Type.Horizontal) { positions[0] = _vertexList[index].position.x; @@ -422,24 +467,27 @@ float[] GetPositions(List _vertexList, int index) positions[1] = _vertexList[index + 1].position.y; positions[2] = _vertexList[index + 2].position.y; } - return positions; } - - List FindStops(float zoomOffset, Rect bounds) + + List FindStops(float zoomOffset, Rect bounds, List stops) { - List stops = new List(); var offset = Offset * (1 - zoomOffset); var startBoundary = zoomOffset - offset; var endBoundary = (1 - zoomOffset) - offset; - foreach (var color in EffectGradient.colorKeys) + if (_colorKeys == null) _colorKeys = EffectGradient.colorKeys; + + foreach (var color in _colorKeys) { if (color.time >= endBoundary) break; if (color.time > startBoundary) stops.Add((color.time - startBoundary) * Zoom); } - foreach (var alpha in EffectGradient.alphaKeys) + + if (_alphaKeys == null) _alphaKeys = _effectGradient.alphaKeys; + + foreach (var alpha in _alphaKeys) { if (alpha.time >= endBoundary) break; @@ -455,7 +503,13 @@ List FindStops(float zoomOffset, Rect bounds) size = bounds.height; } - stops.Sort(); + stops.Sort((x, y) => + { + if (x > y) return 1; + if (x == y) return 0; + return -1; + }); + for (int i = 0; i < stops.Count; i++) { stops[i] = (stops[i] * size) + min; diff --git a/Runtime/Scripts/Layout/ScrollSnapBase.cs b/Runtime/Scripts/Layout/ScrollSnapBase.cs index d200bef0..bca4aa1b 100644 --- a/Runtime/Scripts/Layout/ScrollSnapBase.cs +++ b/Runtime/Scripts/Layout/ScrollSnapBase.cs @@ -189,6 +189,11 @@ void Awake() _screensContainer = _scroll_rect.content; + //ScrollRect.content RT anchors has to be stretched first in order for HSS/VSS.DistributePages() to have the correct result + _screensContainer.anchorMin = Vector2.zero; + _screensContainer.anchorMax = Vector2.one; + _screensContainer.sizeDelta = Vector2.zero; + InitialiseChildObjects(); if (NextButton) diff --git a/Runtime/Scripts/Primitives/UILineRenderer.cs b/Runtime/Scripts/Primitives/UILineRenderer.cs index 4f836c2c..35f4381d 100644 --- a/Runtime/Scripts/Primitives/UILineRenderer.cs +++ b/Runtime/Scripts/Primitives/UILineRenderer.cs @@ -499,10 +499,6 @@ protected override void OnEnable() { m_points = new Vector2[1]; } - if (transform.GetComponent().position != Vector3.zero) - { - Debug.LogWarning("A Line Renderer component should be on a RectTransform positioned at (0,0,0), do not use in child Objects.\nFor best results, create separate RectTransforms as children of the canvas positioned at (0,0) for a UILineRenderer and do not move."); - } } } } diff --git a/Runtime/Scripts/Utilities/UILineConnector.cs b/Runtime/Scripts/Utilities/UILineConnector.cs index 77a3fc93..7423d53e 100644 --- a/Runtime/Scripts/Utilities/UILineConnector.cs +++ b/Runtime/Scripts/Utilities/UILineConnector.cs @@ -12,32 +12,50 @@ public class UILineConnector : MonoBehaviour // The elements between which line segments should be drawn public RectTransform[] transforms; private Vector3[] previousPositions; - private RectTransform canvas; + private Vector3 previousLrPos; + private Vector3 previousGlobalScale; private RectTransform rt; private UILineRenderer lr; private void Awake() { - var canvasParent = GetComponentInParent().GetParentCanvas(); - if (canvasParent != null) - { - canvas = canvasParent.GetComponent(); - } rt = GetComponent(); lr = GetComponent(); } - // Update is called once per frame - void Update() + private void OnEnable() { if (transforms == null || transforms.Length < 1) { return; } - //Performance check to only redraw when the child transforms move - if (previousPositions != null && previousPositions.Length == transforms.Length) + + CalculateLinePoints(); + } + + private void Update() + { + if (lr.RelativeSize) + { + Debug.LogWarning("While using UILineConnector, UILineRenderer should not use relative size, so that even if this RectTransform has a zero-size Rect, the positions of the points can still be calculated"); + lr.RelativeSize = false; + } + + if (transforms == null || transforms.Length < 1) + { + return; + } + + // Get world position of UILineRenderer + Vector3 lrWorldPos = rt.position; + + /*Performance check to only redraw when the child transforms move, + or the world position of UILineRenderer moves */ + bool updateLine = lrWorldPos != previousLrPos; + updateLine = rt.lossyScale != previousGlobalScale; + + if (!updateLine && previousPositions != null && previousPositions.Length == transforms.Length) { - bool updateLine = false; for (int i = 0; i < transforms.Length; i++) { if (transforms[i] == null) @@ -47,56 +65,48 @@ void Update() if (!updateLine && previousPositions[i] != transforms[i].position) { updateLine = true; + break; } } - if (!updateLine) return; - } + } + if (!updateLine) return; - // Get the pivot points - Vector2 thisPivot = rt.pivot; - Vector2 canvasPivot = canvas.pivot; - // Set up some arrays of coordinates in various reference systems - Vector3[] worldSpaces = new Vector3[transforms.Length]; - Vector3[] canvasSpaces = new Vector3[transforms.Length]; - Vector2[] points = new Vector2[transforms.Length]; + // Calculate delta from the local position + CalculateLinePoints(); + - // First, convert the pivot to worldspace + //save previous states + previousLrPos = lrWorldPos; + previousGlobalScale = rt.lossyScale; + previousPositions = new Vector3[transforms.Length]; for (int i = 0; i < transforms.Length; i++) { if (transforms[i] == null) { continue; } - worldSpaces[i] = transforms[i].TransformPoint(thisPivot); - } - - // Then, convert to canvas space - for (int i = 0; i < transforms.Length; i++) - { - canvasSpaces[i] = canvas.InverseTransformPoint(worldSpaces[i]); - } - - // Calculate delta from the canvas pivot point - for (int i = 0; i < transforms.Length; i++) - { - points[i] = new Vector2(canvasSpaces[i].x, canvasSpaces[i].y); + previousPositions[i] = transforms[i].position; } + } - // And assign the converted points to the line renderer - lr.Points = points; - lr.RelativeSize = false; - lr.drivenExternally = true; - - previousPositions = new Vector3[transforms.Length]; + private void CalculateLinePoints() + { + Vector2[] points = new Vector2[transforms.Length]; for (int i = 0; i < transforms.Length; i++) { if (transforms[i] == null) { continue; } - previousPositions[i] = transforms[i].position; + var offsetPos = rt.InverseTransformPoint(transforms[i].position); + points[i] = new Vector2(offsetPos.x, offsetPos.y); } + + // And assign the converted points to the line renderer + lr.Points = points; + lr.RelativeSize = false; + lr.drivenExternally = true; } } } \ No newline at end of file diff --git a/package.json b/package.json index 591a6824..70ac69b1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "com.unity.uiextensions", "displayName": "Unity UI Extensions", - "version": "2.3.2", + "version": "2.3.3", "description": "An extension project for the Unity3D UI system, all crafted and contributed by the awesome Unity community", "author": "Simon darkside Jackson <@SimonDarksideJ>", "contributors": [