108 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // Copyright (c) Pixel Crushers. All rights reserved.
 | |
| 
 | |
| using UnityEngine;
 | |
| using System.Collections;
 | |
| 
 | |
| namespace PixelCrushers
 | |
| {
 | |
| 
 | |
|     /// <summary>
 | |
|     /// Enables a scrollbar only if the content is larger than the scroll rect. This component only
 | |
|     /// only shows or hides the scrollbar when the component is enabled or when CheckScrollbar is invoked.
 | |
|     /// </summary>
 | |
|     [AddComponentMenu("")] // Use wrapper.
 | |
|     public class UIScrollbarEnabler : MonoBehaviour
 | |
|     {
 | |
| 
 | |
|         [Tooltip("The scroll rect.")]
 | |
|         [UnityEngine.Serialization.FormerlySerializedAs("container")]
 | |
|         public UnityEngine.UI.ScrollRect scrollRect = null;
 | |
| 
 | |
|         [Tooltip("The content inside the scroll rect. The scrollbar will be enabled if the content is taller than the scroll rect.")]
 | |
|         [UnityEngine.Serialization.FormerlySerializedAs("content")]
 | |
|         public RectTransform scrollContent = null;
 | |
| 
 | |
|         [Tooltip("The scrollbar to enable or disable. If scroll rect doesn't have a scrollbar, just scrolls scroll rect.")]
 | |
|         public UnityEngine.UI.Scrollbar scrollbar = null;
 | |
| 
 | |
|         [Tooltip("Scroll smoothly instead of jumping to reset value.")]
 | |
|         public bool smoothScroll = false;
 | |
| 
 | |
|         public float smoothScrollSpeed = 5;
 | |
| 
 | |
|         protected bool m_started = false;
 | |
|         protected bool m_checking = false;
 | |
|         protected RectTransform m_scrollRectTransform = null;
 | |
| 
 | |
|         protected virtual void Start()
 | |
|         {
 | |
|             m_started = true;
 | |
|             CheckScrollbar();
 | |
|         }
 | |
| 
 | |
|         public virtual void OnEnable()
 | |
|         {
 | |
|             if (m_started) CheckScrollbar();
 | |
|         }
 | |
| 
 | |
|         public virtual void OnDisable()
 | |
|         {
 | |
|             m_checking = false;
 | |
|         }
 | |
| 
 | |
|         public virtual void CheckScrollbar()
 | |
|         {
 | |
|             if (m_checking || scrollRect == null || scrollContent == null || !gameObject.activeInHierarchy || !enabled) return;
 | |
|             StopAllCoroutines();
 | |
|             StartCoroutine(CheckScrollbarAfterUIUpdate(false, 0));
 | |
|         }
 | |
| 
 | |
|         public virtual void CheckScrollbarWithResetValue(float value)
 | |
|         {
 | |
|             if (m_checking || scrollRect == null || scrollContent == null || !gameObject.activeInHierarchy || !enabled) return;
 | |
|             StopAllCoroutines();
 | |
|             StartCoroutine(CheckScrollbarAfterUIUpdate(true, value));
 | |
|         }
 | |
| 
 | |
|         protected virtual IEnumerator CheckScrollbarAfterUIUpdate(bool useResetValue, float resetValue)
 | |
|         {
 | |
|             m_checking = true;
 | |
|             yield return null;
 | |
|             if (scrollbar != null)
 | |
|             {
 | |
|                 scrollbar.gameObject.SetActive(scrollContent.rect.height > scrollRect.GetComponent<RectTransform>().rect.height);
 | |
|             }
 | |
|             m_checking = false;
 | |
|             yield return null;
 | |
|             if (useResetValue)
 | |
|             {
 | |
|                 if (smoothScroll)
 | |
|                 {
 | |
|                     var contentHeight = scrollContent.rect.height;
 | |
|                     if (m_scrollRectTransform == null) m_scrollRectTransform = scrollRect.GetComponent<RectTransform>();
 | |
|                     var scrollRectHeight = m_scrollRectTransform.rect.height;
 | |
|                     var needToScroll = contentHeight > scrollRectHeight;
 | |
|                     if (needToScroll)
 | |
|                     {
 | |
|                         var ratio = scrollRectHeight / contentHeight;
 | |
|                         var timeout = Time.time + 10f; // Avoid infinite loops by maxing out at 10 seconds.
 | |
|                         while (scrollRect.verticalNormalizedPosition > 0.01f && Time.time < timeout)
 | |
|                         {
 | |
|                             var newPos = scrollRect.verticalNormalizedPosition - smoothScrollSpeed * Time.deltaTime * ratio;
 | |
|                             scrollRect.verticalNormalizedPosition = Mathf.Max(0, newPos);
 | |
|                             yield return null;
 | |
|                         }
 | |
|                     }
 | |
|                     scrollRect.verticalNormalizedPosition = 0;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if (scrollbar != null) scrollbar.value = resetValue;
 | |
|                     scrollRect.verticalNormalizedPosition = resetValue;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| }
 | 
