jason
jason

Reputation: 3615

Strange behavior adding objects to Array Unity3d C#

I am seeing some odd behavior, when adding objects to an array of GameObjects. Here is my sudo code:

public class GameController : MonoBehaviour {
    public GameObject[] MyArray;

   void Awake() {
       Application.runInBackground = true;
       MyArray= new GameObject[144];
   }
    //some code that calls myFunction
   public  IEnumerator myFunction(float time)   
    {
       int counter = 0;
       GameObject card= AnotherArrayOfGameObjects[0];
       for (int j = 0; j < 144; j++)
        {
             card.name = "BLANK_" + (j+1);           
            Instantiate(card, cardVector, Quaternion.Euler(0, rotateAdujust, 180));
            MyArray[counter] = card;
            yield return new WaitForSeconds(time);
            counter++;
        }
    }

} 

This function kind of works ok. It creates my object and instantiates it. But, when it adds the object "card" to the array MyArray, it does not add it correctly. I.e, as this is in a loop, 0-143, I would expect the array to look like this:

MyArray[0] = "BLANK_1" 
MyArray[1] = "BLANK_2" 
....
MyArray[143] = "BLANK_144" 

Instead, it looks like this:

MyArray[0] = "BLANK_144" 
MyArray[1] = "BLANK_144" 
....
MyArray[143] = "BLANK_144" 

I can see all this, by the way, because MyArray is a public variable in my code, so I can see it in Unity's Inspector. If I debug, I can see each iteration overwrite the previous. So, in the first iteration of the loop, i get:

   MyArray[0] = "BLANK_1" 

Then in the second iteration of the loop, I get:

   MyArray[0] = "BLANK_2" 
   MyArray[1] = "BLANK_2" 

In the Third:

   MyArray[0] = "BLANK_3" 
   MyArray[1] = "BLANK_3" 
   MyArray[2] = "BLANK_3" 

Until it completes the full loop and all items in the array say "BLANK_144"

Can anyone explain why this is happening?

Upvotes: 1

Views: 33

Answers (1)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236228

You are adding same card object to array on each iteration. And you are changing name of this object on each iteration. Thus you end up with array, all items of which are pointing to same card instance. And that card instance whill have latest name which you have assigned (on last iteration):

MyArray[counter] = card;

Remember - Instantiate method returns cloned object, but it does not change the object which you are cloning. So you instantiate new clone on each iteration, but you don't save it anywhere.

You should add to array card clones which you are instantiating:

GameObject card = AnotherArrayOfGameObjects[0];
for (int j = 0; j < 144; j++)
{
    var cardClone = Instantiate(card, cardVector, Quaternion.Euler(0, rotateAdujust, 180));
    cardClone.name = "BLANK_" + (j+1); 
    MyArray[j] = cardClone;
    yield return new WaitForSeconds(time);
}

Upvotes: 3

Related Questions