Reputation: 1
I have a really weird bug where I have a function that resets my whole room. First, it clears the previous grids if they exist. Then, it generates lists of lists of vectors, which work as grids. Then it spawns objects at random places of the grid, at least one space appart from each other, and then it does this with enemies too. When I collide with the player on another gameobject, this function is executed, resetting the room. The problem is that when I replace the function with a coroutine, my objects spawn properly, but my enemies only spawn at a specific area. I checked the enemy grid but it seems to be working just fine, and this only happens when the function that resets the room is called after a yield return. It works properly if it is called before a yield return. How can I solve this? Thanks.
The following video shows the full problem:
This is how the enemies spawn in a function or in a coroutine with the "roomSpawnerScript.Spawnear()" before a yield return:
This is how the enemis spawn in a coroutine after the yield return: CODE:
Empty collision object:
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "Player")
{
StartCoroutine(Siguiente());
}
}
private IEnumerator Siguiente()
{
Color newColor = Color.clear;
while (BlackScreen.GetComponent<Image>().color.a < 1)
{
newColor.a += 0.01f;
BlackScreen.GetComponent<Image>().color = newColor;
yield return null;
}
scrRoomSpawner roomSpawnerScript = roomSpawner.GetComponent<scrRoomSpawner>();
foreach (GameObject instancia in roomSpawnerScript.instancias)
{
Destroy(instancia);
}
roomSpawnerScript.Spawnear();
player.transform.position = playerSpawnPos;
yield return new WaitForSeconds(1);
while (BlackScreen.GetComponent<Image>().color.a > 0)
{
newColor.a -= 0.01f;
BlackScreen.GetComponent<Image>().color = newColor;
yield return null;
}
}
Object that resets the room (RoomSpawner):
public class scrRoomSpawner : MonoBehaviour
{
//Variables
public float gridWidth;
public float gridHeight;
public float objectNumber;
public float enemyNumber;
//Objetos
public GameObject bloque;
public GameObject enemy;
public GameObject enviroment;
public GameObject aa;
private List<Vector2> gridObjetos = new List<Vector2>();
private List<Vector2> gridEnemigos = new List<Vector2>();
public List<GameObject> instancias = new List<GameObject>();
// Start is called before the first frame update
void Start()
{
Spawnear();
}
// Update is called once per frame
void Update()
{
}
public void Spawnear()
{
gridObjetos.Clear();
gridEnemigos.Clear();
//Crear grid objetos
for (int x = 0; x < gridWidth; x++)
{
for (int y = 0; y < gridHeight; y++)
{
gridObjetos.Add(new Vector2(x - 7.5f, y - 5.5f));
}
}
//Crear grid enemigos
for (int x = 0; x < gridWidth; x++)
{
for (int y = 0; y < gridHeight; y++)
{
gridEnemigos.Add(new Vector2(x - 7.5f, y - 5.5f));
}
}
//Spawnear objetos
for (int i = 0; i < objectNumber; i++)
{
if (gridObjetos.Count > 0)
{
GameObject objeto = Instantiate(bloque);
objeto.transform.SetParent(enviroment.transform);
instancias.Add(objeto);
objeto.transform.position = gridObjetos[Random.Range(0, gridObjetos.Count)];
Vector2 vectorObjeto = objeto.transform.position;
Vector2 minBound = vectorObjeto - new Vector2(1, 1);
Vector2 maxBound = vectorObjeto + new Vector2(1, 1);
gridObjetos.RemoveAll(v => v.x >= minBound.x && v.x <= maxBound.x && v.y >= minBound.y && v.y <= maxBound.y);
}
}
//Spawnear enemigos
for (int i = 0; i < enemyNumber; i++)
{
GameObject enemigo = Instantiate(enemy);
instancias.Add(enemigo);
enemigo.transform.position = gridEnemigos[Random.Range(0, gridEnemigos.Count)];
Vector2 vectorEnemigo = enemigo.transform.position;
gridEnemigos.Remove(vectorEnemigo);
}
}
}
I tried putting callid the Spawnear() function before the yield return, and taht worked, but I want it to be after it, so that I can implement a transition first.
Upvotes: 0
Views: 42