Reputation: 329
I'm having a bit of trouble trying to dynamically generate a Gui in Unity3D. I've made a canvas with a panel as a child. I'm trying to populate this Panel with 7x4 images.
I receive a json object that has an x amount of items. Based on the amount of items I populate the panel with the amount of items received. For instance, if i receive a Json object with 28 items(7x4), I want the GUI to look like the following:
So like I've told, I made a canvas with a panel in the editor. In the script I made the following:
public GameObject canvas; //I use this to set the canvas after applying this script to an empty gameobject
public GameObject panel; // I do the same for the panel
In the Start method, i set the canvas as parent for the panel:
panel.transform.SetParent(canvas.transform, false);
Now that I set the panel as child to the Canvas, I want to generate 7x4 Images. Could anyone help me with this? What is the best way to generate multiple UI/Images and make it that it shows in the Panel like in the illustration?
Pretty new to Unity3D and I would like to get more familiair with scripting.
Upvotes: 2
Views: 2974
Reputation: 329
Managed to fix my code. How I did it: 1. Add an empty gameobject to the editor 2. Add a canvas with a panel as a child 3. Add the following script to the empty gameobject in step 1:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class generateUI : MonoBehaviour
{
public GameObject canvas;
public GameObject Panel;
public GameObject image;
int size = 40;
private float scaler = 0.0125f;
void Start()
{
Panel.transform.SetParent(canvas.transform, false);
GameObject[] tiles = new GameObject[size];
Vector3 change = new Vector3(20 * scaler, 0, 0);
for (int i = 0; i < size; i++)
{
tiles[i] = GameObject.Instantiate(image, transform.position, transform.rotation);
tiles[i].transform.position += change;
tiles[i].transform.SetParent(Panel.transform, false);
}
}
}
4: now add the following script to the canvas object:
using System.Collections
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI
public class DynamicGrid : MonoBehaviour
{
public int col,row;
void Start()
{
RectTransform parent = gameObject.GetComponent<RectTransform>();
GridLayoutGroup grid = gameObject.GetComponent<GridLayoutGroup>();
grid.cellSize = new Vector2(parent.rect.width / col, parent.rect.height / row);
}
void Update()
{
}
}
5: Set the canvas width to 1090 and height to 430
6: make a prefab from an image(100 by 100)
7: add a Grid Layout Group to the Panel
8: Set CellSize to 100 by 100 and spacing to 10 by 10
9: change the size in the generateUI script to a number you'd like to see
10: profit.
I now have the desired function. I followed @jour's suggestion to use a gridlayout, which I've used before while creating a mobile app with python's Kivy software.
Upvotes: 0
Reputation: 10137
Why do you set the canvas as parent for the panel from code?
So, if you need to generate all your images dynamically from code, you could do the following:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GUIBuilder : MonoBehaviour
{
public GameObject canvas; //I use this to set the canvas after applying this script to an empty gameobject
public GameObject panel; // I do the same for the panel
public Vector2 ImageViewCount; // 6 * 4
public Vector2 ImageViewSize; // 80 * 80
public Vector2 InitialImageViewPosition; // -300 * 250
public Vector2 ImageViewPositionOffset; // 125 * 200
// Use this for initialization
void Start()
{
GenerateImageView();
}
void GenerateImageView()
{
for (int a = 0; a < ImageViewCount.y; a++)
{
for (int b = 0; b < ImageViewCount.x; b++)
{
ImageViewBuilder(ImageViewSize,
new Vector2(InitialImageViewPosition.x + (ImageViewPositionOffset.x * b),
InitialImageViewPosition.y - (ImageViewPositionOffset.x * a)),
panel.transform);
}
}
}
void ImageViewBuilder(Vector2 size, Vector2 position, Transform objectToSetImageView)
{
GameObject imageView = new GameObject("ImageView", typeof(RectTransform));
RawImage image = imageView.AddComponent<RawImage>();
//image.texture = Your Image Here
RectTransform rectTransform = imageView.GetComponent<RectTransform>();
rectTransform.sizeDelta = size;
rectTransform.anchoredPosition = position;
imageView.transform.SetParent(objectToSetImageView, false);
}
}
Upvotes: 2
Reputation: 91
I think the best you could do is use Layout grid group on the panel, then set the images as children of the panel and force a rebuild layout
Upvotes: 1