0

As the title suggests, I'm trying to populate a UI panel with a GridLayoutGroup component at runtime with sprites from the resources folder. The problem is that the sprites do not auto-align to the grid cells, instead getting drawn on the center of the panel.

I've tried the approach mentioned here but it does not work for me. Here is the script I've attached to the gui with the GridLayoutGroup:

public class SpriteList : MonoBehaviour
{
    public GameObject gridPanel;
    public const string sortingLayer = "Foreground";

    // Use this for initialization
    void Start()
    {
        Sprite[] spriteArray = Resources.LoadAll<Sprite>("Sprites");
        RectTransform gridRT = gridPanel.GetComponent<RectTransform>();

        for (int i = 0; i < spriteArray.Length; i++)
        {
            GameObject cellObject = new GameObject();
            cellObject.AddComponent<SpriteRenderer>();
            cellObject.GetComponent<SpriteRenderer>().sprite = spriteArray[i];
            cellObject.GetComponent<SpriteRenderer>().sortingLayerName = sortingLayer;

            GameObject sprite = (GameObject) Instantiate(cellObject);
            sprite.transform.SetParent(gridPanel.transform, false);
            LayoutRebuilder.ForceRebuildLayoutImmediate( 
                    gridPanel.GetComponent<RectTransform>());
            sprite.transform.localScale = new Vector3(30, 30, 1);
    }
}

Changing the settings of the GridLayoutGroup do not modify the behaviour I'm seeing at all.

Since everything I see online seems to indicate that the key is the line

sprite.transform.SetParent(gridPanel.transform, false);

which I use, what am I missing?

Much gratitude!

derHugo
  • 83,094
  • 9
  • 75
  • 115
Rookatu
  • 1,487
  • 3
  • 21
  • 50

2 Answers2

0

Your objects should have a 'Layout Element' component attached.

After setting the parent of the objects call LayoutRebuilder.ForceRebuildLayoutImmediate() on the parent.

Sandro Figo
  • 183
  • 10
  • I tried this and it did not work (I also updated my post to include the new code). Do you know why this might be? Thanks! – Rookatu Nov 18 '17 at 20:53
0

I was able to solve this by creating a rect transform prefab with a SpriteRenderer attached, and then instantiating copies of the prefab and assigning the desired sprite at runtime. I'm not sure why my old approach did not work (I think I am missing something very fundamental) but here is the code I'm using now:

public GameObject gridPanel;
public const string sortingLayer = "Foreground";
public GameObject prefab;

// Use this for initialization
void Start()
{
    Sprite[] spriteArray = Resources.LoadAll<Sprite>("Sprites");
    GameObject newObj;

    for (int i = 0; i < spriteArray.Length; i++)
    {
        newObj = (GameObject)Instantiate(prefab, transform);
        newObj.GetComponent<SpriteRenderer>().sprite = spriteArray[i];
        newObj.GetComponent<SpriteRenderer>().sortingLayerName = sortingLayer;
        LayoutRebuilder.ForceRebuildLayoutImmediate(gridPanel.transform as RectTransform);
    }
}

I should mention that this approach has introduced/uncovered a new issue which is that the sizing and spacing of the sprites is way off. I've been trying to fix this for a while now with no success; I'll continue to try and post my solution here when I determine it, or else ask a separate question and post a link to that here.

Rookatu
  • 1,487
  • 3
  • 21
  • 50