- Home /
How can I spawn different GameObjects using IEnumerator?
Hi!
I've been searching all day and I still can't find an answer, so let's get straight to the point. My game has two principal scripts that control everything, the first, named "Game_Controller" has access to score, and the second named "Object_Spawner", is responsible for spawning GameObjects according to the score in Game_Controller.
If score > 5, Object_Spawner will spawn a different GameObject, it's like creating a new wave of enemies.
For that, I'm using IEnumerator and coroutines to start and stop a wave, the first wave spawn seems to work fine, but the problem is when I start the second wave it will just spawn hundreds of objects at high speed. Please note that I'm using a random timer in order to spawn objects at random time. I think the issue with the second wave has something to do with the timer.
The problem is when I start coroutine diamond. Please if there's something bad in my code please notify me, Im just 17.
Thaanks!
CODE (Object_Spawner):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Object_Spawner : MonoBehaviour {
private float Timer;
public GameObject wave_Cam;
public Text wave_Text;
public Transform spawner;
public GameObject victim;
public GameObject Clone;
public Transform diamond_Spawner;
public GameObject diamond_Obstacle;
public GameObject diamond_Clone;
public IEnumerator coroutine_Triangle;
public IEnumerator coroutine_Diamond;
// Use this for initialization
void Start () {
RandomTimer();
coroutine_Triangle = Callvictim (); // Assign function to variable coroutine_Triangle
StartCoroutine(coroutine_Triangle); // On start run Triangle coroutine
coroutine_Diamond = callDiamond (); // Assign function to variable coroutine_Diamond
StopCoroutine (coroutine_Diamond); // On start don't run Diamond coroutine
// coroutine_Gear = callGear(); // Assign function to variable coroutine_Diamond
// StopCoroutine (coroutine_Gear); // On start don't run Gear coroutine
}
void RandomTimer()
{
Timer = Random.Range(0.9f , 1.8f);
}
void spawnVictim(){ // Spawn Triangle function
Clone = Instantiate (victim, spawner.transform.position, spawner.rotation) as GameObject;
Clone.GetComponent<Rigidbody2D> ().AddForce (Vector2.left * 300);
}
void spawnDiamond(){ // Spawn Diamond function
diamond_Clone = Instantiate (diamond_Obstacle, diamond_Spawner.transform.position, diamond_Spawner.rotation) as GameObject;
diamond_Clone.GetComponent<Rigidbody2D> ().AddForce (Vector2.left * 380);
}
IEnumerator Callvictim() // Start Callvictim to spawn triangles by random time
{
//---------------------------------------------------------// WAVE ACTIVATOR
wave_Text.text = "WAVE 1";
yield return new WaitForSeconds (1);
wave_Cam.SetActive (true);
yield return new WaitForSeconds (2);
wave_Cam.SetActive (false);
//---------------------------------------------------------//
while (true) {
spawnVictim ();
yield return new WaitForSeconds (Timer);
RandomTimer ();
}
}
IEnumerator callDiamond() // Start callDiamond to spwan Diamonds by random time **--PROBLEM--**
{
while (true) {
spawnDiamond ();
yield return new WaitForSeconds (Timer);
RandomTimer ();
}
}
public void stop_Coroutine_Triangle(){ // Stop top Triangle coroutine
StopCoroutine (coroutine_Triangle);
}
public void start_Coroutine_Diamond(){ // Start top Diamond coroutine
StartCoroutine (coroutine_Diamond);
}
public void stop_Coroutine_Diamond(){ // Stop top Diamond coroutine
StopCoroutine (coroutine_Diamond);
}
void Update(){
}
}
CODE (Game_Controller):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Game_Controller : MonoBehaviour {
public GameObject up_Plane;
public int accessedCount;
// Use this for initialization
void Start () {
access_Count (); // Execute function on start
}
void access_Count(){ // Get access to count int located in a different script
accessedCount = up_Plane.GetComponent<GO_UP> ().count;
}
void check_points(){
if (accessedCount > 2) { // Triangle wave
Camera.main.GetComponent<Spawner_Up> ().stop_Coroutine_Triangle();
Camera.main.GetComponent<Spawner_Down> ().stop_Coroutine_Triangle_2();
}
if (accessedCount > 4) {
Camera.main.GetComponent<Spawner_Up> ().start_Coroutine_Diamond();
}
if (accessedCount > 5) {
Camera.main.GetComponent<Hex_Spawn> ().enabled = true;
}
}
// Update is called once per frame
void Update () {
check_points (); // Execute function to check points
access_Count (); // Execute function to update points
}
}
I think the problem is at IEnumerator callDiamond();
Answer by pako · Dec 25, 2017 at 06:46 PM
You haven't provided any information or relative code to show what are the Spawner_Up
and Spawner_Down
components, which are used in check_points()
method of Game_Controller
.
However, I can only assume that they are related to the the Object_Spawner
, since they contain methods of the same name, e.g. start_Coroutine_Diamond()
.
What you are doing wrong is your're starting coroutine_Diamond
multiple times, once per frame to be exact, since you are calling check_points ()
, which starts this coroutine, from inside Update()
.
So, as soon as accessedCount > 4
becomes true, a new instance of coroutine_Diamond
will be created and started, in every frame.
So, check if the coroutine has started, before starting it again. Something like:
//quick fix
bool diamondStarted;
//etc...
if (accessedCount > 4 && !diamondStarted) {
Camera.main.GetComponent<Spawner_Up> ().start_Coroutine_Diamond();
diamondStarted = true; //reset to false at some point
}
...you get the idea... Now that you know where the problem is, maybe you can find a better solution to this (better than my quick fix), since you have all the relevant code in front of you.
Your answer
![](https://koobas.hobune.stream/wayback/20220612145211im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Cant Play Sound On Destroy 2 Answers
How do I move a 2d object to center of screen? 1 Answer
Small error C# 2 Answers
Unity 5 UNet Spawn as Child. 1 Answer
Unity UFO tutorial question about code 0 Answers