Vertically scrollable UI with children that stretch to width

261 views Asked by At

I am trying to create a vertically scrollable UI element that stretches horizontally, with children that also stretch horizontally. The children are instantiated prefabs. The prefab root object is set to TOP STRETCH but when it is instantiated it gets set to TOP LEFT and warns me that "Some values driven by VerticalLayoutGroup". In the inspector at runtime, I can simply click the widget for the rect transform and set it to TOP STRETCH and it immediately displays properly. I have tried numerous ways of fixing this, including a coroutine that programmatically changes the anchors one frame after they are instantiated. This technically worked, but then when you resize, it reverts to TOP LEFT. Besides this is a bit of a hack I don't want to do.

What is the best way to accomplish my goal of having a GameObject inside a Vertical Layout Group that is stretched?

Hierarchy:

enter image description here

GameObject Components Comment
EventTrackContainer Scroll Rect
Rect Mask 2D
EventTrackContent Vertical Layout Group
Content Size Fitter will not scroll without this, despite the warning
[prefab] EntityTrack Layout Element Flexible Width checked [1] (this was an attempt to solve the problem but did not work). This is the item that is set to TOP STRETCH but gets reverted.
EventTrackEntityName N/A
EventTrackContent N/A This is the one I really need to be the same width as EventTrackContent

Prefab in Prefab editor:

enter image description here

Instantiated prefab (The problem):

enter image description here

I tried adding a "Layout Element" and setting Flexible Width to 1. I tried programmatically changing the anchors.

3

There are 3 answers

1
derHugo On BEST ANSWER

This should behave as expected

enter image description here

The pivot and anchoring and child alignment settings etc are optional, the main focus is the Control Child Size -> Width and disabling the Child Force Expand -> Height but rather tick Use Child Height

enter image description here

0
hijinxbassist On

The values are controlled from the vertical layout group. Modifications you want to make to the positioning and scale of the children (in specific modes) need to be handled from the vertical layout group.

In order to have the children stretch, tick the Control Child Size checkbox for the Width.

Vertical Layout Group Reference

1
Nota Programmer On

I ended up removing the Layout Group and Content Size fitter components and managing it all manually.

Here's the code:

    // Instantiate prefab into track scroll area
    GameObject EntityTrack = Instantiate(entityTrackPrefab, entityTrackParent.transform);

    // Add instantiated object to dictionary
    entityTrackInstances.Add(entityName, EntityTrack);


    // Move the prefab to the correct position
    RectTransform rectTransform = EntityTrack.GetComponent<RectTransform>();
    rectTransform.anchoredPosition = new Vector2(0, currentTrackY);
    rectTransform.anchorMin = new Vector2(0, 1); // Top-left anchor
    rectTransform.anchorMax = new Vector2(1, 1); // Top-right anchor
    rectTransform.pivot = new Vector2(0.5f, 1); // Top-center pivot
    rectTransform.sizeDelta = new Vector2(0, rectTransform.sizeDelta.y); // Stretch horizontally

    // Update currentY for the next prefab
    currentTrackY -= eventTrackOffsetY;

    // Update the size of the parent RectTransform so it's parent can scroll
    RectTransform contentRect = entityTrackParent.GetComponent<RectTransform>();
    contentRect.sizeDelta = new Vector2(contentRect.sizeDelta.x, Mathf.Abs(currentTrackY));