Hi people, I hope you can help me with this!
Each wave, I make a list of all the enemies that should spawn. However, I only want to spawn some of them and not all of them. For example, on wave 3 there will be 15 enemies, but I only want 6-7 enemies max on screen at once (for difficulty reasons or perhaps even performance reasons).
I have fabricated this piece of code, were I count my enemies with a gameobject find that is on update.
function enemySpawn(){
while (enemyCount<i){ //while number of enemies is smaller than the length of the list
if (enemyCount<maxEnemyCount){ //only spawn if there are less than 3
Instantiate (eneContainer[x], spawnPoints[Random.Range(0,spawnPoints.length)].transform.position, Quaternion.identity);
x++;
}else break;
}
}
but it doesn’t work. Even though my max enemy count is 3 I still get all the enemies that are on the list, help?
by the way this is how I keep track of my enemycount.
function Update () {
enemyCount= GameObject.FindGameObjectsWithTag(“enemy”).Length;
Debug.Log("Enemy count: " + enemyCount);
}
I would advise coming up with an event driven solution rather than a constantly searching function (which has bad performance)
- Create a script to put on enemy
- Create two functions. Spawn. Die (for now… I would use the same script to control their movement, health, etc etc)
//going to call this class EnemyController;
public bool Alive = true;
public bool Spawned = false;
public Transform SpawnLocation;
function bool Spawn()
{
if(!Spawned Alive)
{
transform.position = SpawnLocation.position;
Spawned = true;
return true;
}
return false;
}
function Die()
{
Alive = false;
(FindObjectOfType(typeof(SpawnController)) as SpawnController).EnemyDied();
}
then under your spawn script (which would be like that one above)
//going to call this class SpawnController - NOTE: you only want one instance of this. Attach to say Main Camera
List<EnemyController> enemies;
function Start()
{
foreach(EnemyController enemy in FindObjectsOfType(typeof(EnemyController))
enemies.Add(enemy);
}
function SpawnEnemy()
{
foreach(EnemyController enemy in enemies)
{
if(enemy.Spawn())
return;
}
}
function EnemyDied()
{
SpawnEnemy()
}
something like that… lol… sorry this is a bit of a mix of c# / JS code so probably wont compile
So your suggestion is a different way to count enemies? because what I noticed is, my script works if I don’t use enemy count but use x instead. (enemycount is the variable that finds enemies by tag, while x just increases after an enemy is spawned).
So yes my script works that way but it stops at the maximum and I got to find a way for it to loop again so it produces the rest of the enemies if there is space in the screen again
I would just use a static variables and functions. It’s fairly simple to do. For example (in javascript, I don’t do much in c# myself.)
//Filename: Globals.js
//Globals script is only needed once per scene.
static var EnemyCount:int = 0;
static function CreateEnemy(position:Vector3, enemy:GameObject)
{
Quaternion.Instantiate(enemy, position, Quaternion.Identity);
EnemyCount += 1;
}
static function RemoveEnemy(enemy:GameObject)
{
Destroy(enemy);
EnemyCount -= 1;
//Could add to score, etc here as well
}
//Filename: SpawnCheck.js
var maxEnemies:int = 6;
var enemyPrefab:GameObject;
var spawnLocation:Vector3;
function Update()
{
if(Globals.EnemyCount < maxEnemies)
{
Globals.CreateEnemy(spawnLocation, enemyPrefab);
}
}
Then all you have to do is Globals.RemoveEnemy(gameObject); as the last line in your kill script. Simple as that. Now you can get a full enemy count any time you want, without wasting so much time using the find command (much slower then looking at an integer).
(Note, I just typed this up, and didn’t test, but everything should work fine.)
Alright seems like I will just have to do it the old way then.
I thought the find object function was the proper way to do it, but its slower people have said.
Thanks everyone!