2
\$\begingroup\$

I have a nested ScrollRect, or more specifically a scrollable list inside one of the items in another scrollable list. Think of it as a scrollable menu with one of the items including a scrollable list. All the following will just refer to vertical scrolling, since I do not require any horizontal scrolling.

I would have expected that once reaching the limits of the child ScrollRect, the scrolling would pass through to the parent ScrollRect and continue scrolling the parent list, as is common in all such instances that I'm aware of. However, this simply does not happen. The child ScrollRect captures the scrolling, sees that it is at its limit, does not continue scrolling and nothing further happens.

Looking for answers online, I only find answers to having a horizontal scrolling ScrollRect inside a vertical one, but no problems matching mine. If I'm just missing something very obvious, I'm happy to be pointed in the right direction, but if not, any assistance with this problem would be appreciated. For now I'm going to play around with subclassing to see if I can solve the problem in that way.

See below the child and the parent ScrollRects

The child ScrollRect

The parent ScrollRect

\$\endgroup\$
1
  • \$\begingroup\$ Using a subclass didn't really seem to work since the a bunch of the required functions and variables are private and I didn't want to mess with the original ScrollRect script. I ended up copying the code form the ScrollRect script directly and modifying it a little. I added a bool that sets "Pass to parents", which if set will pass any remaining scroll to the first parent it finds with either a ScrollRect or my new ScrollRectChild script. While this works, I would love to see if anyone has a better solution. \$\endgroup\$ Jun 8, 2022 at 10:39

1 Answer 1

1
\$\begingroup\$

I ended up copying the ScrollRect script as is to my own script. I called it ScrollRectChild and removed it from the namespace. I tried to subclass from ScrollRect, but too many of the functions and variables are private and I didn't want to change the base script.

Note: This modification will only work for a clamped ScrollRect, and I haven't tested it for horizontal movement, though it should work for that as well.

Modifications to the script: Added a bool called passScrolling, which indicates that "overrunning" the scrolling should be passed on to parent ScrollRects.

In the OnScroll function, modify the last if statement to:

if (m_MovementType == MovementType.Clamped)
{
    Vector2 offset = CalculateOffset(position - m_Content.anchoredPosition);
    position += offset;
    data.scrollDelta = offset / m_ScrollSensitivity;
    if (passScrolling)
    {
        passToParent(data);
    }
}

The passToParent function:

private void passToParent(PointerEventData data)
{
    Transform parent = transform.parent;
    while (parent != null)
    {
        if (parent.GetComponent<ScrollRect>() != null)
        {
            parent.GetComponent<ScrollRect>().OnScroll(data);
            break;
        }
        if (parent.GetComponent<ScrollRectChild>() != null)
        {
            parent.GetComponent<ScrollRectChild>().OnScroll(data);
            break;
        }
        parent = parent.parent;
    }
}

This code works perfectly for horizontal scrolling (slight modification might be required for horizontal, to be tested). However if there is a better solution, please post it as another answer. This is more of a work-around and I'm still very surprised this functionality isn't standard.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .