Yeah, I’ve got something set up like that.
It’s a big mess though.
Basic concept is-
Have two int variables (CountPerWave,UnitsToSpawn), an interface with a function called ‘Unit Died’ that takes an actor parameter, an actor array, and a class to spawn (your AI). Inside your wave manager, set UnitsToSpawn to the value of CountPerWave. Do not use a for loop. Now, check if UnitsToSpawn is greater than or equal to 1, and then spawn your unit. Next, add the spawned unit to the array of actors (can also be your unit type). Add a delay node, and then decrement (subtract 1 and set) UnitsToSpawn. Connect this to the earlier check (the wire will be going back to the left) if UnitsToSpawn is greater than or equal to one. This is your spawning logic, and you can adjust the spawn rate by changing the delay.
Next, have your spawner implement your interface, and add ‘Event Unit Died’. Check if the array contains the unit, and if it does, remove the unit. Check if the array length is equal to zero, if it is you can load the next wave. Now, in the unit actor (the AI) you want to have a variable for the spawner. Make this variable editable and exposed on spawn. Back in the spawner, get a self node and pass that to the spawned unit. Finally, when the unit dies, call ‘Unit Died (Interface Call/Message)’ on the variable you set for the spawner.
In effect, the spawner keeps track of which enemies it spawned, and the enemies tell the spawner when they died. Since all enemies tell the spawner when they died, you only need to check the array when an enemy dies.
I scaled this up so a single actor can manage any number of configured spawners that have any number of configured waves (and then continues infinitely with the settings from the last configured wave). That’s why this is a big mess in my project.