void ScrollMoved(Vector2 delta) { //Set the size of the content container to match the size of all of its 'children' AdjustContentSize(ElementSize * _totalNumElements); //How many elements can fit into the content area float scrollAreaSize = _scrollRect.vertical ? ((RectTransform)_scrollRect.transform).rect.height : ((RectTransform)_scrollRect.transform).rect.width; int numElementsVisibleInScrollArea = Mathf.CeilToInt(scrollAreaSize / ElementSize); //basically the number of elements culled 'above you', clamped between 0 and 'number of total emenents - number of elements that would fit in the display area' //since there is nothing lower than those last few elements int numElementsCulledAbove = Mathf.Clamp(Mathf.FloorToInt(GetScrollRectNormalizedPosition() * (_totalNumElements - numElementsVisibleInScrollArea)), 0, Mathf.Clamp(_totalNumElements - (numElementsVisibleInScrollArea + 1), 0, int.MaxValue)); //Adjust the spacers width/height and have it fill the empty space that is supposed to be taken up by all the ui elements that are being culled AdjustSpacer(numElementsCulledAbove * ElementSize); int requiredElementsInList = Mathf.Min((numElementsVisibleInScrollArea + 1), _totalNumElements); bool refreshRequired = _activeElements.Count != requiredElementsInList || _lastCulledAbove != numElementsCulledAbove; if (refreshRequired) { if (_activeElements.Count != requiredElementsInList) { InitializeElements(requiredElementsInList, numElementsCulledAbove); } else { RepurposeMethod repurposeMethod = numElementsCulledAbove > _lastCulledAbove ? RepurposeMethod.TopGoesToBottom : RepurposeMethod.BottomGoesToTop; RepurposeElement(repurposeMethod, numElementsCulledAbove); } } _lastCulledAbove = numElementsCulledAbove; }
void RepurposeElement(RepurposeMethod repurposeMethod, int numElementsCulledAbove) { if (repurposeMethod == RepurposeMethod.TopGoesToBottom) { var top = _activeElements[0]; _activeElements.RemoveAt(0); _activeElements.Add(top); top.transform.SetSiblingIndex(_activeElements[_activeElements.Count - 2].transform.GetSiblingIndex() + 1); top.Setup((numElementsCulledAbove + _activeElements.Count - 1), _scrollListData); } else { var bottom = _activeElements[_activeElements.Count - 1]; _activeElements.RemoveAt(_activeElements.Count - 1); _activeElements.Insert(0, bottom); bottom.transform.SetSiblingIndex(_activeElements[1].transform.GetSiblingIndex()); bottom.Setup((numElementsCulledAbove), _scrollListData); } }