3
\$\begingroup\$

I need to add X objects to a scrollview. I do it like this:

GameObject statsObject = Instantiate(instance.statsObjectPrefab);
statsObject.transform.SetParent(statsParent.transform);

statsParent is the content container if the scrollview.

Scrollview
---- Viewport
-------- Content // This is statsParent

In the pause I see that then objects are added successfully, but they all overlap and no scrollbar is visible.

The content has a content size fitter and a vertical layout group, but I tried now all settings and the result is always the same.

enter image description here

I use Unity 2019.2

\$\endgroup\$
4
  • \$\begingroup\$ Best way to work with that is to use layouts. like grid layouts as simply set right size for contents and you dont need to care for anchors after instantiation \$\endgroup\$
    – virtouso
    Commented Sep 13, 2019 at 21:49
  • \$\begingroup\$ Presumably you tried SetParent(statsParent.transform, false)? \$\endgroup\$
    – DMGregory
    Commented Jun 21, 2020 at 2:03
  • 1
    \$\begingroup\$ Did you try LayoutRebuilder.ForceRebuildLayoutImmediate after adding the object? \$\endgroup\$
    – Safa
    Commented Jun 21, 2020 at 9:13
  • \$\begingroup\$ How did you resolve this Roman? \$\endgroup\$ Commented Oct 1, 2021 at 20:26

2 Answers 2

6
\$\begingroup\$

This should be very straightforward. Here is a simple example of how to accomplish this.

Here is the scene hierarchy, with the Content game object as a child of the Viewport, which in turn is a child of the Scrollbar gameobject. This is default Unity set up for a ScrollView game object.

Scene Hierarchy

The only other thing I've added is a Controller game object, to hold our sample scroll view populator script.

The Content game object needs two components: Vertical Layout Group and Content Size Fitter. I've added a bit of spacing in the Vertical Layout Group to separate the items. Child Force Expand Height should be unchecked.

enter image description here

Create the item template(s) as children of the Content game object. For the demo, the item template is very simple, just a background image with a text label child:

temp hierachy with template under construction

Here's the scene so far, with the item prefab in place:

demo scene under construction

When the template is to your satisfaction, save it as prefab and remove it from the scene hierarchy.

Here is an example script that will populate the ScrollView without the items overlapping:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PopulateScrollView : MonoBehaviour
{
    [SerializeField] private Transform m_ContentContainer;
    [SerializeField] private GameObject m_ItemPrefab;
    [SerializeField] private int m_ItemsToGenerate;

    void Start()
    {
        for(int i = 0; i < m_ItemsToGenerate; i++)
        {
            var item_go = Instantiate(m_ItemPrefab);
            // do something with the instantiated item -- for instance
            item_go.GetComponentInChildren<Text>().text = "Item #" + i;
            item_go.GetComponent<Image>().color = i % 2 == 0 ? Color.yellow : Color.cyan;
            //parent the item to the content container
            item_go.transform.SetParent(m_ContentContainer);
            //reset the item's scale -- this can get munged with UI prefabs
            item_go.transform.localScale = Vector2.one;
        }
    }
}

One thing to note about the script -- I always reset the instantiated prefab's local scale after parenting it to a UI object, as sometimes (often, even) the scale gets messed up when taken out of its Canvas context.

Here are the exposed settings for this component, which was added to the Controller game object:

enter image description here

And here is the result when played:

Demo

\$\endgroup\$
1
\$\begingroup\$

From the Vertical Layout Group docs:

The Vertical Layout Group component places its child layout elements on top of each other. Their heights are determined by their respective minimum, preferred, and flexible heights according to [...]

You have to add a LayoutElement component to your prefab and set its values according to your needs.

\$\endgroup\$

You must log in to answer this question.

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