private void SetElement(UIPoolScrollElement element, int contentIndex, float position, bool addHeight, int topChange) { if (contentIndex < 0 || contentIndex >= mTotalElementCount) { return; } element.SetIndex(contentIndex); element.SetData(mData[contentIndex]); if (addHeight) { position += element.Height; } element.SetPosition(position); mCurrentTopElement += topChange; if (mCurrentTopElement < 0) { mCurrentTopElement += mElementPool.Length; } if (mCurrentTopElement >= mElementPool.Length) { mCurrentTopElement -= mElementPool.Length; } }
private void UpdateLooping() { int currentBot = mCurrentTopElement + mElementPool.Length - 1; currentBot %= mElementPool.Length; UIPoolScrollElement topElement = mElementPool[mCurrentTopElement]; UIPoolScrollElement botElement = mElementPool[currentBot]; if (topElement.IsOnScreen() > 0) { // Current top element is above the screen top, it can be moved to the bot float contentBotPosition = botElement.Bot - mSpacing; int newContentIndex = botElement.Index + 1; SetElement(topElement, newContentIndex, contentBotPosition, false, 1); } else if (topElement.Top < -mSpacing) { // Current top element's top has scrolled below the screen top, a new element need to be moved to the top float contentTopPosition = topElement.Top + mSpacing; int newContentIndex = topElement.Index - 1; SetElement(botElement, newContentIndex, contentTopPosition, true, -1); } }
private void UpdateElastic() { int currentBot = mCurrentTopElement + mElementPool.Length - 1; currentBot %= mElementPool.Length; UIPoolScrollElement topElement = mElementPool[mCurrentTopElement]; UIPoolScrollElement botElement = mElementPool[currentBot]; float offset = 0; // Elastic clamp at top if (topElement.Index <= 0) { if (topElement.Top < -mSpacing) { offset = -mSpacing - topElement.Top; } } // Elastic clamp at bot if (Mathf.Approximately(offset, 0) && botElement.Index >= mTotalElementCount - 1) { if (botElement.Bot > -mScrollHeight - mSpacing) { offset = -(botElement.Bot + mScrollHeight - mSpacing); } } if (Mathf.Approximately(offset, 0)) { return; // No clamp required } float elasticBase = 300f; float sign = Mathf.Sign(offset); float offRatio = Mathf.Clamp01(Mathf.Abs(offset) / elasticBase); float correction = 1f - (offRatio * offRatio); if (mHasInput) { // Is currently dragging if (offset > 0 != mVelocity > 0) { // Velocity is pulling elements off screen - apply velocity dampening mVelocity *= correction; } } else { // Not dragging, set velocity to return to screen mVelocity = sign * correction * elasticBase * mElasticity; float move = mVelocity * Time.deltaTime; if (Mathf.Abs(offset) < Mathf.Abs(move)) { // The next move with velocity will go past the wanted position, set the position exactly and stop velocity mVelocity = 0; Move(offset); } } }