- Home /
How to instantiate a prefab one by one in foreach loop
Hello Guys I'm new to unity and I am stuck on a problem. I have to show my prefabs one by one in a slide Show (like a slider in websites) . I have added all my prefabs in a list and I'm trying to show it in a slide show but the problem is all of the prefabs are being displayed at once. I know I have done something wrong in my code. Here's my Code.
using UnityEngine.SceneManagement;
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class PizzaScript : MonoBehaviour {
public Text header;
public static List<GameObject> createObjects = new List<GameObject>();
private static int slideIndex = 1;
// Use this for initialization
void Start()
{
Vector3 startPosition;
Object[] subListObjects = Resources.LoadAll("Prefabs", typeof(GameObject));
foreach(GameObject list in subListObjects)
{
GameObject lo = (GameObject)list;
createObjects.Add(lo);
}
startPosition = transform.position;
showPrefabs(slideIndex);
}
// Update is called once per fram
public void OnClickRightArrow()
{
plusPrefabs(1);
}
public void OnClickLeftArrow()
{
plusPrefabs(-1);
}
public void plusPrefabs(int n)
{
showPrefabs(slideIndex += n);
}
public void showPrefabs(int n)
{
Vector3 temp = new Vector3(0.34f, 0.074f, 0);
var x = createObjects.Count;
if (n > createObjects.Count)
{
slideIndex = 1;
}
if (n < 1)
{
slideIndex = createObjects.Count;
}
foreach(GameObject i in createObjects)
{
GameObject instance = Instantiate(i, temp, Quaternion.identity);
i.transform.localScale = new Vector3(10, 10, 10);
}
}
}
OnClickRightArrow() and OnClickLeftArrow() are my methods that triger when I click the left or Right button
Here is my scene So, that you can get the idea .
Answer by tormentoarmagedoom · Sep 19, 2018 at 10:22 PM
Good day.
First, i just saw this:
foreach(GameObject i in createObjects)
{
GameObject instance = Instantiate(i, temp, Quaternion.identity);
i.transform.localScale = new Vector3(10, 10, 10);
}
Do you see you are changing the localscale of i (the "prefab"), not the new object called instance ??
And, if you do a foreach, the code will execute all orders for each "i" with no stops. I dont knw what you want to get, but if you dont do any "if" inside the foreach, it will do the code for each i in the list.
If you just want to pause the time between instantiates, use a corutine.
public void showPrefabs(int n)
{
[...]
StartCorutine (InstantiateObjects());
}
Ienumerator InstantiateObjects()
{
foreach(GameObject i in createObjects)
{
GameObject instance = Instantiate(i, temp, Quaternion.identity);
i.transform.localScale = new Vector3(10, 10, 10);
yield return new WaitForSeconds (5);
}
}
So now, it will do the code for each "i" , but will wait 5 seconds between each iteration.
Bye!
Thanks man for the help I did by taking your advise I put some "if" conditions and it worked Thanks alot man
Answer by Mateusz-Armir · Sep 19, 2018 at 08:50 PM
Hi
Well, your prefabs are all displayed at once, because you instantiate all of them at once. May I propose to you more elegant solution.
From what I see, you want to make a slider which shows different kind of pizzas (your prefabs). Here is the script that spawns all pizzas, then hide them, then show only the one of them, according to what you press.
public class PizzaScript : MonoBehaviour {
private GameObject[] pizzaArray = new GameObject[0];
private int pizzaIndex = 0;
private Vector3 pizzaDisplayPosition = new Vector3(0.34f, 0.074f, 0);
void Start() {
GameObject[] pizzaPrefabs = Resources.LoadAll("Prefabs", typeof(GameObject));
pizzaArray = new GameObject[pizzaPrefabs .length];
for(int i=0;i<pizzaPrefabs .length;i++){
pizzaArray [i] = Instantiate(pizzaPrefabs[i], pizzaDisplayPosition , Quaternion.identity);
pizzaArray [i].transform.localScale = new Vector3(10, 10, 10);
pizzaArray [i].SetActive(false);
//SetActive(false) makes this object inactive - it dissapears, cannot be interacted with in any way, but it is still in the scene
}
plusPrefabs(0);
}
// Update is called once per fram
public void OnClickRightArrow()
{
plusPrefabs(1);
}
public void OnClickLeftArrow()
{
plusPrefabs(-1);
}
public void plusPrefabs(int n)
{
pizzaIndex += n;
if(pizzaIndex<0) pizzaIndex = pizzaArray.Length-1;
if(pizzaIndex>=pizzaArray.Length) pizzaIndex = 0;
for(int i=0;i<pizzaPrefabs .length;i++){
pizzaArray [i].SetActive(false);
}
pizzaArray [pizzaIndex].SetActive(true);
}
}
Hi Thanks for the Reply @$$anonymous$$ateusz-Armir there is an error on the first line of void Start() on line
GameObject[] pizzaPrefabs = Resources.LoadAll("Prefabs", typeof(GameObject));
The error is cannot implicitly convert type unityengine.object' to unityengine.gameobject' can you please help me Thanks
What you need is an explicit cast:
GameObject[] pizzaPrefabs = (GameObject)Resources.LoadAll("Prefabs",typeof(GameObject));
It looks like you're learning C#, so I suggest you look at the docs for Foreach vs For (there's a number of very important differences here and Foreach doen't work quite the way you might expect). Also, check out Casting, which is what fixes that error.
I wish you the best!
Answer by imraniqbal · Sep 20, 2018 at 06:55 PM
Thanks everyone for your help but I have done it by fixing my Code. I shouldn't use loop there that was the problem I did it by using "if" conditions. Thanks again.