Moving scrollview by mousedrag

I was working on my node based editor extension. I really wanted to move my workspace by mouse drag, something like in the mecanim animator. Since I didn’t find a complete solution, I decided to share my script with you, maybe somebody needs it. :slight_smile:

    Vector2 _scrollPosition = Vector2.zero;
    Vector2 _lastMousePos = new Vector2(-999f, -999f);

    void OnGUI ()
    {
        Rect scrollViewRect = new Rect(0,0, 400, 400);

        // Scroll view
        _scrollPosition = GUI.BeginScrollView(scrollViewRect, _scrollPosition, new Rect(0, 0, 2000, 2000));
            /* Your code here */
        GUI.EndScrollView();
       
        /* Move by mouse drag */

        // Check if the mouse is above our scrollview.
        if (scrollViewRect.Contains(Event.current.mousePosition))
        {
            // Only move if we are hold down the middle (wheel) mouse button, and the mouse is moving.
            if (Event.current.button == 2 && Event.current.type == EventType.mouseDrag)
            {
                // Current position
                Vector2 currPos = Event.current.mousePosition;

                // Only move if the distance between the last mouse position and the current is less than 50.
                // Without this it jumps during the drag.
                if(Vector2.Distance(currPos, _lastMousePos) < 50)
                {
                    // Calculate the delta x and y.
                    float x = _lastMousePos.x - currPos.x;
                    float y = _lastMousePos.y - currPos.y;

                    // Add the delta moves to the scroll position.
                    _scrollPosition.x += x;
                    _scrollPosition.y += y;
                    Event.current.Use();
                }
                // Set the last mouse position to the current mouse position.
                _lastMousePos = currPos;
            }           
        }
    }
2 Likes

Good, exactly what I needed for the class diagram tool I make. Still polishing it …

1 Like

I’ve improved on the OP’s code:

if(scrollViewRect.Contains(Event.current.mousePosition)){
    if(Event.current.button == 2 && Event.current.type == EventType.MouseDrag){
        _scrollPosition += -Event.current.delta;
        Event.current.Use();
    }
}

The former way it was presented, the ScrollView would jump around if you moved the mouse too fast, or if you clicked a small distance away from your previous click. There’s also no need to calculate your own delta. Removing these factors makes it a lot cleaner and without any jumping around.

1 Like