Search Unity

Question Trying to create array

Discussion in 'Scripting' started by badhavokk, Jun 7, 2020.

Thread Status:
Not open for further replies.
  1. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    Hi There,

    First post and new to programming so here goes... I've been following Brakeys Tower Defense tutorial and I am trying to create an array so I can spawn in enemies based on what is set inside Unity Inspector.

    I've kept the old code so you can see what I'm doing. With the code like that, it will spawn in each "set" of enemies one after the other, where as I want the enemies to spawn in concurrently...

    Right now - Enemy 1 spawns 10, before Enemy 2 appears
    Desire - Enemy 1 spawns every ~3 seconds, Enemy 2 spawns every 7 seconds : So, E1(3sec) > E1(6sec) > E2(7sec) > E1(9sec)

    The code gives me "cannot apply indexing with to an expression of type gameobject" but I can't see where I should define it/what I should write instead.

    Assets\Scripts\WaveSpawner.cs(73,21): error CS1001: Identifier expected


    Sorry if I've broken any rules... brain is fried from looking at how to tweak this specific code - hopefully understanding it more overall!

    Thank you in advance!

    Here is wave.cs

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [System.Serializable]
    4. public class Wave {
    5.  
    6.     public GameObject enemy0;
    7.     public int count;
    8.     public float rate;
    9.     public GameObject enemy1;
    10.     public int count1;
    11.     public float rate1;
    12.     public GameObject enemy2;
    13.     public int count2;
    14.     public float rate2;
    15.  
    16. }
    WaveSpawner.cs

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class WaveSpawner : MonoBehaviour {
    6.  
    7.     public static int EnemiesAlive = 0;
    8.  
    9.     public Wave[] waves;
    10.     public GameObject[] enemy;
    11.  
    12.     public Transform spawnPoint;
    13.  
    14.     public float timeBetweenWaves = 10f;
    15.     private float countdown = 2f;
    16.  
    17.     public Text waveCountdownText;
    18.  
    19.     public GameManager gameManager;
    20.  
    21.     private int waveIndex = 0;
    22.  
    23.  
    24.     void Start()
    25.     {
    26.         EnemiesAlive = 0;
    27.     }
    28.  
    29.     void Update ()
    30.     {
    31.         if (EnemiesAlive > 0)
    32.         {
    33.             return;
    34.         }
    35.  
    36.         if (waveIndex == waves.Length)
    37.         {
    38.             gameManager.WinLevel();
    39.             this.enabled = false;
    40.         }
    41.  
    42.         if (countdown <= 0f)
    43.         {
    44.             StartCoroutine(SpawnWave());
    45.             countdown = timeBetweenWaves;
    46.             return;
    47.         }
    48.  
    49.         countdown -= Time.deltaTime;
    50.  
    51.         countdown = Mathf.Clamp(countdown, 0f, Mathf.Infinity);
    52.  
    53.         waveCountdownText.text = string.Format("{0:00.00}", countdown);
    54.     }
    55.  
    56.     IEnumerator SpawnWave ()
    57.     {
    58.         PlayerStats.Rounds++;
    59.  
    60.         Wave wave = waves[waveIndex];
    61.      
    62.         EnemiesAlive = (wave.count + wave.count1 + wave.count2);
    63.      
    64.         {
    65.  
    66.             yield return new WaitForSeconds(1f / wave.rate);
    67.          
    68.             for (int i = 0; i < wave.count; i++)
    69.                 {
    70.                 for (int j = 0; j < wave.count; j++)
    71.                 {
    72.                 yield return new WaitForSeconds(wave.rate);
    73.                 SpawnEnemy(wave.enemy0[i]);
    74.                 }
    75.             }
    76.         }
    77.         // for (int i = 0; i < wave.count; i++)
    78.             // {
    79.                 // SpawnEnemy(wave.enemy);
    80.                 // yield return new WaitForSeconds(1f / wave.rate);
    81.             // }
    82.          
    83.         // if (wave.count1 >= 1)
    84.             // {
    85.             // for (int j = 0; j < wave.count1; j++)
    86.                 // {
    87.                     // SpawnEnemy1(wave.enemy1);
    88.                     // yield return new WaitForSeconds(1f / wave.rate1);
    89.                 // }
    90.             // }  
    91.          
    92.         // if (wave.count2 >= 1)
    93.             // {  
    94.             // for (int k = 0; k < wave.count2; k++)
    95.                 // {
    96.                     // SpawnEnemy2(wave.enemy2);
    97.                     // yield return new WaitForSeconds(1f / wave.rate2);
    98.                 // }
    99.             // }      
    100.          
    101.         waveIndex++;
    102.     }
    103.  
    104.     void SpawnEnemy (GameObject enemy)
    105.     {
    106.         Instantiate(enemy, spawnPoint.position, spawnPoint.rotation);
    107.     }
    108.  
    109.     void SpawnEnemy1(GameObject enemy1)
    110.     {
    111.         Instantiate(enemy1, spawnPoint.position, spawnPoint.rotation);
    112.     }
    113.  
    114.     void SpawnEnemy2(GameObject enemy2)
    115.     {
    116.         Instantiate(enemy2, spawnPoint.position, spawnPoint.rotation);
    117.     }
    118. }
     
    Last edited: Jun 7, 2020
  2. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    If I update
    Code (CSharp):
    1. SpawnEnemy(wave.[waveIndex].enemy[i]);
    I get CS1001 identifier expected... In case I'm closer?

    Edit: I also noticed the double for loop which isn't required... *sigh* been a long day! o_O
     
    Last edited: Jun 7, 2020
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    enemy0[i]
    doesn't make sense because enemy0 isn't an array

    enemy[i]
    is worse, because "enemy" doesn't exist; you don't have a variable by that name inside of Wave

    If you are trying to access wave number i, you need to write
    waves[i]


    If you are trying to access enemy number i within a given wave, then that's impossible with your current data structures, because you don't have an array of enemies, you have 3 distinct enemies with different names. Those names happen to be enemy0, enemy1, and enemy2, but from the computer's perspective that doesn't make them connected. From the computer's perspective, those are just arbitrary labels, same as if you named them foo, bar, and baz.

    Also note that count1, count2, rate1, and rate2 currently aren't being used in the spawn process at all. You are using the same "count" and "rate" variables for everything.

    If you want to be able to iterate through all the enemies in a wave, then you probably want to redefine your "Wave" class so it looks something like this:

    Code (CSharp):
    1. [System.Serializable]
    2. public class Wave {
    3.     public WavePart[] parts;
    4. }
    5.  
    6. [System.Serializable]
    7. public class WavePart {
    8.     public GameObject enemy;
    9.     public int count;
    10.     public float rate;
    11. }
    Alternately, you can "unroll" your loop so that you have completely separate code for enemy0, enemy1, and enemy2 rather than trying to access something called
    enemy[i]
     
  4. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    Thanks for confirming that to me. I've tweaked the code so much today that I'm not sure where I started right now.

    I'm not sure how to interpret your code and add it into what I have already but I would like to iterate through all enemies in the wave, based on their own "rate" which is defined in "Wave.cs". The enemy defined in the script is attached to a prefab inside Unity (Only way I could get more enemies defined in Unity was to give a new variable), is there a way to define the prefab itself which may then allow me to build an array?

    I commented out the old code (77>99) which was setup to call each enemy variant but it runs through each for statement and I can't work out how to run through all three enemy types and only send them based on their individual rate.

    My aim to get it setup this way is to help in future when I add more units and the waves begin to get more complicated.

    Appreciate any pointers to include your code, thanks very much!
     
  5. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    hi @Antistone

    Thanks again for the tips, I've done some research and I now understand how to place your suggestion into my code. I've done some further research but I'm not sure how I can access the nested data - if that's the term...

    As I'm in the learning stages still (obvious, much!) I'd appreciate what I need to search for to get this working.

    Thanks in advance interwibble!

    Wave.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [System.Serializable]
    4. public class Wave {
    5.  
    6. public WavePart[] parts;
    7. }
    8. [System.Serializable]
    9. public class WavePart {
    10.     public GameObject enemy;
    11.     public int count;
    12.     public float rate;
    13. }
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UnityEngine.UI;
    4.  
    5. public class WaveSpawner : MonoBehaviour {
    6.  
    7.     public static int EnemiesAlive = 0;
    8.  
    9.     public Wave[] waves;
    10.     public Wave[] waveparts;
    11.  
    12.     public GameObject enemy;
    13.  
    14.     public Transform spawnPoint;
    15.  
    16.     public float timeBetweenWaves = 10f;
    17.     private float countdown = 2f;
    18.  
    19.     public Text waveCountdownText;
    20.  
    21.     public GameManager gameManager;
    22.  
    23.     private int waveIndex = 0;
    24.  
    25.     void Start()
    26.     {
    27.         EnemiesAlive = 0;
    28.     }
    29.  
    30.     void Update ()
    31.     {
    32.         if (EnemiesAlive > 0)
    33.         {
    34.             return;
    35.         }
    36.  
    37.         if (waveIndex == waves.Length)
    38.         {
    39.             gameManager.WinLevel();
    40.             this.enabled = false;
    41.         }
    42.  
    43.         if (countdown <= 0f)
    44.         {
    45.             SpawnWave();
    46.             countdown = timeBetweenWaves;
    47.             return;
    48.         }
    49.  
    50.         countdown -= Time.deltaTime;
    51.  
    52.         countdown = Mathf.Clamp(countdown, 0f, Mathf.Infinity);
    53.  
    54.         waveCountdownText.text = string.Format("{0:00.00}", countdown);
    55.     }
    56.  
    57.  
    58.     void SpawnWave()
    59.     {
    60.         foreach (WavePart group in groups)
    61.             {
    62.                 for (int i = 0; i < group.WavePart.count; i++)
    63.                 {
    64.                     SpawnEnemy(group.enemy);
    65.                 }
    66.             }
    67.         }
    68.  
    69.     void SpawnEnemy (GameObject enemy)
    70.     {
    71.         Instantiate(enemy, spawnPoint.position, spawnPoint.rotation);
    72.     }
    73.  
    74. }

    Assets\Scripts\WaveSpawner.cs(62,31): error CS1061: 'WavePart' does not contain a definition for 'WavePart' and no accessible extension method 'WavePart' accepting a first argument of type 'WavePart' could be found (are you missing a using directive or an assembly reference?)
     
  6. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    It won't let me update, but the other error...


    Assets\Scripts\WaveSpawner.cs(60,30): error CS0103: The name 'groups' does not exist in the current context
     
  7. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    You do not have a variable named groups. I'm guessing you meant to iterate through your waves array. Although, I have no idea why you have two arrays of the wave class.
     
  8. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    I have two arrays because I'm still learning and tweaking the tutorial code that was written by Brackeys.

    I have corrected the duplicate class but I still have the other error below.

    Assets\Scripts\WaveSpawner.cs(62,31): error CS1061: 'WavePart' does not contain a definition for 'WavePart' and no accessible extension method 'WavePart' accepting a first argument of type 'WavePart' could be found (are you missing a using directive or an assembly reference?)


    A little feedback... Be constructive if you're going to criticise. I've admitted I'm learning and you have the opportunity to share.
     
  9. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Excuse me? I didn't criticize at all. I told you that you didn't have a variable named groups and now you don't have one called WavePart within the wave class.
     
  10. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    "Although, I have no idea why you have two arrays of the wave class." = criticism. "Although, there is no reason for two Wave [] arrays so you can remove it" = assistance.

    Thanks for telling me what I see... I just don't know what to learn to correct it. Everything I keep trying from online forums and this chain, keeps generating new errors so I'm trying to stick to one 'thing' that my very limited knowledge understands to be "the right path" (for me).

    I'm also reading up about different fixes for errors which tell me a new way to create the logic so everything is now confusing and I came to the forum for direction.

    I'm a sysadmin who scripts with relative confidence and I am trying to learn programming for fun while following this tutorial to do so. I followed the videos but still copied the code from his github so I knew I wouldn't encounter any silly bugs when I started to develop it further.
     
  11. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    That's not a criticism, I don't have any idea why you created two arrays. There could be a reason, only you know your thinking behind it.
     
  12. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    It's completely useless commentary. I have told you why. Just here to feed your ego?
     
  13. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    wtf? Good luck with it.
     
  14. badhavokk

    badhavokk

    Joined:
    Jun 7, 2020
    Posts:
    12
    I'm asking for help and you're just pointing out the failure.
     
  15. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    9,051
    Closed because arguing with people trying to help you illustrates that you don't want help at all and the thread is of no use. Read clearly what has been posted your answer is right there.
     
Thread Status:
Not open for further replies.