Instantiating a list of gameobjects in Unity C#

22,301

Solution 1

Well considering your comments and that the first script your provided works perfectly without any error (as it should: there's no reason it should return an error), I feel like you are very new to Unity.

Therefore I'd recommend you to look to the Unity tutorials before anything else (they are quite well made and will help you understand the basics of the engine). You can find the Roll-a-ball tutorial here.

About your question:

1- In the first script, the Fill() method isn't called anywhere, you have to do something like this:

private void Start()
{
    Fill();
}

2- This Start() method comes from the MonoBehaviour parent class (as well as the Update() method which is called every frame) and is called once at the beginning of the scene. Look to this chart to understand how unity flow is made.

3- Using a List<GameObject> or a GameObject[] all depends on your situation: if the size of the collection is going to change, go for a list. Otherwise array is advised.

4- Considering your script my guess is it should look like this:

namespace Assets
{
    class Deck : MonoBehaviour
    {
        [SerializeField]
        private GameObject[] deck;

        private GameObject[] instanciatedObjects;

        private void Start()
        {
            Fill();
        }

        public void Fill()
        {
            instanciatedObjects = new GameObject[deck.Length];
            for (int i = 0; i < deck.Lenght; i++)
            {
                instanciatedObjects[i] = Instanciate(deck[i]) as GameObject;
            }
        }
    }
}

You can of course still use lists if needed :)

EDIT:
If you want to use a list you simply have to:

  • change private GameObject[] instanciatedObjects; to private List<GameObject> instanciatedObjects;
  • replace instanciatedObjects = new GameObject[deck.Length]; by instanciatedObjects = new List<GameObject>();
  • replace instanciatedObjects[i] = Instanciated(deck[i]) as GameObject; by instanciateObjects.Add(Instanciated(deck[i]) as GameObject);

Hope this helps,

Solution 2

Use foreach to loop over your List with prefabs, like this:

public List<GameObject> Deck = new List<GameObject>(); // im assuming Deck is your list with prefabs?
public List<GameObject> CreatedCards = new List<GameObject>();

void Start()
{
     Fill();
}

public void Fill()
{
    foreach(GameObject _go in Deck)
    {
        GameObject _newCard = (GameObject)Instantiate(_go);
        CreatedCards.Add(_newCard);
    }
}

Also it's a good habit to name your lists with capital letter.

Share:
22,301

Related videos on Youtube

GrayFur
Author by

GrayFur

I do most of my coding for university projects.

Updated on July 09, 2022

Comments

  • GrayFur
    GrayFur almost 2 years

    How can I instantiate a list of GameObject in Unity3D using c#? I fill the list with prefabs manually in inspector window.

    enter image description here

    Below is the code I've written in Deck.cs, but I get "Object reference is not set to an instance of an object". If you have a solution with an array, that will be appreciated as well.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Assets
    {
        class Deck:MonoBehaviour
        {
            public List<GameObject> deck;
            public void Fill()
            {
                GameObject c1 = Instantiate(deck[0]);
                GameObject c2 = Instantiate(deck[1]);
                GameObject c3 = Instantiate(deck[2]);
                GameObject c4 = Instantiate(deck[3]);
                GameObject c5 = Instantiate(deck[4]);
                GameObject c6 = Instantiate(deck[5]);
            }
    
        }
    }
    

    I also tried doing it with an array and I get 'The object you want to instantiate is null'

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using UnityEngine;
    using UnityEngine.UI;
    
    namespace Assets
    {
        class Deck:MonoBehaviour
        {
            public GameObject card1;
            public GameObject card2;
            public GameObject card3;
            public GameObject card4;
            public GameObject card5;
            public GameObject card6;
    
            public GameObject[] deck;
    
            public void Start ()
            {
                deck = new GameObject[5];
                GameObject c1 = Instantiate(card1) as GameObject;
                GameObject c2 = Instantiate(card2) as GameObject;
                GameObject c3 = Instantiate(card3) as GameObject;
                GameObject c4 = Instantiate(card4) as GameObject;
                GameObject c5 = Instantiate(card5) as GameObject;
                GameObject c6 = Instantiate(card6) as GameObject;
            }
    
        }
    }
    
    • Kardux
      Kardux almost 7 years
      At what line do you get the error message? Those 6 lines seem okay to me (even if we don't know when the Fill() method is called).
    • GrayFur
      GrayFur almost 7 years
      At 'public List<GameObject> deck'
    • Kardux
      Kardux almost 7 years
      Not sure this error was thrown: I tested it and no error happens. Check my answer for further details.
  • GrayFur
    GrayFur almost 7 years
    It doesn't give any errors, but it doesn't create any instances either. :( The CreatedCards list is empty all the time
  • Fiffe
    Fiffe almost 7 years
    Is your Deck filled with GameObjects? Also check the edit - I forgot about new List<GameObject>()
  • GrayFur
    GrayFur almost 7 years
    Nope, it works if I call the function Start instead of Fill
  • Fiffe
    Fiffe almost 7 years
    You need to populate your Deck with some prefabs if you want to Instantiate them. Also check the edit - I forgot about new List<GameObject>()
  • GrayFur
    GrayFur almost 7 years
    I filled it with prefabs, and yes, now it works, but I had to rename the function to Start. I'm not sure why it didn't work the other way
  • Fiffe
    Fiffe almost 7 years
    Because you didn't call your Fill() function anywhere. You can leave it in Fill() but you have to call fill from Start() or some other place.
  • GrayFur
    GrayFur almost 7 years
    Welp now I got it! The other time I tried to call it from other function, but it didn't work, so I have to call it from Start. Thanks a lot!
  • Fiffe
    Fiffe almost 7 years
    Glad it worked! If my answered helped be sure to accept it
  • GrayFur
    GrayFur almost 7 years
    Thanks for the answer. I'll try your version of the code as well. Yes, I'm really new to Unity :)
  • Kardux
    Kardux almost 7 years
    Noticed it and that's why I wanted to provide as much information as possible: Unity is fast to learn as long as you take your time to learn it. Since it feels like you are familiar with C# it shouldn't take to long to get your hands on it :)
  • GrayFur
    GrayFur almost 7 years
    I tried your solution and it works perfectly! in case of list I get out of range exception when I try to call instantiated objects by indexes. The array works great though. Thank you so much for help, I finally did what I'd beentrying to do for hours.
  • Kardux
    Kardux almost 7 years
    Sorry forgot to reply to your comment: glad it worked well. I edited my answer to add the changes required to use a list instead of an array.