Hi, I’m getting errors CS1502 and CS1503 for line 59. I’m trying to adapt a spawner that I made following a tutorial (which works correctly), as it did not have the ability to add various enemies (with different variables such as spawn count/rate etc.) I tried to overcome this by nesting a list within my wave array but i’m getting these errors. I’m not much of a scripter and still learning so please could someone identify my problem? I’ve posted both the initial script, and my adaptation below. Thanks in advance!
Initial Script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class WaveController : MonoBehaviour {
[System.Serializable]
public class Wave {
public string name;
public Transform enemy;
public int count;
public float spawnRate;
}
public float timeBetweenWaves = 5f;
private GameObject[] SpawnPoints;
public Wave[] Waves;
public bool enemiesAlive = false;
public bool spawning = false;
private static float _waveCountdown = 0f;
public static float waveCountdown {
get { return _waveCountdown; }
set { _waveCountdown = Mathf.Clamp (value, 0, Mathf.Infinity); }
}
public static int waveNumber = 1;
int waveIndex = 0;
void Start () {
waveNumber = 1;
waveCountdown = 5;
SpawnPoints = GameObject.FindGameObjectsWithTag ("EnemySpawnPoint");
InvokeRepeating ("WaveTracker", 0f, 1f);
}
void WaveTracker () {
if (waveCountdown == 0 && !spawning) {
if (GameObject.FindGameObjectsWithTag ("Enemy").Length == 0) {
enemiesAlive = false;
waveCountdown = timeBetweenWaves;
waveNumber++;
}
}
}
void Update () {
waveCountdown -= Time.deltaTime;
if (waveCountdown == 0 && enemiesAlive == false) {
StartCoroutine ( SpawnWave ( Waves[waveIndex] ) );
return;
}
}
public IEnumerator SpawnWave (Wave wave) {
enemiesAlive = true;
spawning = true;
yield return new WaitForSeconds (2f);
for (int i = 0; i < wave.count; i++)
{
int spawnIndex = Random.Range (0, SpawnPoints.Length);
Transform enemy = Instantiate (wave.enemy, SpawnPoints[spawnIndex].transform.position, SpawnPoints[spawnIndex].transform.rotation) as Transform;
yield return new WaitForSeconds (1f/wave.spawnRate);
}
if (waveIndex < Waves.Length - 1) //Calls next wave
{
waveIndex++;
}
else
{
waveIndex = 0;
}
spawning = false;
}
}
My adapted script:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class WaveController : MonoBehaviour {
[System.Serializable]
public class Wave {
List<WaveAction> actions;
}
[System.Serializable]
public class WaveAction {
public string name;
public Transform enemy;
public int count;
public float spawnRate;
}
public float timeBetweenWaves = 5f;
private GameObject[] SpawnPoints;
public Wave[] Waves; //Creates array
public bool enemiesAlive = false;
public bool spawning = false;
private static float _waveCountdown = 0f;
public static float waveCountdown {
get { return _waveCountdown; }
set { _waveCountdown = Mathf.Clamp (value, 0, Mathf.Infinity); }
}
public static int waveNumber = 1;
int waveIndex = 0;
void Start () {
waveNumber = 1;
waveCountdown = 5;
SpawnPoints = GameObject.FindGameObjectsWithTag ("EnemySpawnPoint");
InvokeRepeating ("WaveTracker", 0f, 1f);
}
void WaveTracker () {
if (waveCountdown == 0 && !spawning) {
if (GameObject.FindGameObjectsWithTag ("Enemy").Length == 0) {
enemiesAlive = false;
waveCountdown = timeBetweenWaves;
waveNumber++;
}
}
}
void Update () {
waveCountdown -= Time.deltaTime;
if (waveCountdown == 0 && enemiesAlive == false) {
StartCoroutine ( SpawnWave ( Waves[waveIndex] ) );
return;
}
}
public IEnumerator SpawnWave (WaveAction wave) {
enemiesAlive = true;
spawning = true;
yield return new WaitForSeconds (2f);
for (int i = 0; i < wave.count; i++)
{
int spawnIndex = Random.Range (0, SpawnPoints.Length);
Transform enemy = Instantiate (wave.enemy, SpawnPoints[spawnIndex].transform.position, SpawnPoints[spawnIndex].transform.rotation) as Transform;
yield return new WaitForSeconds (1f/wave.spawnRate);
}
if (waveIndex < Waves.Length - 1) //Calls next wave
{
waveIndex++;
}
else
{
waveIndex = 0;
}
spawning = false;
}
}
What are the errors exactly? Don’t just link codes, copy the error over.
I see your issue. Your coroutine takes a waveaction but you’re passing in a wave. So either your coroutine needs to take the wave or your parameter has to pass in the waveaction list from the wave you are getting.
Thanks for the replies. The errors are; “The best overload match for ‘WaveController.SpawnWave(WaveController.WaveAction)’ has some invalid arguments” and "Argument #1 cannot convert ‘WaveController.Wave’ expression to type ‘WaveController.WaveAction’
How do I pass in the waveaction list? I thought that’s what I had done
Waves [index].actions is a list of waveactions, so it’ll actually be something like Waves [index].actions [actionIndex] that would need to be given as the parameter to the coroutine I think.
Okay I think i’m getting there slowly. This is what I currently have:
if (actionIndex < WaveController.WaveAction.count - 1)
{
actionIndex++;
}
else
{
if (waveIndex < Waves.Length - 1) //Calls next wave
{
waveIndex++;
}
else
{
waveIndex = 0;
}
}
I think that is correct (almost), but I get error CS0120: an object reference is required to access non-static member…
I have tried gameObject.GetComponent<WaveController>().WaveAction.count, and a few other variations but they all throw up similar errors. What is the correct way to reference the list in this class? Thanks in advance[/code]
Might be a stupid tip, but is count the right way to call it. Did you try Count instead? Could you post your current up to date script and tell us, on which line the error gets called.
I just realised this too, so not stupid at all! count is one of my variables so it didn’t even throw an error. But ‘Count’ is not recognised, so I imagine I am missing something up to ‘Using…’. Here’s my script currently:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class WaveController : MonoBehaviour {
[System.Serializable]
public class Wave {
public string name;
public List<WaveAction> actions;
}
[System.Serializable]
public class WaveAction {
public string name;
public Transform enemy;
public int count;
public float spawnRate;
}
public float timeBetweenWaves = 5f;
private GameObject[] SpawnPoints;
public Wave[] Waves; //Creates array
public bool enemiesAlive = false;
public bool spawning = false;
private static float _waveCountdown = 0f;
public static float waveCountdown {
get { return _waveCountdown; }
set { _waveCountdown = Mathf.Clamp (value, 0, Mathf.Infinity); }
}
public static int waveNumber = 1;
int waveIndex = 0;
int actionIndex = 0;
void Start () {
waveNumber = 1;
waveCountdown = 5;
SpawnPoints = GameObject.FindGameObjectsWithTag ("EnemySpawnPoint");
InvokeRepeating ("WaveTracker", 0f, 1f);
}
void WaveTracker () {
if (waveCountdown == 0 && !spawning) {
if (GameObject.FindGameObjectsWithTag ("Enemy").Length == 0) {
enemiesAlive = false;
waveCountdown = timeBetweenWaves;
waveNumber++;
}
}
}
void Update () {
waveCountdown -= Time.deltaTime;
if (waveCountdown == 0 && enemiesAlive == false) {
StartCoroutine ( SpawnWave ( Waves[waveIndex].actions[actionIndex] ) );
return;
}
}
public IEnumerator SpawnWave (WaveAction wave) {
enemiesAlive = true;
spawning = true;
yield return new WaitForSeconds (2f);
for (int i = 0; i < wave.count; i++)
{
int spawnIndex = Random.Range (0, SpawnPoints.Length);
Transform enemy = Instantiate (wave.enemy, SpawnPoints[spawnIndex].transform.position, SpawnPoints[spawnIndex].transform.rotation) as Transform;
yield return new WaitForSeconds (1f/wave.spawnRate);
}
if (actionIndex < WaveController.WaveAction.Count - 1)
{
actionIndex++;
}
else
{
if (waveIndex < Waves.Length - 1) //Calls next wave
{
waveIndex++;
}
else
{
waveIndex = 0;
}
}
spawning = false;
}
}
The only error I get for this is CS0117: 'WaveController.WaveAction does not contain a definition for Count.
Not sure why this is because I thought Lists were a part of System.Collections.Generic?
Same line except a no object reference error instead.
But I have a list made from the wave action class. Is that not the same thing? Maybe the problem is it think I am referencing the class instead. But in that case, how can I reference the list instead?
EDIT: I’ll try WaveController.Wave.WaveAction.Count when I get the chance. Think that may be correct way to reference the list.
So as far as I can see, the actions is the list, so the actions do have Count. Actions is the list of waveactions. So, if you are trying to call the wave in that list, you have to call actions[0] for the first item for example.
Cheers for the reply again. I already set actionIndex = 0 before my methods, and call on that first. Then it should iterate through the list via actionIndex++
And is that because you have to specify you are checking that list within the array rather than just the list itself? Sounds promising, I’ll let you know the results. Cheers
I tried this. I set up 3 waves; Wave 1: 5 x Enemy1, Wave 2: 5x Enemy2, Wave3: 5x Enemy1 + 5xEnemy2.
It goes through waves 1 and 2 with no problem. Then on wave 3 the first 5x Enemy1’s spawn fine, but then it goes to Wave 4 and spawns 5x Enemy2. These should have spawned at the same time, and in the same wave.
After the final wave finishes it doesn’t loop back round anymore either, so I’ve broken it even further it appears. It continues to countdown new waves one after the other whilst generating multiple error code:
ArgumentOutOfRangeException: Argument is out of range.
Parameter name: index
System.Collections.Generic.List`1[WaveController+WaveAction].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633)
WaveController.Update () (at Assets/_MyProject/Scripts/Spawning/WaveController.cs:65)
Honestly, your script seems really complicated for what it’s suppose to do, which I suspect is part of the bugs you are encountering. (and also why debugging it is a bit difficult).
Argument out of range means you’re trying to access an index in your list that doesn’t exist. So if you have 10 items in your list and you want to access item 11 (or index 10), you’ll get that error.
Managed to fix the error. It now loops through everything, with all enemies. But it still counts seperate enemies as a new wave (so as above, Wave3 gets split into 2 seperate waves). New code:
if (actionIndex < Waves [waveIndex].actions.Count - 1) { //Calls next action
actionIndex++;
} else {
actionIndex = 0;
if (waveIndex < Waves.Length - 1) { //Call next wave
waveIndex++;
} else {
waveIndex = 0;
}
}
Hmm, to be honest this was one of the simpler spawners that I have seen, hence why I chose to work with it. I have seen simpler but with limited capability in terms of waves and spawning multiple enemy types. It’s my lack of knowledge of lists and arrays that is causing me the trouble. A lot of what I am doing is trial and error