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

Having trouble with wavespawner system

Discussion in 'Scripting' started by Tazzoman, Mar 22, 2021.

  1. Tazzoman

    Tazzoman

    Joined:
    Aug 19, 2018
    Posts:
    2
    My wavesspawner script does a number of things, tracks enemies, awards nanites via the scoremanager when enemies get killled, deducts HP when enemies make it to the mainframe (the goal), etc. Everything in this script works great. What I am trying to add is an enemy that has its own spawner and creates replicants of itself.

    I am having trouble with the UFOSpawner script (2nd one in this list) in adding active enemies to the wavespawner. When I add:
    wavespawner2.Instance.ActiveEnemies.Add(EnemyEvent.enemyId, enemySpawned);
    to the spawn section it does keep the level running, but when I kill the enemy it doesn't end the level, nor does it give nanites or do damage to the mainframe. I have tried it a varries amount of ways with no luck, I don't know what I am missing. I admit I barely understand how this works together as I am new to unity and C#. I have kinda been hammering my way through. Thanks all!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5.  
    6. public class wavespawner2 : MonoBehaviour
    7. {
    8.     private static wavespawner2 instance;
    9.     public static wavespawner2 Instance
    10.     {
    11.         get { return instance; }
    12.     }
    13.  
    14.     [System.Serializable]
    15.     public class wave
    16.     {
    17.         public string waveName;
    18.         public GameObject[] enemy;
    19.         public int count;
    20.         [Tooltip("Time between each spawn, lower = faster")]
    21.         public float rate;
    22.         public float waveTimer;
    23.         public Transform[] SpawnPos;
    24.     }
    25.  
    26.     [Tooltip("Sign to turn on during the wave")]
    27.     public GameObject sign;
    28.     [Tooltip("The amount of gigabyte gained for winning with perfect state")]
    29.     [SerializeField] public int gigabyteForCleanWin;
    30.     [Tooltip("The amount of gigabyte gained for winning with less then perfect")]
    31.     [SerializeField] public int gigabyteForNormalWin;
    32.     [SerializeField] public int gigabyteForFail;
    33.     [SerializeField] public int levelunlock;
    34.     [SerializeField] public int startnanites;
    35.  
    36.  
    37.     public wave[] waves;
    38.     public float TimeBetweenWAves = 3f;
    39.     public bool spawn = true;
    40.     public bool wavespawn = true;
    41.     public int nextwave = 0;
    42.  
    43.     private Dictionary<int, GameObject> activeEnemies;
    44.  
    45.     public Dictionary<int, GameObject> ActiveEnemies { get => activeEnemies; set => activeEnemies = value; }
    46.  
    47.     private Coroutine spawner;
    48.  
    49.     private void Awake()
    50.     {
    51.  
    52.     }
    53.  
    54.     public void activate()
    55.     {
    56.         Debug.Log("Start spawning of " + gameObject.name);
    57.         sign.SetActive(true);
    58.         instance = this;
    59.         wavespawn = true;
    60.         nextwave = 0;
    61.         spawn = true;
    62.         ScoreManager.Instance.GainNanites(startnanites);
    63.         activeEnemies = new Dictionary<int, GameObject>();
    64.  
    65.         if (spawner != null)
    66.         {
    67.             StopCoroutine(spawner);
    68.         }
    69.  
    70.         spawner = StartCoroutine(DoSpawn());
    71.     }
    72.  
    73.     public void StopSpawning()
    74.     {
    75.         if (spawner != null)
    76.         {
    77.             StopCoroutine(spawner);
    78.             spawner = null;
    79.             sign.SetActive(false);
    80.         }
    81.     }
    82.  
    83.     IEnumerator DoSpawn()
    84.     {
    85.         while (nextwave <= waves.Length)
    86.         {
    87.             if (wavespawn)
    88.             {
    89.                 yield return new WaitForSeconds(TimeBetweenWAves);
    90.  
    91.                 //set current wave data to HUD
    92.                 if (nextwave < waves.Length)
    93.                 {
    94.                     SetWaveDataToHUD(waves[nextwave]);
    95.                 }
    96.  
    97.                 for (int i = 0; i < waves[nextwave].count; i++)
    98.                 {
    99.  
    100.                     {
    101.                         yield return new WaitForSeconds(waves[nextwave].rate);
    102.                         SpawnUnit(waves[nextwave].enemy[Random.Range(0, waves[nextwave].enemy.Length)], waves[nextwave]);
    103.                     }
    104.                 }
    105.                 wavespawn = false;
    106.             }
    107.  
    108.             yield return new WaitForSeconds(waves[nextwave].waveTimer);
    109.             if (nextwave + 1 > waves.Length - 1)
    110.             {
    111.                 spawn = false;
    112.                 yield break;
    113.             }
    114.  
    115.             else
    116.  
    117.             {
    118.                 nextwave++;
    119.                 wavespawn = true;
    120.             }
    121.         }
    122.     }
    123.  
    124.     void SpawnUnit(GameObject enemy, wave _wave)
    125.     {
    126.         // Instantiate(enemy, _wave.SpawnPos.position, Quaternion.Euler(new Vector3(0, 180, 0)));
    127.         GameObject enemySpawned = Instantiate(enemy, _wave.SpawnPos[Random.Range(0, _wave.SpawnPos.Length)].position, Quaternion.Euler(new Vector3(0, 180, 0)));
    128.         EnemyEvent enemyEvent = enemySpawned.AddComponent<EnemyEvent>();
    129.         enemyEvent.MyEnemyId = ++EnemyEvent.enemyId;
    130.         enemyEvent.Agent = enemySpawned.GetComponent<NavMeshAgent>();
    131.         enemyEvent.OnEnemyStateChagned += OnEnemyStateChanged;
    132.         activeEnemies.Add(enemyEvent.MyEnemyId, enemySpawned);
    133.     }
    134.  
    135.  
    136.     public void ClearRemainingEnemies()
    137.     {
    138.         if (spawner != null)
    139.         {
    140.             StopCoroutine(spawner);
    141.         }
    142.  
    143.         if (activeEnemies != null)
    144.         {
    145.             foreach (KeyValuePair<int, GameObject> enemy in activeEnemies)
    146.             {
    147.                 if (enemy.Value != null)
    148.                 {
    149.                     Destroy(enemy.Value);
    150.                 }
    151.             }
    152.  
    153.             activeEnemies.Clear();
    154.         }
    155.     }
    156.  
    157.     /// <summary>
    158.     /// Called by an enemy when it's state has changed
    159.     /// </summary>
    160.     /// <param name="currentEnemy">The current state an enemy has changed to</param>
    161.     private void OnEnemyStateChanged(int enemyobjectid, EnemyEvent.EnemyState currentEnemy)
    162.     {
    163.         switch (currentEnemy)
    164.         {
    165.             case EnemyEvent.EnemyState.DIED:
    166.                 if (activeEnemies.ContainsKey(enemyobjectid))
    167.                 {
    168.                     activeEnemies.Remove(enemyobjectid);
    169.                 }
    170.                 if (ScoreManager.Instance != null)
    171.                 {
    172.                     ScoreManager.Instance.KilledAnEnemy();
    173.                 }
    174.                 else
    175.                 {
    176.                     Debug.LogError("There should be one ScoreManager script attached to a gameobject in your scene.");
    177.                 }
    178.                 break;
    179.             case EnemyEvent.EnemyState.REACHED_MAINFRAME:
    180.                 if (activeEnemies.ContainsKey(enemyobjectid))
    181.                 {
    182.                     activeEnemies.Remove(enemyobjectid);
    183.                 }
    184.                 if (ScoreManager.Instance != null)
    185.                 {
    186.                     ScoreManager.Instance.EnemyReachedMainFrame();
    187.                 }
    188.                 else
    189.                 {
    190.                     Debug.LogError("There should be one ScoreManager script attached to a gameobject in your scene.");
    191.                 }
    192.                 break;
    193.         }
    194.     }
    195.  
    196.     /// <summary>
    197.     /// Displays current wave data to the HUD
    198.     /// </summary>
    199.     /// <param name="waveData">The current wave</param>
    200.     private void SetWaveDataToHUD(wave waveData)
    201.     {
    202.         if (HUD.Instance != null)
    203.         {
    204.             HUD.Instance.SetWaveData(waveData);
    205.             // wavenumbersign.Instance.SetWaveData(waveData);
    206.             //        else
    207.             //        {
    208.             //            Debug.LogError("There is no HUD script in the scene. Add the HUD prefab to your scene.");
    209.             //        }
    210.         }
    211.     }
    212.  
    213.  
    214.     // Start is called before the first frame update
    215.     void Start()
    216.     {
    217.  
    218.     }
    219.  
    220.     // Update is called once per frame
    221.     void Update()
    222.     {
    223.  
    224.     }
    225. }
    226.  
    UFOSPAWNER:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5. using UnityEngine.UI;
    6.  
    7. public class ufospawner : MonoBehaviour
    8. {
    9.     [System.Serializable]
    10.  
    11.     public class wave
    12.  
    13.     {
    14.         public GameObject[] enemy;
    15.         public int count;
    16.         public float rate;
    17.         public float waveTimer;
    18.         public Transform[] SpawnPos;
    19.     }
    20.  
    21.     public wave[] waves;
    22.     public float TimeBetweenWAves = 3f;
    23.     public bool spawn = true;
    24.     public bool wavespawn = true;
    25.  
    26.     public int nextwave = 0;
    27.  
    28.     void Awake()
    29.     {
    30.         if (spawn)
    31.         {
    32.             StartCoroutine(DoSpawn());
    33.         }
    34.     }
    35.     IEnumerator DoSpawn()
    36.     {
    37.         while (nextwave <= waves.Length)
    38.         {
    39.             if (wavespawn)
    40.             {
    41.                 yield return new WaitForSeconds(TimeBetweenWAves);
    42.                 for (int i = 0; i < waves[nextwave].enemy.Length; i++)
    43.                 {
    44.                     for (int j = 0; j < waves[nextwave].count; j++)
    45.                     {
    46.                         yield return new WaitForSeconds(waves[nextwave].rate);
    47.                         SpawnUnit(waves[nextwave].enemy[i], waves[nextwave]);
    48.                     }
    49.                 }
    50.                 wavespawn = false;
    51.             }
    52.  
    53.             yield return new WaitForSeconds(waves[nextwave].waveTimer);
    54.             if (nextwave + 1 > waves.Length - 1)
    55.             {
    56.                 Debug.Log("waves completed");
    57.                 spawn = false;
    58.                 yield break;
    59.             }
    60.             else
    61.             {
    62.                 nextwave++;
    63.                 wavespawn = true;
    64.             }
    65.         }
    66.     }
    67.     void SpawnUnit(GameObject enemy, wave _wave)
    68.     {
    69.         GameObject enemySpawned = Instantiate(enemy, _wave.SpawnPos[Random.Range(0, _wave.SpawnPos.Length)].position, Quaternion.Euler(new Vector3(0, 180, 0)));
    70.         EnemyEvent enemyEvent = enemySpawned.AddComponent<EnemyEvent>();
    71.         enemyEvent.MyEnemyId = ++EnemyEvent.enemyId;
    72.         wavespawner2.Instance.ActiveEnemies.Add(EnemyEvent.enemyId, enemySpawned); // should add enemy to wavespawner
    73.     }
    74. }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,780
    You can stare at code a long time and never actually see what's going on if it's a data issue.

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run?
    - what are the values of the variables involved? Are they initialized?

    Knowing this information will help you reason about the behavior you are seeing.
     
    TadasTalalas likes this.
  3. Tazzoman

    Tazzoman

    Joined:
    Aug 19, 2018
    Posts:
    2
    It has something to do with the UFO Spawner not setting the OnEnemyStateChanged, but I don't know how to do it.