Advertisement
pineda100

ScrollRectWorkaround

Feb 16th, 2017
556
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.82 KB | None | 0 0
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using UnityEngine.EventSystems;
  4. using System.Collections;
  5.  
  6. //THIS IS CREATED TO ADDRESS A BUG WEHERE IF THERE IS AN SCROLLBAR ATTACHED TO THE SCROLLRECT THE INERTIA FUCKS UP
  7. [RequireComponent(typeof(Scrollbar))]
  8. public class ScrollRectWorkaround : MonoBehaviour,IPointerDownHandler {
  9.  
  10. enum UpdateValue
  11. {
  12. ScrollRect,
  13. ScrollBar,
  14. None
  15. }
  16.  
  17. private Scrollbar m_scrollBar;
  18.  
  19. [SerializeField]
  20. ScrollRect m_scrollRect;
  21.  
  22. private Bounds m_ContentBounds;
  23. private Bounds m_ViewBounds;
  24.  
  25. private UpdateValue thisFrameUpdate = UpdateValue.None;
  26. private UpdateValue nextFrameUpdate = UpdateValue.None;
  27.  
  28. // Use this for initialization
  29. public void Start()
  30. {
  31. m_scrollBar = this.GetComponent<Scrollbar>();
  32.  
  33. m_scrollRect.onValueChanged.AddListener(UpdateScrollbar);
  34. m_scrollBar.onValueChanged.AddListener(UpdateScrollRect);
  35. StartCoroutine(InitializeScroll());
  36.  
  37. }
  38.  
  39. IEnumerator InitializeScroll()
  40. {
  41. yield return new WaitForEndOfFrame();
  42. UpdateScrollbar(m_scrollRect.normalizedPosition);
  43. thisFrameUpdate = UpdateValue.None;
  44. UpdateScrollRect(m_scrollBar.value);
  45. }
  46.  
  47. void LateUpdate()
  48. {
  49. thisFrameUpdate = UpdateValue.None;
  50.  
  51. if(nextFrameUpdate != UpdateValue.None)
  52. {
  53. thisFrameUpdate = nextFrameUpdate;
  54. nextFrameUpdate = UpdateValue.None;
  55. }
  56. }
  57.  
  58. public void OnPointerDown(PointerEventData eventData)
  59. {
  60. nextFrameUpdate = UpdateValue.ScrollRect;
  61. }
  62.  
  63. //ScrollBar Updates ScrollRect
  64. public void UpdateScrollRect(float value)
  65. {
  66. switch(thisFrameUpdate)
  67. {
  68. case UpdateValue.None:
  69. case UpdateValue.ScrollRect:
  70. thisFrameUpdate = UpdateValue.ScrollRect;
  71. break;
  72. default:
  73. return;
  74. }
  75.  
  76. if (m_scrollRect.horizontal)
  77. {
  78. m_scrollRect.normalizedPosition = new Vector2(value, m_scrollRect.normalizedPosition.y);
  79. }
  80. else if(m_scrollRect.vertical)
  81. {
  82. m_scrollRect.normalizedPosition = new Vector2(m_scrollRect.normalizedPosition.x, value);
  83. }
  84. }
  85.  
  86.  
  87. //Scroll Rect Updates ScrollBar
  88. public void UpdateScrollbar(Vector2 normalizedPosition)
  89. {
  90. switch (thisFrameUpdate)
  91. {
  92. case UpdateValue.None:
  93. case UpdateValue.ScrollBar:
  94. thisFrameUpdate = UpdateValue.ScrollBar;
  95. break;
  96. default:
  97. return;
  98. }
  99.  
  100. //setting offset to zero temporarily.
  101. UpdateBounds();
  102. Vector2 offset = Vector2.zero;
  103.  
  104. if (m_scrollRect.horizontal)
  105. {
  106. if (m_ContentBounds.size.x > 0)
  107. m_scrollBar.size = Mathf.Clamp01((m_ViewBounds.size.x - Mathf.Abs( offset.x)) / m_ContentBounds.size.x);
  108. else
  109. m_scrollBar.size = 1;
  110.  
  111. m_scrollBar.value = normalizedPosition.x;
  112. }
  113.  
  114. else if (m_scrollRect.vertical)
  115. {
  116. if (m_ContentBounds.size.y > 0)
  117. m_scrollBar.size = Mathf.Clamp01((m_ViewBounds.size.y - Mathf.Abs(offset.y)) / m_ContentBounds.size.y);
  118. else
  119. m_scrollBar.size = 1;
  120.  
  121. m_scrollBar.value = normalizedPosition.y;
  122. }
  123. }
  124.  
  125. private readonly Vector3[] m_Corners = new Vector3[4];
  126. private void UpdateBounds()
  127. {
  128. if (m_scrollRect.content == null)
  129. {
  130. m_ContentBounds = new Bounds();
  131. return;
  132. }
  133.  
  134. //UpdateContentBounds
  135.  
  136. m_scrollRect.content.GetWorldCorners(m_Corners);
  137.  
  138. RectTransform ViewRect = null;
  139. ViewRect = m_scrollRect.viewport;
  140.  
  141. if (ViewRect == null)
  142. ViewRect = (RectTransform)m_scrollRect.transform;
  143.  
  144. var viewWorldToLocalMatrix = ViewRect.worldToLocalMatrix;
  145. m_ContentBounds = InternalGetBounds(m_Corners, ref viewWorldToLocalMatrix);
  146.  
  147. //UpdateViewBounds
  148.  
  149. m_ViewBounds = new Bounds(ViewRect.rect.center, ViewRect.rect.size);
  150. }
  151.  
  152. internal static Bounds InternalGetBounds(Vector3[] corners, ref Matrix4x4 viewWorldToLocalMatrix)
  153. {
  154. var vMin = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
  155. var vMax = new Vector3(float.MinValue, float.MinValue, float.MinValue);
  156.  
  157. for (int j = 0; j < 4; j++)
  158. {
  159. Vector3 v = viewWorldToLocalMatrix.MultiplyPoint3x4(corners[j]);
  160. vMin = Vector3.Min(v, vMin);
  161. vMax = Vector3.Max(v, vMax);
  162. }
  163.  
  164. var bounds = new Bounds(vMin, Vector3.zero);
  165. bounds.Encapsulate(vMax);
  166. return bounds;
  167. }
  168. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement