0
\$\begingroup\$

does anyone knows how to shorten down this script and that I can edit the amount of enemies I want to spawn in, so that I don't have to keep on copying and pasting the same method below again and again, my code is also making my game a bit laggy. Which isn't a good sign. This is my code:

    public bool fromTop = false;

public GameObject enemy1;
public float enemy1Time = 2f;

public GameObject enemy2;
public float enemy2Time = 2f;

public GameObject enemy3;
public float enemy3Time = 2f;

public GameObject enemy4;
public float enemy4Time = 2f;

// Variable to know how fast we should create new enemies


void Start() {  
    InvokeRepeating ("Enemy1", enemy1Time, enemy1Time);
    InvokeRepeating ("Enemy2", enemy2Time, enemy2Time);
    InvokeRepeating ("Enemy3", enemy3Time, enemy3Time);
    InvokeRepeating ("Enemy4", enemy4Time, enemy4Time);
}

void Enemy1() {  
    Vector2 spawnPoint = new Vector2 (transform.position.x, transform.position.y);

    if (fromTop)
    {
        float x1 = transform.position.x - GetComponent<Renderer> ().bounds.size.x / 2;
        float x2 = transform.position.x + GetComponent<Renderer> ().bounds.size.x / 2;

        // Randomly pick a x point within the spawn object
        spawnPoint.x = Random.Range (x1, x2);
    }
    else
    {
        float y1 = transform.position.y - GetComponent<Renderer> ().bounds.size.y / 2;
        float y2 = transform.position.y + GetComponent<Renderer> ().bounds.size.y / 2;

        // Randomly pick a y point within the spawn object
        spawnPoint.y = Random.Range (y1, y2);
    }
    Instantiate (enemy1, spawnPoint, Quaternion.identity);
}
void Enemy2() {  
    Vector2 spawnPoint = new Vector2 (transform.position.x, transform.position.y);

    if (fromTop)
    {
        float x1 = transform.position.x - GetComponent<Renderer> ().bounds.size.x / 2;
        float x2 = transform.position.x + GetComponent<Renderer> ().bounds.size.x / 2;

        // Randomly pick a x point within the spawn object
        spawnPoint.x = Random.Range (x1, x2);
    }
    else
    {
        float y1 = transform.position.y - GetComponent<Renderer> ().bounds.size.y / 2;
        float y2 = transform.position.y + GetComponent<Renderer> ().bounds.size.y / 2;

        // Randomly pick a y point within the spawn object
        spawnPoint.y = Random.Range (y1, y2);
    }
    Instantiate (enemy2, spawnPoint, Quaternion.identity);
}
void Enemy3() {  
    Vector2 spawnPoint = new Vector2 (transform.position.x, transform.position.y);

    if (fromTop)
    {
        float x1 = transform.position.x - GetComponent<Renderer> ().bounds.size.x / 2;
        float x2 = transform.position.x + GetComponent<Renderer> ().bounds.size.x / 2;

        // Randomly pick a x point within the spawn object
        spawnPoint.x = Random.Range (x1, x2);
    }
    else
    {
        float y1 = transform.position.y - GetComponent<Renderer> ().bounds.size.y / 2;
        float y2 = transform.position.y + GetComponent<Renderer> ().bounds.size.y / 2;

        // Randomly pick a y point within the spawn object
        spawnPoint.y = Random.Range (y1, y2);
    }
    Instantiate (enemy3, spawnPoint, Quaternion.identity);
}
void Enemy4() {  
    Vector2 spawnPoint = new Vector2 (transform.position.x, transform.position.y);

    if (fromTop)
    {
        float x1 = transform.position.x - GetComponent<Renderer> ().bounds.size.x / 2;
        float x2 = transform.position.x + GetComponent<Renderer> ().bounds.size.x / 2;

        // Randomly pick a x point within the spawn object
        spawnPoint.x = Random.Range (x1, x2);
    }
    else
    {
        float y1 = transform.position.y - GetComponent<Renderer> ().bounds.size.y / 2;
        float y2 = transform.position.y + GetComponent<Renderer> ().bounds.size.y / 2;

        // Randomly pick a y point within the spawn object
        spawnPoint.y = Random.Range (y1, y2);
    }
    Instantiate (enemy4, spawnPoint, Quaternion.identity);
}

