How to scroll a ScrollRect at a constant speed, regardless of the size of the content.

Hi all, I am having trouble writing a script to scroll a ScrollRect at a constant speed, regardless of the size of the content.

I have a ScrollRect with a mask, with a text layer using the contentfitter component.

I have a scroll bar (which is invisible) and I set the value through code to scroll a dialog window. Simple stuff…

But of course, seeing as the min and max value is 0 - 1, that means that when there is little text, it scrolls slowly, and when there is loads it scrolls super fast.

Thats because I was using:

        if (_player.GetAxis("WheelScroll") > 0)
        {
            scroller.value += scrollSpeedMouse;
        }

Clearly that wont work.

So I figured that I needed to find some way to scale the speed, based on the height of the content maybe…

So I tried the following:

public float textHeight;
public Text dialogText;
float textHeight;

textHeight = dialogText.preferredHeight;

if (_player.GetAxis("WheelScroll") > 0)
{
            scroller.value += scrollSpeedMouse * textHeight;
}

I thought that this might work, but alas it still doesnt scale well.

I’m probably being dumb here, but there must be a way to scroll at a constant speed regardless of the content size…

Any ideas?

The value between 0 and 1 in scrolling is about how much extra height the inner content has compared to the scroll view. 0 means the top of the content will match the top of the view and 1 means the bottom of the content match the bottom of the view; so the movement is contentHeight - viewHeight.

So here you should use the (textHeight - viewHeight) in your calculations not the textHeight only.
Also you should divide speed by height to map it to 0…1 not multiply it. Multiply would make it go faster you have more extra content.

2 Likes
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class Test_SV : MonoBehaviour {
    public ScrollRect sRect;
    // Use this for initialization
    void Start () {
   
    }
   
    // Update is called once per frame
    void Update () {
        if (sRect.verticalNormalizedPosition < 1)
        {
            sRect.verticalNormalizedPosition += Time.deltaTime;//Move Vertical
        }
        else
        {
            sRect.verticalNormalizedPosition = 0.0f;
        }
    }
}

Hey both, thanks so much for helping out :slight_smile:

I tried the calculation that @mahdi_jeddi suggested and it worked great :slight_smile:

1 Like