Tanoda
VerticalScrollSnap.cs
Go to the documentation of this file.
1
5
6using System;
8
10{
11 [RequireComponent(typeof(ScrollRect))]
12 [AddComponentMenu("Layout/Extensions/Vertical Scroll Snap")]
14 {
15 void Start()
16 {
17 _isVertical = true;
18 _childAnchorPoint = new Vector2(0.5f,0);
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.y > 0.01 || _scroll_rect.velocity.y < -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.y > startingSpeed && _scroll_rect.velocity.y < SwipeVelocityThreshold) ||
67 (_scroll_rect.velocity.y < startingSpeed && _scroll_rect.velocity.y > -SwipeVelocityThreshold);
68 }
69
70 public void DistributePages()
71 {
72 _screens = _screensContainer.childCount;
73 _scroll_rect.verticalNormalizedPosition = 0;
74
75 float _offset = 0;
76 float _dimension = 0;
77 Rect panelDimensions = gameObject.GetComponent<RectTransform>().rect;
78 float currentYPosition = 0;
79 var pageStepValue = _childSize = (int)panelDimensions.height * ((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 currentYPosition = _offset + i * pageStepValue;
85 child.sizeDelta = new Vector2(panelDimensions.width, panelDimensions.height);
86 child.anchoredPosition = new Vector2(0f, currentYPosition);
87 child.anchorMin = child.anchorMax = child.pivot = _childAnchorPoint;
88 }
89
90 _dimension = currentYPosition + _offset * -1;
91
92 _screensContainer.GetComponent<RectTransform>().offsetMax = new Vector2(0f, _dimension);
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.verticalNormalizedPosition = 0;
112 GO.transform.SetParent(_screensContainer, WorldPositionStays);
113 InitialiseChildObjectsFromScene();
115 if (MaskArea) UpdateVisible();
116
117 SetScrollContainerPosition();
118 }
119
126 public void RemoveChild(int index, out GameObject ChildRemoved)
127 {
128 RemoveChild(index, false, out ChildRemoved);
129 }
130
138 public void RemoveChild(int index, bool WorldPositionStays, out GameObject ChildRemoved)
139 {
140 ChildRemoved = null;
141 if (index < 0 || index > _screensContainer.childCount)
142 {
143 return;
144 }
145 _scroll_rect.verticalNormalizedPosition = 0;
146
147 Transform child = _screensContainer.transform.GetChild(index);
148 child.SetParent(null, WorldPositionStays);
149 ChildRemoved = child.gameObject;
150 InitialiseChildObjectsFromScene();
152 if (MaskArea) UpdateVisible();
153
154 if (_currentPage > _screens - 1)
155 {
156 CurrentPage = _screens - 1;
157 }
158
159 SetScrollContainerPosition();
160 }
161
166 public void RemoveAllChildren(out GameObject[] ChildrenRemoved)
167 {
168 RemoveAllChildren(false, out ChildrenRemoved);
169 }
170
176 public void RemoveAllChildren(bool WorldPositionStays, out GameObject[] ChildrenRemoved)
177 {
178 var _screenCount = _screensContainer.childCount;
179 ChildrenRemoved = new GameObject[_screenCount];
180
181 for (int i = _screenCount - 1; i >= 0; i--)
182 {
183 ChildrenRemoved[i] = _screensContainer.GetChild(i).gameObject;
184 ChildrenRemoved[i].transform.SetParent(null, WorldPositionStays);
185 }
186
187 _scroll_rect.verticalNormalizedPosition = 0;
188 CurrentPage = 0;
189 InitialiseChildObjectsFromScene();
191 if (MaskArea) UpdateVisible();
192 }
193
194 private void SetScrollContainerPosition()
195 {
196 _scrollStartPosition = _screensContainer.anchoredPosition.y;
197 _scroll_rect.verticalNormalizedPosition = (float)(_currentPage) / (_screens - 1);
198 OnCurrentScreenChange(_currentPage);
199 }
200
204 public void UpdateLayout()
205 {
206 _lerp = false;
208 if (MaskArea) UpdateVisible();
209 SetScrollContainerPosition();
210 OnCurrentScreenChange(_currentPage);
211 }
212
213 private void OnRectTransformDimensionsChange()
214 {
215 if (_childAnchorPoint != Vector2.zero)
216 {
217 UpdateLayout();
218 }
219 }
220
221 private void OnEnable()
222 {
223 InitialiseChildObjectsFromScene();
225 if (MaskArea) UpdateVisible();
226
227 if (JumpOnEnable || !RestartOnEnable) SetScrollContainerPosition();
229 }
230
235 public override void OnEndDrag(PointerEventData eventData)
236 {
237 _pointerDown = false;
238
239 if (_scroll_rect.vertical)
240 {
241 if (UseSwipeDeltaThreshold && Math.Abs(eventData.delta.y) < SwipeDeltaThreshold)
242 {
243 ScrollToClosestElement();
244 }
245 else
246 {
247 var distance = Vector3.Distance(_startPosition, _screensContainer.anchoredPosition);
248 if (UseHardSwipe)
249 {
250 _scroll_rect.velocity = Vector3.zero;
251
252 if (distance > FastSwipeThreshold)
253 {
254 if (_startPosition.y - _screensContainer.anchoredPosition.y > 0)
255 {
256 NextScreen();
257 }
258 else
259 {
261 }
262 }
263 else
264 {
265 ScrollToClosestElement();
266 }
267 }
268 else
269 {
270 if (UseFastSwipe && distance < panelDimensions.height + FastSwipeThreshold && distance >= 1f)
271 {
272 _scroll_rect.velocity = Vector3.zero;
273 if (_startPosition.y - _screensContainer.anchoredPosition.y > 0)
274 {
275 if (_startPosition.y - _screensContainer.anchoredPosition.y > _childSize / 3)
276 {
277 ScrollToClosestElement();
278 }
279 else
280 {
281 NextScreen();
282 }
283 }
284 else
285 {
286 if (_startPosition.y - _screensContainer.anchoredPosition.y > -_childSize / 3)
287 {
288 ScrollToClosestElement();
289 }
290 else
291 {
293 }
294 }
295 }
296 }
297 }
298 }
299 }
300 }
301}
Es.InkPainter.Math Math
Definition: PaintTest.cs:7
void GoToScreen(int screenIndex)
Function for switching to a specific screen *Note, this is based on a 0 starting index - 0 to x
void RemoveAllChildren(bool WorldPositionStays, out GameObject[] ChildrenRemoved)
Remove all children from this ScrollSnap
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 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 UpdateLayout()
used for changing / updating between screen resolutions
void RemoveAllChildren(out GameObject[] ChildrenRemoved)
Remove all children from this ScrollSnap
void AddChild(GameObject GO, bool WorldPositionStays)
Add a new child to this Scroll Snap and recalculate it's children
override void OnEndDrag(PointerEventData eventData)
Release screen to swipe
void AddChild(GameObject GO)
Add a new child to this Scroll Snap and recalculate it's children
Credit Erdener Gonenc - @PixelEnvision.