Trouble Resuming after Yielding while Inside Coroutine

Hello everyone, I’m having trouble with yielding for a coroutine (then resuming execution) while inside another coroutine, where yielding to another coroutine causes the original coroutine to never complete (it just ends after the yield instuction. More details below:

The Script:

	private IEnumerator InitialSpawnLogic()
	{
		Debug.Log("InitialSpawnLogic() coroutine starting...");

		#region Dealing with Initial Spawning:
		//figure out if a player/npc are needed or some other combo:

		//we always need a player ship:
		yield return StartCoroutine(ChooseSpawnAndInstantiateShip(currentPlayerShip, false) ); //select a good spawn point, instantiate Player...

		//need an NPC ship unless TRAINING is detected:
		if(currentGameMode != GameModes.Training)
		{
			Debug.Log("the GAMEMODE seleteced requires at least 1 NPC ship...");

			//now get NPC:
			Debug.Log("1111");

			yield return StartCoroutine (ChooseSpawnAndInstantiateShip(currentNPCShip, true) ); //select a good spawn point, instantiate NPC..

			Debug.Log("2222");
		}
		else
		{
			Debug.Log("the GAMEMODE seleteced does NOT require any NPC ship(s)...");
		}
		#endregion Dealing with Initial Spawning:

		Debug.Log("3333");

		//check game type to either start recurring spawn logic or not:
		if(currentGameMode == GameModes.Survival) //for now, RANDOM is only 1v1 battles (since that is the "free default", so don't account for it)...
		{
			Debug.Log("currentGameMode == GameModes.Survival");
			StartCoroutine("RecurringSpawnLogic");
		}
		else
		{
			Debug.Log("This game type does not require Re-spawns, InitialSpawnLogic() coroutine ending");
		}
	}

In Detail:

The InitialSpawnLogic coroutine never gets to the “Debug(“2222”)” line or beyond. What confuses me is that there does not seem to be any problem the first time I yield, and the method it yields to ends the same way regardless of the arguments passed in. So, why does the script continue to execute the first time but not the second?

Any ideas are appreciated, thank you for reading.

UPDATE 2: Turns out an issue with Nav Meshes on the created ships was stalling the script, problem fixed.

UPDATE: (as requested, here are the other methods in question)

	//get valid spawn point, then instantiate Ship:
	private IEnumerator ChooseSpawnAndInstantiateShip(ShipTypes desiredShipType, bool isNPCShip)
	{
		Debug.Log("ChooseSpawnAndInstantiateShip() coroutine started...");

		yield return StartCoroutine(GetSpawnPoint() ); //grab a valid spawn point for the incoming ship...
		Debug.Log("valid spawn point found for new ship...");

		GameObject ship; //becomes the instantiated prefab...

		if(isNPCShip)
		{
			//create a new GO parent of the instan.GO, attatch the script to it (so the prefab can get NPC/Player controll):
			GameObject npcShipGOParent = new GameObject();
			npcShipGOParent.name = "NPCShip";
			npcShipGOParent.transform.parent = parent_NPCShips;
			Ship_ControlSetter sCS = npcShipGOParent.AddComponent<Ship_ControlSetter>();
			sCS.ShipControlledBy = ShipControlledBy.NPC;
			
			//Debug.Log("Manager_ShipSpawning: ChooseSpawnAndInstantiateShip() Breaking");
			//Debug.Break();

			//instantiate ship at spawn point:
			if(desiredShipType != 0) //random ship desired...
			{
				ship = (GameObject) Instantiate(shipArray[(int) desiredShipType], tempSpawnLocation, Quaternion.identity);
				Debug.Log("new NPC ship of value: " + (int) desiredShipType + " should have been instantiated");
				ship.transform.parent = npcShipGOParent.transform;
			}
			else //random ship is desired:
			{
				ship = (GameObject) Instantiate(shipArray[Random.Range(1, shipArray.Length)], tempSpawnLocation, Quaternion.identity); //1 because of enum values...
				Debug.Log("new randomized NPC ship should have been instantiated");
				ship.transform.parent = npcShipGOParent.transform;
			}
		}
		else //Player ship...
		{
			//create a new GO parent of the instan.GO, attatch the script to it (so the prefab can get NPC/Player controll):
			GameObject playerShipGOParent = new GameObject();
			playerShipGOParent.name = "PlayerShip";
			playerShipGOParent.transform.parent = parent_PlayerShips;
			Ship_ControlSetter sCS = playerShipGOParent.AddComponent<Ship_ControlSetter>();
			sCS.ShipControlledBy = ShipControlledBy.Player;

			//Debug.Log("Manager_ShipSpawning: ChooseSpawnAndInstantiateShip() Breaking");
			//Debug.Break();

			//instantiate the player ship at the chosen spawn point:
			if(desiredShipType != 0) //specific ship desired...
			{
				ship = (GameObject) Instantiate(shipArray[(int) desiredShipType], tempSpawnLocation, Quaternion.identity);
				Debug.Log("new Player ship of value: " + (int) desiredShipType + " should have been instantiated");
				ship.transform.parent = playerShipGOParent.transform;
			}
			else //random ship is desired:
			{
				ship = (GameObject) Instantiate(shipArray[Random.Range(1, shipArray.Length)], tempSpawnLocation, Quaternion.identity); //1 because of enum values...
				Debug.Log("new randomized Player ship should have been instantiated");
				ship.transform.parent = playerShipGOParent.transform;
			}

			#region set ship correctly for Player Usage:
			//the pathfinding GO and and NPC logic script need to get disabled/turned off:
			Debug.Log("Manager_ShipSpawning disabling NPC components for Player Ship use...");
			Transform pathfindingTrans = ship.transform.FindChild("Pathfinder");
			pathfindingTrans.gameObject.GetComponent<NavMeshAgent>().enabled = false;
			pathfindingTrans.gameObject.SetActive(false);

			ship.GetComponentInChildren<NPC_Logic>().enabled = false;
			//Debug.Log("ship.GetComponentInChildren<NPC_Logic>().enabled = false");
			#endregion set ship correctly for Player Usage:
		}

		#region Final Setups for NPC/Player ships:
		Ship_Initializer shipInitializer = ship.GetComponentInChildren<Ship_Initializer>();
		shipInitializer.SetupShip();
		
		UI_ObjectTracker.ui_ObjectTracker.Activate();
		#endregion Final Setups for NPC/Player ships:

		yield return null; //wait to make sure 2 ships don't get spawned on top of each other in the same frame...
	}

	//use this to effectively "lock up" Instantiation coroutines if no new spawn point is available:
	private IEnumerator GetSpawnPoint()
	{
		Debug.Log("GetSpawnPoint() coroutine started");

		//get valid spawn point:
		while(true)
		{
			Debug.Log("GetSpawnPoint() coroutine running...");

			tempSpawnLocation = spawnTransList[Random.Range(0, spawnTransList.Count)].transform.position;
			Debug.Log("tempSpawnLocation is: " + tempSpawnLocation);

			//Debug.Log("Manager_ShipSpawning: GetSpawnPoint() breaking");
			//Debug.Break();

			//now test to see if the spawnpoint is valid:
			if(!Physics.CheckSphere(tempSpawnLocation, spawnSafeRadius, layersToCheckAgainst) ) //if nothing is hit in layermask...
			{
				//Debug.Log("ManagerShipSpawning: GetSpawnPoint() breaking");
				//Debug.Break();

				yield break;
			}
			else
			{
				Debug.Log("randomly selected spawnpoint was not valid, trying again...");
				yield return new WaitForSeconds(1f); //done to minimize collider checks per frame...
			}
		}
	}

Put some logs into ChooseSpawnAndInstantiateShip to see where its actually getting to. Maybe yield return StartCoroutine(GetSpawnPoint()); isn’t returning or something.

Also, in GetSpawnPoint you don’t need to yield break, you can just break. A coroutine needs to have at least one yield in it, but it doesn’t actually need to get called in every code path.