Why doesn't my spawning code work?

I want it to spawn balloons in a set distance between each other in rounds a set time apart. but the balloons spawn on top of each other and aren’t spacing themselves apart.

public GameObject red;
public GameObject yellow;
public GameObject green;
public GameObject blue;

public int numberOfReds;

private bool timerOn;
private float timer;
public float secondsBetweenWaves;

private float distance;
public float distanceBetweenBalloons;

void FixedUpdate()
{
    Timer();
    if (timer <= 0)
    {
        for (int i = 0; i < numberOfReds; i++)
        {
            Instantiate(red, transform, false);
            distance = distanceBetweenBalloons;
            while(distance > 0 && i != numberOfReds - 1)
            {
                DistanceTimer();
            }
        }
        timer = secondsBetweenWaves;
        timerOn = true;
    }
}
void Timer()
{
    if (timerOn)
    {
        timer -= (Time.deltaTime);
        if (timer <= 0)
        {
            timerOn = false;
        }
    }
}

void DistanceTimer()
{
    distance -= (Time.deltaTime);
}

Is secondsBetweenWaves set to the correct number? I would do a debug log after setting timer to see the value and also as the Timer update to see how it decreases.

The while loop doesn’t run each frame, it runs much faster and so the distance is instantly 0, you should better add a delay using maybe a coroutine.

  1. You aren’t using your distance variable anywhere, instead every balloon is being put at the position of the object that has this spawner script attached.
  2. Your DistanceTimer() function is not doing anything. The while loop will run fully through every time FixedUpdate is called, so you are setting distance and then immediately lowering it to zero in a while loop (I imagine you wanted this while loop to work as a time delay between each balloon spawn? Otherwise I’m not sure what the purpose of it is)…

**
There are lots of ways you could implement this (Coroutines would probably be better than what I’m about to suggest), but here is a script that I think loosely does what you are trying to do. I had to make some assumptions about how you wanted this to work so you will have to go in and tweak it to fit your goals, but this should get you started. Note that I have not tested this code.

public GameObject red;
public float timeBetweenWaves;
public float distanceBetweenBalloons;
public float timeBetweenEachBallon;
public int numberOfReds;

private bool spawningWave = false;
private float waveTimer = 0; //Tracks time between waves
private float spawnTimer = 0; //Tracks time between balloons
private int numberRedsSpawned = 0;

void Update () {

    if (!spawningWave) {
        waveTimer -= Time.deltaTime;
        if (waveTimer <= 0) spawningWave = true;
    }

    if (spawningWave) {
        if (numberRedsSpawned >= numberOfReds) {
            //Done spawning red balloons
            numberRedsSpawned = 0;
            spawningWave = false;
            waveTimer = timeBetweenWaves;
            spawnTimer = 0;
        } else {

            
            spawnTimer -= Time.deltaTime;
            if (spawnTimer <= 0) {
                //Spawn a balloon
                //First calculate the distance offset
                Vector3 direction = Vector3.right; //Not sure what direction you want the balloons to be spawned in, so lets just use the x axis
                Vector3 spawnOffset = numberRedsSpawned * distanceBetweenBalloons * direction;
                Instantiate (red, transform.position + spawnOffset, Quaterion.identity, transform);
                numberRedsSpawned++;
                spawnTimer = timeBetweenEachBallon;
            }
        }
    }
}