- Home /
This question was
closed Apr 27, 2016 at 07:44 AM by
Internetman.
Question by
Internetman · Apr 25, 2016 at 10:39 AM ·
c#instantiaterandomspawnspawning problems
Spawn enemies so they aren't spawned on top of each other (C#)
Hello my fellow great Unites, I have an enemy spawn system that spawns out enemies using Ienumerator inside a set of borders. Now the only problem is that the enemies will sometimes spawn out on the player, or another object..
How can I fix this problem? Using a for loop?
Here's the code:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class EnemySpawn : MonoBehaviour
{
// EnemyPrefabs
public GameObject EnemyBouncingPrefab;
public GameObject EnemyGrowerPrefab;
public GameObject EnemyMinePrefab;
//Show where spawn is prefab
public GameObject showEnemySpawn;
public GameObject showEnemyFlyBySpawn;
public GameObject showEnemyGrowerSpawn;
public GameObject showEnemyMineSpawn;
// Array of spawn points
public Transform[] spawnPointsEnemyFollow;
public Transform[] spawnPointsEnemyExplode;
public Transform[] spawnPointsEnemyFlyBy;
// Borders
public Transform borderTop;
public Transform borderBottom;
public Transform borderLeft;
public Transform borderRight;
//Used to put active enemies in a list
public static List<GameObject> activeEnemies;
void Start ()
{
// Starts a coroutine function for spawning bouncing enemies and fly by enemy
StartCoroutine(SpawnBouncingEnemy());
StartCoroutine(SpawnGrowerEnemy());
StartCoroutine(SpawnEnemyFlyBy());
StartCoroutine(SpawnMineEnemy());
}
void Awake()
{
// Create the list
activeEnemies = new List<GameObject>();
}
// Spawn a Bouncing enemy
IEnumerator SpawnBouncingEnemy()
{
//Wait 3 to 5 seconds when game starts to spawn a ball
yield return new WaitForSeconds(Random.Range(1, 3));
while(true)
{
//Calls the function to set random position
Vector2 spawnPoint = RandomPointWithinBorders();
// Show spawn location for one second
Object marker = Instantiate(showEnemySpawn, spawnPoint, Quaternion.identity);
yield return new WaitForSeconds(1);
Destroy(marker);
// Spawn enemy
GameObject newEnemy = (GameObject) Instantiate(EnemyBouncingPrefab, spawnPoint, Quaternion.identity);
activeEnemies.Add(newEnemy);
yield return new WaitForSeconds(Random.Range(4, 6));
}
}
// Spawn a Grower enemy
IEnumerator SpawnGrowerEnemy()
{
//Wait 3 to 5 seconds when game starts to spawn a "grower"
yield return new WaitForSeconds(Random.Range(20, 40));
while(true)
{
//Calls the function to set random position
Vector2 spawnPoint = RandomPointWithinBorders();
// Show spawn location for one second
Object marker = Instantiate(showEnemyGrowerSpawn, spawnPoint, Quaternion.identity);
yield return new WaitForSeconds(1);
Destroy(marker);
// Spawn enemy
GameObject newEnemy = (GameObject) Instantiate(EnemyGrowerPrefab, spawnPoint, Quaternion.identity);
activeEnemies.Add(newEnemy);
yield return new WaitForSeconds(Random.Range(20, 50));
}
}
// Spawn a Mine enemy
IEnumerator SpawnMineEnemy()
{
//Wait 40 to 60 seconds when game starts to spawn a "Mine_enemy"
yield return new WaitForSeconds(Random.Range(45, 60));
while(true)
{
//Calls the function to set random position
Vector2 spawnPoint = RandomPointWithinBorders();
// Show spawn location for one second
Object marker = Instantiate(showEnemyMineSpawn, spawnPoint, Quaternion.identity);
yield return new WaitForSeconds(2);
Destroy(marker);
// Spawn enemy
GameObject newEnemy = (GameObject) Instantiate(EnemyMinePrefab, spawnPoint, Quaternion.identity);
activeEnemies.Add(newEnemy);
yield return new WaitForSeconds(Random.Range(50, 60));
}
}
public Vector2 RandomPointWithinBorders()
{
//Code that will spawn a bouncing ball and ShowSpawn at a random position inside the borders
Vector2 random = new Vector2();
random.x = (int)Random.Range(borderLeft.position.x, borderRight.position.x);
random.y = (int)Random.Range(borderBottom.position.y, borderTop.position.y);
return random;
}
}
Comment
Best Answer
Answer by fafase · Apr 25, 2016 at 10:49 AM
Use a set of positions and an index that you push to avoid using the same entry again.
public Transform [] spawns;
private int index = 0;
public Vector3 GetPosition(){
if(++index >= this.spawns.Length){
index = 0;
}
return spawns[index];
}
You could add some more check to make sure the previous guy is gone from the position. The amount of spawns should be logical based on how you move your guys and how often you spawn them but this is the basic idea.