Search Unity

Question How to get smooth inertia scrolling on a scroll rect with a mouse scroll wheel?

Discussion in 'UGUI & TextMesh Pro' started by ArnoldRauers_Tinytouchtales, Nov 30, 2022.

  1. ArnoldRauers_Tinytouchtales

    ArnoldRauers_Tinytouchtales

    Joined:
    Jan 25, 2015
    Posts:
    33
    Hi,

    is there a way to get the same inertia behavior on a scroll rect that you get when click-dragging the list,
    when you use a mouse scroll wheel? The scroll wheel just moves the list without any smoothing.

    Thanks!
     
  2. ArnoldRauers_Tinytouchtales

    ArnoldRauers_Tinytouchtales

    Joined:
    Jan 25, 2015
    Posts:
    33
    Ok, with the help of my boy OpenAI Chatbot I came up with this. Works pretty well. You can use this script to replace the regular Scroll Rect script.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5. using UnityEngine.UI;
    6.  
    7. public class InertiaScrollRect : ScrollRect, IScrollHandler, IDragHandler
    8. {
    9.     // The speed at which the scrolling will slow down when inertia is applied
    10.     float decelerationRate = 2;
    11.  
    12.     // The current velocity of the scrolling
    13.     private float scrollVelocity;
    14.  
    15.     // A flag that indicates whether inertia is currently being applied
    16.     private bool isInertiaActive = true;
    17.  
    18.     // Stop inertia when you click on the list
    19.     public override void OnInitializePotentialDrag(PointerEventData eventData)
    20.     {
    21.         StopInertia();
    22.     }
    23.  
    24.     public override void OnScroll(PointerEventData eventData)
    25.     {
    26.         // Calculate the amount of scrolling that should be applied based on the mouse wheel delta
    27.  
    28.         // I had to tone the regular scroll sensitivy of 1 way down for this to be not too fast
    29.         // You can probaly mess around with the values here
    30.         float scrollDelta = eventData.scrollDelta.y * (scrollSensitivity * 0.001f);
    31.  
    32.         // If inertia is currently being applied, we need to stop it before we can apply
    33.         // the new scroll delta.
    34.         if (isInertiaActive)
    35.         {
    36.             StopInertia();
    37.         }
    38.  
    39.         float normalizedPosition = verticalNormalizedPosition;
    40.  
    41.         // Apply the scroll delta to the current normalized position
    42.         normalizedPosition += scrollDelta;
    43.  
    44.         // Set the new normalized position of the scroll rect
    45.          SetNormalizedPosition(normalizedPosition,1);
    46.  
    47.         // Start inertia scrolling with the current scroll velocity
    48.         StartInertia(scrollDelta / Time.deltaTime);
    49.     }
    50.  
    51.     // Update is called once per frame
    52.     void Update()
    53.     {
    54.         if (isInertiaActive)
    55.         {
    56.  
    57.             // Calculate the new scroll position based on the current scroll velocity
    58.             float scrollDelta = scrollVelocity * Time.deltaTime;
    59.  
    60.             float normalizedPosition = verticalNormalizedPosition;
    61.  
    62.             // Apply the scroll delta to the current normalized position
    63.             normalizedPosition += scrollDelta;
    64.  
    65.             if (normalizedPosition <= 0 || normalizedPosition >= 1)
    66.             {
    67.                 // The content has reached the top or bottom, so stop applying inertia
    68.                 StopInertia();
    69.             }
    70.             else
    71.             {
    72.                 // The content has not reached the top or bottom, so set the new normalized position
    73.                 // and continue applying inertia.
    74.                 SetNormalizedPosition(normalizedPosition, 1);
    75.  
    76.                 // Reduce the scroll velocity according to the deceleration rate
    77.                 scrollVelocity -= scrollVelocity * decelerationRate * Time.deltaTime;
    78.  
    79.                 // Check if the scroll velocity has reached 0
    80.                 if (Mathf.Abs(scrollVelocity) <= 0)
    81.                 {
    82.                     // The scroll velocity has reached 0, so stop applying inertia
    83.                     StopInertia();
    84.                 }
    85.             }
    86.         }
    87.     }
    88.  
    89.     // Start inertia scrolling with the specified scroll velocity
    90.     private void StartInertia(float velocity)
    91.     {
    92.         scrollVelocity = velocity;
    93.         isInertiaActive = true;
    94.     }
    95.  
    96.     // Stop applying inertia to the scrolling
    97.     private void StopInertia()
    98.     {
    99.         scrollVelocity = 0;
    100.         isInertiaActive = false;
    101.     }
    102. }
     
  3. rodrigolaiz

    rodrigolaiz

    Joined:
    Apr 4, 2022
    Posts:
    2
    Oh boy...!
     
  4. alessandrocesa19

    alessandrocesa19

    Joined:
    Jun 10, 2021
    Posts:
    3
    Amazing. Thanks for sharing this script with us.