I’m working on the Unity 2d course and I’m on Laser Defender. I’ve created the coroutine to spawn all of the enemies of a wave. The coroutine that created the enemy and moved it along the waypoints worked correctly.
Once I added the for loop, however, I’m finding issues. The additional enemies of the wave are created and do move along the waypoints, as expected.
However, it appears that the script will fail once the number of enemies spawned reaches the number of points in the path for the wave. As long as the number of enemies does not exceed the number of waypoints in the path. I’ve tested this by creating new waves, new paths, linking and unlinking new and existing paths and waves. I’ve verified variables, indexes, and I can’t find how they’re linked.
Any help would be appreciated, because I’m stumped.
EnemyPathing
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyPathing : MonoBehaviour
{
[SerializeField]
private WaveConfig waveConfig;
private List<Transform> waypoints;
[SerializeField]
private float moveSpeed = 1.0f;
private int waypointIndex = 0;
// Start is called before the first frame update
void Start()
{
waypoints = waveConfig.GetWavePoints();
transform.position = waypoints[waypointIndex].transform.position;
}
// Update is called once per frame
void Update()
{
MoveToWaypoints();
}
private void MoveToWaypoints()
{
if (waypointIndex < waypoints.Count)
{
var targetPosition = waypoints[waypointIndex].transform.position;
var movementThisFrame = moveSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, targetPosition, movementThisFrame);
if (transform.position == targetPosition)
{
waypointIndex++;
}
}
else
{
Destroy(gameObject);
}
}
}
WaveConfig
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(menuName = "Enemy Wave Config")]
public class WaveConfig : ScriptableObject
{
[SerializeField]
private GameObject enemyPrefab;
[SerializeField]
private GameObject pathPrefab;
[SerializeField]
private float timeBetweenSpawns = 0.5f;
[SerializeField]
private float spawnRandomFactor = 0.3f;
[SerializeField]
private int numberOfEnemies;
[SerializeField]
private float moveSpeed = 2f;
public List<Transform> GetWavePoints ()
{
// Pull the waypoints out of the wave path prefab and return them
// so we don't just return the prefab
var waveWayPoints = new List<Transform>();
foreach(Transform child in pathPrefab.transform)
{
waveWayPoints.Add(child);
}
return waveWayPoints;
}
public GameObject GetEnemyPrefab() { return enemyPrefab; }
public float GetTimeBetweenSpawns () { return timeBetweenSpawns; }
public float GetSpawnRandomFactor () { return spawnRandomFactor; }
public int GetNumberOfEnemies () { return numberOfEnemies; }
public float GetMoveSpeed () { return moveSpeed; }
}
EnemySpawner
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
[SerializeField]
private List<WaveConfig> waveConfigs;
private int startingWave = 0;
// Start is called before the first frame update
void Start()
{
var currentWave = waveConfigs[startingWave];
StartCoroutine(SpawnAllEnemiesInWave(currentWave));
}
private IEnumerator SpawnAllEnemiesInWave(WaveConfig waveConfig)
{
var enemyCount = waveConfig.GetNumberOfEnemies();
Debug.Log($"Number of Enemies: {enemyCount}");
for (int enemyIndex = 0; enemyIndex <= enemyCount - 1; enemyIndex++)
{
Debug.Log($"Enemy# {enemyIndex}");
Instantiate(
waveConfig.GetEnemyPrefab(),
waveConfig.GetWavePoints()[enemyIndex].transform.position,
Quaternion.identity
);
yield return new WaitForSeconds(waveConfig.GetTimeBetweenSpawns());
}
}
}
Thank you in advance for any help.