user11746000
user11746000

Reputation:

How to find out the number of child object of an instantiated prefab in Unity?

I have 2 objects:

In the GameManager script I'm instantiating a stripe every 2 seconds, and in the Stripe script I'm instantiating Tiles using for loop with a random number and I'm parenting them to the stripe just created.

My problem is that I want to find out the number the of tiles per instantiated Stripe?

I mean using newStripe.transform.childCount won't work because it will always return zero, and just for testing reasons I edited the Stripe prefab by adding an empty gameobject and then applied the changes newStripe.transform.childCount will return 1.

I know that I'm supposed to use object pooling techniques in such situations, but I'm a beginner and I'm trying to learn.

// GameManager Script

void Update()
{
    timeBetweenSpawns -= Time.deltaTime;

    if (timeBetweenSpawns < -2)
    {           
       Stripe newStripe = Instantiate(stripePrefab, spawnPosition, 
       Quaternion.identity);

        // This variable (tilesCountIntStripe) always returns zero
        tilesCountInStripe = newStripe.transform.childCount;

        timeBetweenSpawns = 0;
    }
}

// Stripe Script
void Update()
{
    if (createTile)
    {
        int randomStripesCount = Random.Range(1, 10);
        for (int i = 0; i < randomStripesCount; i++)
        {
            Tile newTile = Instantiate(tile);
            newTile.transform.SetParent(transform, true);
            newTile.transform.localPosition = new Vector2(transform.position.x, (-i * (1.1f)));
            tilesCount += 1;
        }
        createTile = false;
    }
}

Upvotes: 1

Views: 576

Answers (1)

It returns 0 where you're asking because Tile::Update() hasn't run yet

If you want that code to run immediately, I suggest doing something like this:

// GameManager Script

void Update()
{
    timeBetweenSpawns -= Time.deltaTime;

    if (timeBetweenSpawns < -2)
    {           
       Stripe newStripe = Instantiate(stripePrefab, spawnPosition, 
         Quaternion.identity);

       tilesCountInStripe = newStripe.GetComponent<Stripe>().Init();
       //Or whatever the exact name of your class is ^ here

       timeBetweenSpawns = 0;
    }
}

// Stripe Script
public int Init()
{
    int randomStripesCount = Random.Range(1, 10);
    for (int i = 0; i < randomStripesCount; i++)
    {
        Tile newTile = Instantiate(tile);
        newTile.transform.SetParent(transform, true);
        newTile.transform.localPosition = new Vector2(transform.position.x, (-i * (1.1f)));
        tilesCount += 1;
    }
    return randomStripesCount;
}

Changes:

  1. Rather than waiting for Update to create the tiles, we instantiate them in an Init function that is called from code that you control.
    • This also removes the neccessity of having a createTile field that prevents the update code (which runs once a frame) from running every frame.
      • this should have been a clue that you were doing things in the wrong place
  2. Returning the random number of tiles from this Init method (FAST), avoiding having to query the transform hierarchy (SLOW).

Upvotes: 0

Related Questions