using System; using System.Collections.Generic; using System.Collections; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using Platinio.UI; /// /// Code to handle generic scroll list, like leaderboards or achievements /// public class Scroller : MonoBehaviour , IPointerDownHandler , IPointerUpHandler , IPointerExitHandler { public enum ScrollMode { Horizontal, Vertical } #region INSPECTOR [SerializeField] protected ScrollRect scroll = null; [SerializeField] protected GridLayoutGroup gridLayout = null; [SerializeField] protected RectTransform viewRect = null; [SerializeField] protected ScrollMode scrollMode = ScrollMode.Horizontal; [SerializeField] protected bool shouldAling = false; [SerializeField] protected float scrollVelocityThreshold = 0.2f; #endregion #region PRIVATE private List elements = new List(); private RectTransform contentRect = null; private Coroutine shouldAlingCoroutine = null; private float minSize = 0.0f; private bool userInteraction = false; #endregion protected RectTransform scrollRect = null; protected Action onReachEndOfList = null; public GridLayoutGroup GridLayout { get { return gridLayout; } } protected virtual void Awake() { scrollRect = scroll.GetComponent(); contentRect = gridLayout.GetComponent(); minSize = contentRect.rect.size.y; SetupScrollingComponets(); //set listener for end of list scroll.onValueChanged.AddListener( delegate (Vector2 v) { if (userInteraction && scroll.velocity.magnitude > scrollVelocityThreshold) { if (shouldAlingCoroutine != null) StopCoroutine( shouldAlingCoroutine ); shouldAlingCoroutine = StartCoroutine( ShouldAlingRoutine() ); } if (GetNormalizedPosition() <= 0.0f && onReachEndOfList != null) { onReachEndOfList(); } } ); } private void Start() { GetStartingElements(); ResizeContentRect(); } private void GetStartingElements() { for (int n = 0; n < gridLayout.transform.childCount; n++) { AddElement( gridLayout.transform.GetChild(n).gameObject ); } } public float GetNormalizedPosition() { return scrollMode == ScrollMode.Horizontal ? scroll.horizontalNormalizedPosition : scroll.verticalNormalizedPosition; } private void SetupScrollingComponets() { gridLayout.startAxis = scrollMode == ScrollMode.Horizontal ? GridLayoutGroup.Axis.Horizontal : GridLayoutGroup.Axis.Vertical; scroll.vertical = scrollMode == ScrollMode.Vertical; scroll.horizontal = scrollMode == ScrollMode.Horizontal; } /// /// add element to scroll list /// public void AddElement(GameObject element) { element.transform.parent = gridLayout.transform; element.transform.localScale = Vector3.one; elements.Add( element ); ResizeContentRect(); } private IEnumerator ShouldAlingRoutine() { while (scroll.velocity.magnitude > 0.00001f) { yield return new WaitForEndOfFrame(); } AlingToCloserElement(); } private void AlingToCloserElement() { userInteraction = false; Vector2 pos = elements[0].GetComponent().FromAnchoredPositionToAbsolutePosition(viewRect); Debug.Log(pos); } /// /// Resizes the content rect to fit new elements /// protected void ResizeContentRect() { float size = 0.0f; if (scrollMode == ScrollMode.Horizontal) { size = ((gridLayout.cellSize.x + gridLayout.spacing.x) * elements.Count) + gridLayout.padding.left; } else if (scrollMode == ScrollMode.Vertical) { size = (( gridLayout.cellSize.y + gridLayout.spacing.y ) * elements.Count) + gridLayout.padding.top; } //resize contentRect to fit new element if (size > minSize) { if (scrollMode == ScrollMode.Vertical) { contentRect.SetSizeWithCurrentAnchors( RectTransform.Axis.Vertical, size ); } else if (scrollMode == ScrollMode.Horizontal) { contentRect.SetSizeWithCurrentAnchors( RectTransform.Axis.Horizontal, size ); } //reposition Vector2 pos = contentRect.anchoredPosition; if (scrollMode == ScrollMode.Vertical) { contentRect.anchoredPosition = new Vector2( pos.x, pos.y - ( ( gridLayout.cellSize.y + gridLayout.spacing.y ) / 2.0f ) ); } else if (scrollMode == ScrollMode.Horizontal) { contentRect.anchoredPosition = new Vector2( pos.x + ( ( gridLayout.cellSize.x + gridLayout.spacing.x ) / 2.0f ), pos.y ); } } } /// /// Deletes all elements from list /// protected void ClearList() { for (int n = 0; n < elements.Count; n++) { Destroy( elements[n].gameObject ); } elements = new List(); contentRect.SetSizeWithCurrentAnchors( RectTransform.Axis.Vertical, minSize ); } public void OnPointerDown(PointerEventData eventData) { userInteraction = true; } public void OnPointerUp(PointerEventData eventData) { userInteraction = false; } public void OnPointerExit(PointerEventData eventData) { userInteraction = false; } }