I'm having trouble with a coroutine delay

shouldnt this work? I put a delay before the Spawnloop delay. contents are in the NewDelay function.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObstacleSpawner : MonoBehaviour 

{

	public int obstacles_min = 1;
	public int obstacles_max = 4;
	public float obstacles_range= 10;
	public float obstacles_deviation_min = -3;
	public float obstacles_deviation_max = 3;
	public Transform playerTransform;
	public GameObject obstaclePrefab;
	public float obstacleLifetime = 4f;
	public float spawnDelay = 3;
	public float BeginingDelay = 4;



	// Use this for initialization
	void Start ()
	{
		StartCoroutine ("NewDelay");
			StartCoroutine ("SpawnLoop");
		
	}
	
	// Update is called once per frame
	void Update () 

	{
		
	}

	private void SpawnObstacles()
	{
		
		int randomNumber = Random.Range (obstacles_min, obstacles_max); // Picks a number within min and max and store in randomNumber
		for (int i = 0; i < randomNumber; i++)// i = 0 if i is less than the random number stored increment i++ until its reached the value of the random number
		{
			Vector3 randomPos = new Vector3 (playerTransform.position.x + Random.Range (obstacles_deviation_min, obstacles_deviation_max), playerTransform.position.y, playerTransform.position.z + obstacles_range);
			GameObject obstacle = Instantiate (obstaclePrefab, randomPos, Quaternion.identity) as GameObject;
			Destroy (obstacle, obstacleLifetime);
		}
	}

	private IEnumerator SpawnLoop()
	{
		while (true)
		{
			SpawnObstacles ();
			yield return new WaitForSeconds (spawnDelay);
			//print ("spawn delayed");
		}
		yield return null;

	}
	private IEnumerator NewDelay()
	{
		yield return new WaitForSeconds (BeginingDelay);
	}

		
}

Your NewDelay coroutine isn’t actually doing anything. It runs, waits a bit, then runs again; but what’s it doing?

I’m going to make an assumption that you’re expecting the Start() method to wait until NewDelay returns before running SpawnLoop - that’s now how it works. NewDelay will run, then as soon as it returns, SpawnLoop will run - they do not affect each other. You wouldn’t want Start() to wait for NewDelay to finish its WaitForSeconds anyway, as that would lock the entire game up until it’s complete (other scripts will only be run when Start(), or any method, has finished executing).

One solution is to use the Invoke method and a new function that simply starts the SpawnLoop , e.g. new function StartSpawning,

void StartSpawning() {
    StartCoroutine("SpawnLoop");
}

Then, in your Start, replace everything there with,

Invoke("StartSpawning", BeginingDelay);

Another, perhaps better solution is to keep things how they are, but remove everything to do with NewDelay, then modify SpawnLoop thusly:

private IEnumerator SpawnLoop()
     {
         yield return new WaitForSeconds(BeginingDelay); // New line
         while (true)
         {
             SpawnObstacles ();
             yield return new WaitForSeconds (spawnDelay);
             //print ("spawn delayed");
         }
         yield return null;     
     }

This means the first time the Coroutine is run, it waits for BeginingDelay (btw it’s spelt “Beginning” :)) seconds, and then carries on to the rest of the Coroutine.

Hi SeanWink,

The problem is in your start function.

void Start ()
     {
        StartCoroutine ("NewDelay");
        StartCoroutine ("SpawnLoop");         
     }

The issue is that the StartCoroutine function doesn’t Add a delay. It creates a new function that runs at the same time as your start function. So everything in your Start function gets executed instantly. To solve this do the following:

void Start ()
         {
            StartCoroutine ("NewDelay");
            // Remove the coroutine from here 
         }

private IEnumerator NewDelay()
     {
         yield return new WaitForSeconds (BeginingDelay);
         StartCoroutine ("SpawnLoop");     // Add it here after the delay 

}