Scroll inertia: in-depth tutorial

inertia is what keeps you going

This tutorial series on how to build a cool scrollable selection area  in unity is nearing its end, here we’ll mod the previous script to add a scroll inertia effect, so that the scroll doesn’t stop immediately when the user lifts the finger.

In last edit we added a snapping behaviour to our scroll area, and if you have not so many items to scroll that can be enough. But what if there are a lot of them? Let’s be clear, if you need to stash more than 30, I’d advice to use at least a scroll slider bar too, makes easier to navigate and keep track of what-is-where. But already with 15 or so elements it would be nice not to have to scroll through every single one of them with your finger. Let’s have one powerful slide do the job of a dozen weak ones!

Scrolling through an image gallery with inertia on
A couple scrolls can have very different effects with inertia…

Let’s set the parameters

To achieve this we’ll add an inertia “factor” to our movement, pretty much in the same way we added a magnetic force.
So, here’s how:

    [Header("inertia Parameters")]
    public bool useInertia;
    protected float inertia;
    public float inertialDampening = 0.9f; 
    public float inertiaPersistenceFactor = 10f;
  • useInertiawill be used as a control flag to switch the behaviour on and off
  • inertiais the variable where we store the movement due to inertia for the frame
  • inertialDampeningis our attrition factor, we’ll just mutiply this to last frame’s inertia to dampen it
  • inertiaPersistenceFactorinstead gives us control on how much the inertia effect should persist before being set to exactly 0

Changing the functions for scroll inertia

This time we’ll also have to change the Awake function because as of now magnetic behaviour and inertia are quite conflicting, they could produce a jerky or oscillating motion. It’s easy to merge them elegantly but that’s something I won’t do here, sorry 😛

    public virtual void Awake()
    {
        if (useInertia)
            doMagnetize = false;
    }

As for our Update function, that very predictably becomes:

    protected virtual void Update()
    {
        updateAlpha();
        updateInertia();
        updateMagnetization();
        if (Mathf.Abs(lastFrameAlpha - alpha) > 0.001f)
        {
            refreshImages();
        }
        lastFrameAlpha = alpha;
    }

Where updateInertia is:

    protected virtual void updateInertia()
    {
        if (useInertia)
        {
            inertia = Mathf.Abs(inputSource.NetSwipe.x) > 0 ? alpha - lastFrameAlpha : inertialDampening * inertia;
            if (Mathf.Abs(inertia) < rotationSensibility / inertiaPersistenceFactor)
                inertia = 0;
        }
    }

What happens here is: first we check our flag, then we evaluate if there is any input. If there is we update inertia to exactly that frame’s movement, so that we may use it later. If there is none, inertia gets its own value, dampened.

When it’s just too low to care about it, we set it to 0;

Lastly we need to insert the inertia we calculated into our updateAlpha function like this:

    protected virtual void updateAlpha()
    {
        alpha = Mathf.Clamp(
                alpha + (Mathf.Abs(inputSource.NetSwipe.x) > 0 ?
                    inputSource.NetSwipe.x * rotationSensibility
                    :
                    inertia + magneticForce), 
                0,
                1
                );
    }

See where we just sum inertia and magnetic force? there is where you want to intervene if you want to use them both without strange behaviours

And that’s it!

Now you can add inertia to your scrolling behaviour. Isn’t it cool? Last part of this tutorial series will introduce selection, which can be key to using this thing in your UIs without having the player tap on the image/button too. Don’t miss it, join my newsletter and I’ll tell you when it’s out. [edit: next part is here]

Here’s the usual copy-paste friendly version:

    [Header("inertia Parameters")]
    public bool useInertia;
    protected float inertia;
    public float inertialDampening = 0.9f; 
    public float inertiaPersistenceFactor = 10f;

    public virtual void Awake()
    {
        if (useInertia)
            doMagnetize = false;
    }
    protected virtual void Update()
    {
        updateAlpha();
        updateInertia();
        updateMagnetization();
        if (Mathf.Abs(lastFrameAlpha - alpha) > 0.001f)
        {
            refreshImages();
        }
        lastFrameAlpha = alpha;
    }

    protected virtual void updateAlpha()
    {
        alpha = Mathf.Clamp(
                alpha + (Mathf.Abs(inputSource.NetSwipe.x) > 0 ?
                    inputSource.NetSwipe.x * rotationSensibility
                    :
                    inertia + magneticForce), 
                0,
                1
                );
    }
    protected virtual void updateInertia()
    {
        if (useInertia)
        {
            inertia = Mathf.Abs(inputSource.NetSwipe.x) > 0 ? alpha - lastFrameAlpha : inertialDampening * inertia;
            if (Mathf.Abs(inertia) < rotationSensibility / inertiaPersistenceFactor)
                inertia = 0;
        }
    }
Share
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

1 thought on “Scroll inertia: in-depth tutorial”

  1. It’s perfect time to make some plans for the long run and it’s time to be happy.
    I’ve learn this post and if I may I want to recommend you some fascinating issues or suggestions.
    Perhaps you can write next articles referring to
    this article. I wish to learn more things approximately it!

Leave a Reply

Your email address will not be published.