Tanoda
HorizontalScrollSnap.cs
Go to the documentation of this file.
1
4
5using System;
7
9{
10
11 [RequireComponent(typeof(ScrollRect))]
12 [AddComponentMenu("Layout/Extensions/Horizontal Scroll Snap")]
14 {
15 void Start()
16 {
17 _isVertical = false;
18 _childAnchorPoint = new Vector2(0, 0.5f);
19 _currentPage = StartingScreen;
20 panelDimensions = gameObject.GetComponent<RectTransform>().rect;
22 }
23
24 void Update()
25 {
26 if (!_lerp && _scroll_rect.velocity == Vector2.zero)
27 {
28 if (!_settled && !_pointerDown)
29 {
30 if (!IsRectSettledOnaPage(_screensContainer.anchoredPosition))
31 {
32 ScrollToClosestElement();
33 }
34 }
35 return;
36 }
37 else if (_lerp)
38 {
39 _screensContainer.anchoredPosition = Vector3.Lerp(_screensContainer.anchoredPosition, _lerp_target, transitionSpeed * (UseTimeScale ? Time.deltaTime : Time.unscaledDeltaTime));
40 if (Vector3.Distance(_screensContainer.anchoredPosition, _lerp_target) < 0.1f)
41 {
42 _screensContainer.anchoredPosition = _lerp_target;
43 _lerp = false;
44 EndScreenChange();
45 }
46 }
47
48 CurrentPage = GetPageforPosition(_screensContainer.anchoredPosition);
49
50 //If the container is moving check if it needs to settle on a page
51 if (!_pointerDown)
52 {
53 if (_scroll_rect.velocity.x > 0.01 || _scroll_rect.velocity.x < -0.01)
54 {
55 //if the pointer is released and is moving slower than the threshold, then just land on a page
56 if (IsRectMovingSlowerThanThreshold(0))
57 {
58 ScrollToClosestElement();
59 }
60 }
61 }
62 }
63
64 private bool IsRectMovingSlowerThanThreshold(float startingSpeed)
65 {
66 return (_scroll_rect.velocity.x > startingSpeed && _scroll_rect.velocity.x < SwipeVelocityThreshold) ||
67 (_scroll_rect.velocity.x < startingSpeed && _scroll_rect.velocity.x > -SwipeVelocityThreshold);
68 }
69
70 public void DistributePages()
71 {
72 _screens = _screensContainer.childCount;
73 _scroll_rect.horizontalNormalizedPosition = 0;
74
75 float _offset = 0;
76 float _dimension = 0;
77 Rect panelDimensions = gameObject.GetComponent<RectTransform>().rect;
78 float currentXPosition = 0;
79 var pageStepValue = _childSize = (int)panelDimensions.width * ((PageStep == 0) ? 3 : PageStep);
80
81 for (int i = 0; i < _screensContainer.transform.childCount; i++)
82 {
83 RectTransform child = _screensContainer.transform.GetChild(i).gameObject.GetComponent<RectTransform>();
84 currentXPosition = _offset + i * pageStepValue;
85 child.sizeDelta = new Vector2(panelDimensions.width, panelDimensions.height);
86 child.anchoredPosition = new Vector2(currentXPosition, 0f);
87 child.anchorMin = child.anchorMax = child.pivot = _childAnchorPoint;
88 }
89
90 _dimension = currentXPosition + _offset * -1;
91
92 _screensContainer.GetComponent<RectTransform>().offsetMax = new Vector2(_dimension, 0f);
93 }
94
99 public void AddChild(GameObject GO)
100 {
101 AddChild(GO, false);
102 }
103
109 public void AddChild(GameObject GO, bool WorldPositionStays)
110 {
111 _scroll_rect.horizontalNormalizedPosition = 0;
112 GO.transform.SetParent(_screensContainer, WorldPositionStays);
113 InitialiseChildObjectsFromScene();
115 if (MaskArea)
116 UpdateVisible();
117
118 SetScrollContainerPosition();
119 }
120
127 public void RemoveChild(int index, out GameObject ChildRemoved)
128 {
129 RemoveChild(index, false, out ChildRemoved);
130 }
131
139 public void RemoveChild(int index, bool WorldPositionStays, out GameObject ChildRemoved)
140 {
141 ChildRemoved = null;
142 if (index < 0 || index > _screensContainer.childCount)
143 {
144 return;
145 }
146 _scroll_rect.horizontalNormalizedPosition = 0;
147
148 Transform child = _screensContainer.transform.GetChild(index);
149 child.SetParent(null, WorldPositionStays);
150 ChildRemoved = child.gameObject;
151 InitialiseChildObjectsFromScene();
153 if (MaskArea)
154 UpdateVisible();
155
156 if (_currentPage > _screens - 1)
157 {
158 CurrentPage = _screens - 1;
159 }
160
161 SetScrollContainerPosition();
162 }
163
168 public void RemoveAllChildren(out GameObject[] ChildrenRemoved)
169 {
170 RemoveAllChildren(false, out ChildrenRemoved);
171 }
172
178 public void RemoveAllChildren(bool WorldPositionStays, out GameObject[] ChildrenRemoved)
179 {
180 var _screenCount = _screensContainer.childCount;
181 ChildrenRemoved = new GameObject[_screenCount];
182
183 for (int i = _screenCount - 1; i >= 0; i--)
184 {
185 ChildrenRemoved[i] = _screensContainer.GetChild(i).gameObject;
186 ChildrenRemoved[i].transform.SetParent(null, WorldPositionStays);
187 }
188
189 _scroll_rect.horizontalNormalizedPosition = 0;
190 CurrentPage = 0;
191 InitialiseChildObjectsFromScene();
193 if (MaskArea)
194 UpdateVisible();
195 }
196
197 private void SetScrollContainerPosition()
198 {
199 _scrollStartPosition = _screensContainer.anchoredPosition.x;
200 _scroll_rect.horizontalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
201 OnCurrentScreenChange(_currentPage);
202 }
203
207 public void UpdateLayout()
208 {
209 _lerp = false;
211 if (MaskArea)
212 UpdateVisible();
213 SetScrollContainerPosition();
214 OnCurrentScreenChange(_currentPage);
215 }
216
217 private void OnRectTransformDimensionsChange()
218 {
219 if (_childAnchorPoint != Vector2.zero)
220 {
221 UpdateLayout();
222 }
223 }
224
225 private void OnEnable()
226 {
227 InitialiseChildObjectsFromScene();
229 if (MaskArea)
230 UpdateVisible();
231
233 SetScrollContainerPosition();
234 if (RestartOnEnable)
236 }
237
242 public override void OnEndDrag(PointerEventData eventData)
243 {
244 _pointerDown = false;
245
246 if (_scroll_rect.horizontal)
247 {
248 if (UseSwipeDeltaThreshold && Math.Abs(eventData.delta.x) < SwipeDeltaThreshold)
249 {
250 ScrollToClosestElement();
251 }
252 else
253 {
254 var distance = Vector3.Distance(_startPosition, _screensContainer.anchoredPosition);
255
256 if (UseHardSwipe)
257 {
258 _scroll_rect.velocity = Vector3.zero;
259
260 if (distance > FastSwipeThreshold)
261 {
262 if (_startPosition.x - _screensContainer.anchoredPosition.x > 0)
263 {
264 NextScreen();
265 }
266 else
267 {
269 }
270 }
271 else
272 {
273 ScrollToClosestElement();
274 }
275 }
276 else
277 {
278 if (UseFastSwipe && distance < panelDimensions.width && distance >= FastSwipeThreshold)
279 {
280 _scroll_rect.velocity = Vector3.zero;
281 if (_startPosition.x - _screensContainer.anchoredPosition.x > 0)
282 {
283 if (_startPosition.x - _screensContainer.anchoredPosition.x > _childSize / 3)
284 {
285 ScrollToClosestElement();
286 }
287 else
288 {
289 NextScreen();
290 }
291 }
292 else
293 {
294 if (_startPosition.x - _screensContainer.anchoredPosition.x < -_childSize / 3)
295 {
296 ScrollToClosestElement();
297 }
298 else
299 {
301 }
302 }
303 }
304 }
305 }
306 }
307 }
308 }
309}
Es.InkPainter.Math Math
Definition: PaintTest.cs:7
void AddChild(GameObject GO)
Add a new child to this Scroll Snap and recalculate it's children
void UpdateLayout()
used for changing / updating between screen resolutions
void RemoveChild(int index, bool WorldPositionStays, out GameObject ChildRemoved)
Remove a new child to this Scroll Snap and recalculate it's children *Note, this is an index address ...
void AddChild(GameObject GO, bool WorldPositionStays)
Add a new child to this Scroll Snap and recalculate it's children
void RemoveAllChildren(out GameObject[] ChildrenRemoved)
Remove all children from this ScrollSnap
override void OnEndDrag(PointerEventData eventData)
Release screen to swipe
void RemoveChild(int index, out GameObject ChildRemoved)
Remove a new child to this Scroll Snap and recalculate it's children *Note, this is an index address ...
void RemoveAllChildren(bool WorldPositionStays, out GameObject[] ChildrenRemoved)
Remove all children from this ScrollSnap
void GoToScreen(int screenIndex)
Function for switching to a specific screen *Note, this is based on a 0 starting index - 0 to x
Credit Erdener Gonenc - @PixelEnvision.