Search code examples
c#unity-game-enginescrollsteamvr

How to design a smooth UI scroll inside Update() for a Unity VR application?


I am developing a VR application in Unity and I am struggling to develop a smooth UI scroll using my VR controller's joystick. So far what I have looks like this...

private void Update() 
{
    float joyStickDirection = globals.menuInteraction_Scroll.GetAxis(SteamVR_Input_Sources.Any).y; // this is either 1 for up or -1 for down
    if (joyStickDirection != 0) 
    {
        float multiplier = joyStickDirection * 5f; 
        scrollRect.verticalNormalizedPosition = scrollRect.verticalNormalizedPosition + (multiplier * Time.deltaTime);
    }
}

...this works, but has two problems. Firstly, it scrolls at different speeds depending how big the scrolling container is. Secondly, the scrolling is not very smooth, as it is clearly just skipping varying gaps between 0 and 1.

I think I know what's wrong but I don't have enough experience working inside Update() to figure out the correct approach. Can anyone advise?


Solution

  • Actually you don't necessarily go through the ScrollRect component itself.

    I usually would simply do

    public class ScrollExample : MonoBehaviour
    {
        public float speed = 5f;
    
        public Transform ScrollContent;
        
        void Update()
        {
            // this is either 1 for up or -1 for down
            var joyStickDirection = globals.menuInteraction_Scroll.GetAxis(SteamVR_Input_Sources.Any).y; 
            if (joyStickDirection != 0) 
            {
                var multiplier = joyStickDirection * speed; 
                
                // You want to invert the direction since scrolling down actually means
                // moving the content up
                ScrollContent.position -= Vector3.up * multiplier * Time.deltaTime;
            }
        }
    }
    

    The ScrollRect then updates and handles the rest itself. The speed is in Units/seconds or in a Screenspace Overlay canvas in pixels per seconds regardless of how big the content is.

    Usually you would want to adjust the elasticity of the ScrollRect or simply set the Movement Type to Clamped right away.