Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Doubles enemies every wave

Discussion in 'Scripting' started by MrDiamondDog, Oct 13, 2020.

  1. MrDiamondDog

    MrDiamondDog

    Joined:
    Aug 12, 2020
    Posts:
    20
    Every wave of my game, the amount of enemies doubles from the previous waves. It goes 3, 4, 8, 16, 32, 64, 128, so on.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using TMPro;
    5.  
    6. public class WaveManager : MonoBehaviour
    7. {
    8.     public TMP_Text waveCounter;
    9.     public float spawnX;
    10.     public float spawnY;
    11.     public float spawnZ;
    12.  
    13.     public GameObject EnemyPrefab;
    14.     public GameObject Player;
    15.  
    16.     public int waves = 1;
    17.     public bool started = false;
    18.     public int enemyIncrement = 1;
    19.     public int totalEnemies = 0;
    20.  
    21.     // Start is called before the first frame update
    22.     void Start()
    23.     {
    24.         waveCounter.text = "Press 'f' to start the waves.";
    25.     }
    26.  
    27.     void Update()
    28.     {
    29.         if (Input.GetKeyDown(KeyCode.F))
    30.         {
    31.             if (!started)
    32.             {
    33.                 spawnEnemies(3);
    34.             }
    35.         }
    36.         if (started)
    37.         {
    38.             var enemies = GameObject.Find("/Enemy(Clone)");
    39.             if (enemies == null)
    40.             {
    41.                 waves += 1;
    42.                 var amountToSpawn = totalEnemies + enemyIncrement;
    43.                 waveCounter.text = "Wave " + waves + "\n" + amountToSpawn + " Enemies";
    44.                 spawnEnemies(amountToSpawn);
    45.             }
    46.         }
    47.     }
    48.  
    49.     public void spawnEnemies(int amount)
    50.     {
    51.         totalEnemies += 1;
    52.         if (!started)
    53.         {
    54.             started = true;
    55.         }
    56.         spawnX = Random.Range(-203, -182);
    57.         spawnY = 14;
    58.         spawnZ = Random.Range(65, 22);
    59.  
    60.         if (spawnX < 40)
    61.         {
    62.             spawnY = 8;
    63.         }
    64.  
    65.         var enemy = Instantiate(EnemyPrefab, new Vector3(spawnX, spawnY, spawnZ), Quaternion.identity);
    66.         var pm = enemy.GetComponent<PlayerManager>();
    67.         pm.player = Player;
    68.        
    69.         amount -= 1;
    70.         if (amount > 0)
    71.         {
    72.             spawnEnemies(amount);
    73.         }
    74.        
    75.     }
    76. }
    77.  
    can someone post some working code, please?
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    First off, going from 3 to 4 is not doubling. I would assume that the "3" was just a typo and was meant to be "2", except that you also have "3" in your source code.

    Notice that right now, you calculate amountToSpawn based on "totalEnemies" and "enemyIncrement", but "totalEnemies" and "enemyIncrement" do not ever change, so you are calculating the same sum every wave.

    If you want to use powers of 2 (i.e. 2, 4, 8, 16, ...) then you could calculate the amount to spawn as
    Mathf.Pow(2, wave)
    . Alternately, you could have a variable that stores the number of enemies spawned in the previous wave, and multiply it by 2 each time.

    If you want to be able to tune the individual numbers, you might instead create an array that lists how many enemies to spawn at each wave, and then you can insert the exact number you want for each wave, independent of other waves.



    You've also got some performance issues in your code.

    Your spawnEnemies function currently relies on tail recursion. In some languages that would be efficient, but the C# compiler does not use the tail-recursion optimization, so that's going to create a stack depth equal to the number of spawns. You should put the spawning code in a for loop instead of using a recursive call.

    Also, your Update function is calling GameObject.Find every single frame to check if the enemies are dead. Find is relatively expensive and Unity specifically recommends that you do not call it every frame. Unfortunately, this one isn't a simple fix; a true fix would require developing an entirely new strategy for tracking the remaining enemies. (Though a quick mitigation might be to check less often than every frame--if you checked, say, once per second, that would probably be good enough for deciding when to start the next save.)

    Your most-efficient option is probably to have an integer variable that tracks the number of living enemies, increasing it for spawns and decreasing it for deaths. But this is kind of dangerous because if the number ever somehow gets out of sync (due to some kind of bug), there's no way to recover.

    I might put all the spawned enemies into a HashSet, then periodically iterate the HashSet and remove the dead enemies, triggering the next wave when its count is zero.
     
    Terraya likes this.
  3. MrDiamondDog

    MrDiamondDog

    Joined:
    Aug 12, 2020
    Posts:
    20
    is it possible you can send me working code?
     
  4. Munchy2007

    Munchy2007

    Joined:
    Jun 16, 2013
    Posts:
    1,731
    Possible yes, likely, I doubt it...
     
    Terraya likes this.
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    Typically, when you ask for programming help on a forum, people will post enough example code to illustrate a point, but you are expected to do your own grunt work of incorporating it into your larger program and doing any necessary refactoring.

    If you want someone to write your program for you, that costs money.