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): using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class SmoothScrollRect : ScrollRect { [SerializeField] private float _smoothTime = 0.3f; private Vector2 _velocity; protected override void LateUpdate() { if (!Input.GetMouseButton(0) && content != null) { Vector2 targetPosition = CalculateTargetPosition(); if ((targetPosition - content.anchoredPosition).magnitude > 0.1f) { content.anchoredPosition = Vector2.SmoothDamp(content.anchoredPosition, targetPosition, ref _velocity, _smoothTime); } else { content.anchoredPosition = targetPosition; } } } private Vector2 CalculateTargetPosition() { Vector2 targetPosition = content.anchoredPosition; if (vertical && Mathf.Abs(_velocity.y) > 0.1f) { targetPosition.y += _velocity.y * Time.deltaTime; } if (horizontal && Mathf.Abs(_velocity.x) > 0.1f) { targetPosition.x += _velocity.x * Time.deltaTime; } targetPosition = CalculateNearestAnchor(targetPosition); return targetPosition; } private Vector2 CalculateNearestAnchor(Vector2 position) { float distance = Mathf.Infinity; Vector2 nearestAnchor = position; foreach (Transform anchor in content) { if (!anchor.gameObject.activeInHierarchy) continue; float currentDistance = Vector2.Distance(position, anchor.position); if (currentDistance < distance) { distance = currentDistance; nearestAnchor = anchor.position; } } return nearestAnchor; } public override void OnBeginDrag(PointerEventData eventData) { base.OnBeginDrag(eventData); _velocity = Vector2.zero; } public override void OnEndDrag(PointerEventData eventData) { base.OnEndDrag(eventData); } }