Please and Thank you. :)

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

In your code all spawn times are the same. If they can be different, things get more complicated, but I assume, that is what you are going for. Unfortunatley it seems to be impossible to pass parameters to the InvokeRepeating method (Unity Answers). So we do not use this method and handle the timed spawning on our own:

public bool fromTop = false;

public GameObject[] enemies;       
public float[] enemySpawnTimes;    
private float[] lastSpawnTimes;    // stores the time an enemy was spawned the last time

void Start()
{
    enemies = ...          // fill with enemies
    enemySpawnTimes = ...  // fill with corresponding times

    lastSpawnTimes = new float[enemies.Length];     
}

void Update()
{
    for (int i = 0; i < enemies.Length; i++)
    {
        lastSpawnTimes[i] += Time.deltaTime;

        if (lastSpawnTimes[i] >= enemySpawnTimes[i])
        {
            lastSpawnTimes[i] = 0;
            SpawnEnemy(enemies[i]);
        }
    }
}

void SpawnEnemy(GameObject enemy) 
{  
    var spawnPoint = new Vector2(transform.position.x, transform.position.y);

    if (fromTop)
    {
        var x1 = transform.position.x - GetComponent<Renderer> ().bounds.size.x / 2;
        var x2 = transform.position.x + GetComponent<Renderer> ().bounds.size.x / 2;

        spawnPoint.x = Random.Range (x1, x2);
    }
    else
    {
        var y1 = transform.position.y - GetComponent<Renderer> ().bounds.size.y / 2;
        var y2 = transform.position.y + GetComponent<Renderer> ().bounds.size.y / 2;

        spawnPoint.y = Random.Range (y1, y2);
    }
    Instantiate (enemy, spawnPoint, Quaternion.identity);
}
\$\endgroup\$
6
  • \$\begingroup\$ Thank you for your response, actually I change the spawn times in my inspector for each different enemies because I don't want them to be spawning in at the same time. Also that do I change this : enemies = ... // fill with enemies & enemySpawnTimes = ... // fill with corresponding times, to because I'm not really sure what to do. Thank you for your response. :) \$\endgroup\$ Aug 20, 2016 at 23:35
  • \$\begingroup\$ These two lines should just show that you have to fill the arrays with values. If you are setting the enemies and times via the inspector window then you can just delete them. \$\endgroup\$ Aug 21, 2016 at 5:11
  • \$\begingroup\$ Thank you for your reply, I'm getting this error every time I play the game - error: IndexOutOfRangeException: Array index is out of range. SpawnScript.Update () and this error CompareApproximately (det, 1.0F, .005f) UnityEngine.Quaternion:LookRotation(Vector3, Vector3) \$\endgroup\$ Aug 21, 2016 at 8:42
  • \$\begingroup\$ Your arrays probably do not have the same size. The loop goes through all enemies, but there could be less spawn times. Output the size of all arrays via Debug.Log(...) at the beginning of the update method to check if the arrays have the same length. \$\endgroup\$ Aug 21, 2016 at 9:26
  • \$\begingroup\$ thank you for your reply, sorry but could you tell me if I did this right : Debug.Log("Array Length: " + enemies.Length); \$\endgroup\$ Aug 21, 2016 at 9:29
0
\$\begingroup\$

You need to put it in the Update. Here is how you're code will be-

float time; float counter; 
void Update()
{ 
    time = Time.deltaTime; 
    if (time > 3) 
    {
        //spawn enemy// 
        time = 0; 
        counter++;
    } 
    if (counter == //the limit of enemies//)
        time = 0;
}

The counter if keeping track of the number of enemies. With this, a enemy is spawned every 3 seconds. I hope this helps

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .