Tanoda
UI_InfiniteScroll.cs
Go to the documentation of this file.
1
4
5using System.Collections.Generic;
6
8{
21 [AddComponentMenu("UI/Extensions/UI Infinite Scroll")]
22 public class UI_InfiniteScroll : MonoBehaviour
23 {
24 //if true user will need to call Init() method manually (in case the contend of the scrollview is generated from code or requires special initialization)
25 [Tooltip("If false, will Init automatically, otherwise you need to call Init() method")]
26 public bool InitByUser = false;
27 private ScrollRect _scrollRect;
28 private ContentSizeFitter _contentSizeFitter;
29 private VerticalLayoutGroup _verticalLayoutGroup;
30 private HorizontalLayoutGroup _horizontalLayoutGroup;
31 private GridLayoutGroup _gridLayoutGroup;
32 private bool _isVertical = false;
33 private bool _isHorizontal = false;
34 private float _disableMarginX = 0;
35 private float _disableMarginY = 0;
36 private bool _hasDisabledGridComponents = false;
37 private List<RectTransform> items = new List<RectTransform>();
38 private Vector2 _newAnchoredPosition = Vector2.zero;
39 //TO DISABLE FLICKERING OBJECT WHEN SCROLL VIEW IS IDLE IN BETWEEN OBJECTS
40 private float _treshold = 100f;
41 private int _itemCount = 0;
42 private float _recordOffsetX = 0;
43 private float _recordOffsetY = 0;
44
45 void Awake()
46 {
47 if (!InitByUser)
48 Init();
49 }
50
51 public void Init()
52 {
53 if (GetComponent<ScrollRect>() != null)
54 {
55 _scrollRect = GetComponent<ScrollRect>();
56 _scrollRect.onValueChanged.AddListener(OnScroll);
57 _scrollRect.movementType = ScrollRect.MovementType.Unrestricted;
58
59 for (int i = 0; i < _scrollRect.content.childCount; i++)
60 {
61 items.Add(_scrollRect.content.GetChild(i).GetComponent<RectTransform>());
62 }
63 if (_scrollRect.content.GetComponent<VerticalLayoutGroup>() != null)
64 {
65 _verticalLayoutGroup = _scrollRect.content.GetComponent<VerticalLayoutGroup>();
66 }
67 if (_scrollRect.content.GetComponent<HorizontalLayoutGroup>() != null)
68 {
69 _horizontalLayoutGroup = _scrollRect.content.GetComponent<HorizontalLayoutGroup>();
70 }
71 if (_scrollRect.content.GetComponent<GridLayoutGroup>() != null)
72 {
73 _gridLayoutGroup = _scrollRect.content.GetComponent<GridLayoutGroup>();
74 }
75 if (_scrollRect.content.GetComponent<ContentSizeFitter>() != null)
76 {
77 _contentSizeFitter = _scrollRect.content.GetComponent<ContentSizeFitter>();
78 }
79
80 _isHorizontal = _scrollRect.horizontal;
81 _isVertical = _scrollRect.vertical;
82
83 if (_isHorizontal && _isVertical)
84 {
85 Debug.LogError("UI_InfiniteScroll doesn't support scrolling in both directions, please choose one direction (horizontal or vertical)");
86 }
87
88 _itemCount = _scrollRect.content.childCount;
89 }
90 else
91 {
92 Debug.LogError("UI_InfiniteScroll => No ScrollRect component found");
93 }
94 }
95
96 void DisableGridComponents()
97 {
98 if (_isVertical)
99 {
100 _recordOffsetY = items[1].GetComponent<RectTransform>().anchoredPosition.y - items[0].GetComponent<RectTransform>().anchoredPosition.y;
101 if (_recordOffsetY < 0)
102 {
103 _recordOffsetY *= -1;
104 }
105 _disableMarginY = _recordOffsetY * _itemCount / 2;// _scrollRect.GetComponent<RectTransform>().rect.height/2 + items[0].sizeDelta.y;
106 }
107 if (_isHorizontal)
108 {
109 _recordOffsetX = items[1].GetComponent<RectTransform>().anchoredPosition.x - items[0].GetComponent<RectTransform>().anchoredPosition.x;
110 if (_recordOffsetX < 0)
111 {
112 _recordOffsetX *= -1;
113 }
114 _disableMarginX = _recordOffsetX * _itemCount / 2;//_scrollRect.GetComponent<RectTransform>().rect.width/2 + items[0].sizeDelta.x;
115 }
116
117 if (_verticalLayoutGroup)
118 {
119 _verticalLayoutGroup.enabled = false;
120 }
121 if (_horizontalLayoutGroup)
122 {
123 _horizontalLayoutGroup.enabled = false;
124 }
125 if (_contentSizeFitter)
126 {
127 _contentSizeFitter.enabled = false;
128 }
129 if (_gridLayoutGroup)
130 {
131 _gridLayoutGroup.enabled = false;
132 }
133 _hasDisabledGridComponents = true;
134 }
135
136 public void OnScroll(Vector2 pos)
137 {
138 if (!_hasDisabledGridComponents)
139 DisableGridComponents();
140
141 for (int i = 0; i < items.Count; i++)
142 {
143 if (_isHorizontal)
144 {
145 if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x > _disableMarginX + _treshold)
146 {
147 _newAnchoredPosition = items[i].anchoredPosition;
148 _newAnchoredPosition.x -= _itemCount * _recordOffsetX;
149 items[i].anchoredPosition = _newAnchoredPosition;
150 _scrollRect.content.GetChild(_itemCount - 1).transform.SetAsFirstSibling();
151 }
152 else if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).x < -_disableMarginX)
153 {
154 _newAnchoredPosition = items[i].anchoredPosition;
155 _newAnchoredPosition.x += _itemCount * _recordOffsetX;
156 items[i].anchoredPosition = _newAnchoredPosition;
157 _scrollRect.content.GetChild(0).transform.SetAsLastSibling();
158 }
159 }
160
161 if (_isVertical)
162 {
163 if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y > _disableMarginY + _treshold)
164 {
165 _newAnchoredPosition = items[i].anchoredPosition;
166 _newAnchoredPosition.y -= _itemCount * _recordOffsetY;
167 items[i].anchoredPosition = _newAnchoredPosition;
168 _scrollRect.content.GetChild(_itemCount - 1).transform.SetAsFirstSibling();
169 }
170 else if (_scrollRect.transform.InverseTransformPoint(items[i].gameObject.transform.position).y < -_disableMarginY)
171 {
172 _newAnchoredPosition = items[i].anchoredPosition;
173 _newAnchoredPosition.y += _itemCount * _recordOffsetY;
174 items[i].anchoredPosition = _newAnchoredPosition;
175 _scrollRect.content.GetChild(0).transform.SetAsLastSibling();
176 }
177 }
178 }
179 }
180 }
181}
UnityEngine.Debug Debug
Definition: TanodaServer.cs:19
Infinite scroll view with automatic configuration
Credit Erdener Gonenc - @PixelEnvision.