Search Unity

Showcase SmoothScrollRect

Discussion in 'Scripting' started by Leuki, Feb 19, 2023.

  1. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    Figured I'd share my smooth scrollrect script. This script extends the ScrollRect class and provides a smooth scrolling effect on mobile devices using the Vector2.SmoothDamp method. It also calculates the nearest anchor point to snap the content to when the scrolling ends.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4.  
    5. public class SmoothScrollRect : ScrollRect
    6. {
    7.     [SerializeField] private float _smoothTime = 0.3f;
    8.  
    9.     private Vector2 _velocity;
    10.  
    11.     protected override void LateUpdate()
    12.     {
    13.         if (!Input.GetMouseButton(0) && content != null)
    14.         {
    15.             Vector2 targetPosition = CalculateTargetPosition();
    16.  
    17.             if ((targetPosition - content.anchoredPosition).magnitude > 0.1f)
    18.             {
    19.                 content.anchoredPosition = Vector2.SmoothDamp(content.anchoredPosition, targetPosition, ref _velocity, _smoothTime);
    20.             }
    21.             else
    22.             {
    23.                 content.anchoredPosition = targetPosition;
    24.             }
    25.         }
    26.     }
    27.  
    28.     private Vector2 CalculateTargetPosition()
    29.     {
    30.         Vector2 targetPosition = content.anchoredPosition;
    31.  
    32.         if (vertical && Mathf.Abs(_velocity.y) > 0.1f)
    33.         {
    34.             targetPosition.y += _velocity.y * Time.deltaTime;
    35.         }
    36.  
    37.         if (horizontal && Mathf.Abs(_velocity.x) > 0.1f)
    38.         {
    39.             targetPosition.x += _velocity.x * Time.deltaTime;
    40.         }
    41.  
    42.         targetPosition = CalculateNearestAnchor(targetPosition);
    43.  
    44.         return targetPosition;
    45.     }
    46.  
    47.     private Vector2 CalculateNearestAnchor(Vector2 position)
    48.     {
    49.         float distance = Mathf.Infinity;
    50.         Vector2 nearestAnchor = position;
    51.  
    52.         foreach (Transform anchor in content)
    53.         {
    54.             if (!anchor.gameObject.activeInHierarchy) continue;
    55.  
    56.             float currentDistance = Vector2.Distance(position, anchor.position);
    57.             if (currentDistance < distance)
    58.             {
    59.                 distance = currentDistance;
    60.                 nearestAnchor = anchor.position;
    61.             }
    62.         }
    63.  
    64.         return nearestAnchor;
    65.     }
    66.  
    67.     public override void OnBeginDrag(PointerEventData eventData)
    68.     {
    69.         base.OnBeginDrag(eventData);
    70.         _velocity = Vector2.zero;
    71.     }
    72.  
    73.     public override void OnEndDrag(PointerEventData eventData)
    74.     {
    75.         base.OnEndDrag(eventData);
    76.     }
    77. }
    78.  
     
    ShidaPenns likes this.