In this video (objectives)...
- Instantiate attackers at intervals within a random range.
- Use a coroutine to continue spawning attackers.
- Create a spawning bool that allows us to stop the attacker spawning when needed.
After watching (learning outcomes)...
Spawn attackers along their lanes using coroutine.
(Unique Video Reference: 12_GL_CUD)
We would love to know…
- What you found good about this lecture?
- What we could do better?
Remember that you can reply to this topic, or create a new topic. The easiest way to create a new topic is to follow the link in Resources. That way the topic will…
- Be in the correct forum (for the course).
- Be in the right sub-forum (for the section)
- Have the correct lecture tag.
Enjoy your stay in our thriving community!
Hi!
I think it could be great to explain difference between using a coroutine in a void Start() and using an IEnumerator Start(), because it can be a bit confusing what are advantages of using one over the other.
-Aurelien
So when you said we had a meaty challenge to complete this lecture, I definitely built my spawner to interact with a scriptable object
[CreateAssetMenu(menuName = "Enemy Wave Config")]
public class WaveConfig : ScriptableObject
{
[SerializeField] GameObject enemyPrefab;
[SerializeField] int numberOfEnemies = 1;
[SerializeField] float minSpawnTime = 1f;
[SerializeField] float maxSpawnTime = 5f;
public GameObject GetEnemyPrefab() { return enemyPrefab; }
public int GetNumberOfEnemies() { return numberOfEnemies; }
public float GetMinSpawnTime() { return minSpawnTime; }
public float GetMaxSpawnTime() { return maxSpawnTime; }
}
public class AttackerSpawner : MonoBehaviour
{
[SerializeField] List<WaveConfig> waveConfig;
[SerializeField] int startingWave = 0;
[SerializeField] bool looping = true;
// Use this for initialization
IEnumerator Start ()
{
do
{
yield return StartCoroutine(SpawnAllWaves());
}
while (looping);
}
private IEnumerator SpawnAllWaves()
{
for (int waveIndex = startingWave; waveIndex < waveConfig.Count; waveIndex++)
{
var currentWave = waveConfig[waveIndex];
yield return StartCoroutine(SpawnEnemiesInWave(currentWave));
}
}
private IEnumerator SpawnEnemiesInWave(WaveConfig waveConfigs)
{
for (int enemyCount = 0; enemyCount < waveConfigs.GetNumberOfEnemies(); enemyCount++)
{
var newEnemy = Instantiate(waveConfigs.GetEnemyPrefab(), this.transform.position, Quaternion.identity);
yield return new WaitForSeconds(Random.Range(waveConfigs.GetMinSpawnTime(), waveConfigs.GetMaxSpawnTime()));
}
}
// Update is called once per frame
void Update ()
{
}
}
This approach shouldn’t be a problem in future lectures correct? I like to try and branch a little bit from coding portions of the lecture as much as I comfortably can to better understand C#
Hi all,
Like Vincent, I too took on the coding challenge with my own take. Instead of creating multiple Spawner game objects, I defined co-ordinates corresponding to each row in my script.
public class AttackerSpawner : MonoBehaviour
{
bool spawn = true;
[SerializeField] GameObject lizardPrefab;
[SerializeField] float minSpawnDelay = 1f;
[SerializeField] float maxSpawnDelay = 5f;
//row co-ords
Vector2 row1 = new Vector2(10f, 5.35f);
Vector2 row2 = new Vector2(10f, 4.35f);
Vector2 row3 = new Vector2(10f, 3.35f);
Vector2 row4 = new Vector2(10f, 2.35f);
Vector2 row5 = new Vector2(10f, 1.35f);
List<Vector2> rowsList = new List<Vector2>();
// Start is called before the first frame update
void Start()
{
AddRowsToList();
StartCoroutine(SpawnLizards());
}
private IEnumerator SpawnLizards()
{
while (spawn)
{
yield return new WaitForSecondsRealtime(Random.Range(minSpawnDelay, maxSpawnDelay));
int randomRow = Random.Range(0, 5);
SpawnLizard(rowsList[randomRow]);
}
}
private void SpawnLizard(Vector2 row)
{
Instantiate(lizardPrefab, row, Quaternion.identity);
}
private void AddRowsToList()
{
rowsList.Add(row1);
rowsList.Add(row2);
rowsList.Add(row3);
rowsList.Add(row4);
rowsList.Add(row5);
}
}