- 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
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