The problem is that when you call InvokeRepeating
, the current value of nextSpawnTime
gets copied to the Unity coroutine system. When you change the value of that variable later, the coroutine system doesn't even notice it. Its copy of the value won't be affected. There is no way (I am aware of) to retroactively change the time interval of a repeating invoke. All you can do is deschedule it with CancelInvoke
and reschedule it again with the new value.
However, I would not use InvokeRepeating at all in this case. I would instead replicate the functionality on my own in Update, just like you did it with the logic which decreases nextSpawnTime
in regular intervals.
My solution for this would look something like this:
private float speedFactor = 1.0f; // start with regular speed
public float spawnInterval = 2.0f; // default spawn rate = one every 2 seconds
private float spawnTimeLeft;
void Update()
{
// spawning logic
spawnTimeLeft -= Time.deltaTime * speedFactor; // higher speed factor = faster spawns;
while (spawnTimeLeft < 0.0f) {
spawnTimeLeft += spawnInterval;
Spawn();
}
}
Now you just need to add some logic which manipulates the variable speedFactor
in order to control the spawning speed. For example, a value of 2.0
will cause spawnTimeLeft
to decrease twice as fast from then on and thus cause Spawn() to get called twice as often.
By the way, you might wonder why I use while (spawnTimeLeft < 0.0f)
instead of if (spawnTimeLeft < 0.0f)
. The reason is that your game might get so fast that you occasionally need to spawn two or more enemies in a single update.
However, if you actually like the Unity coroutine system (I don't, but that's just my preference), then you could use a Coroutine instead of InvokeRepeating which uses yield return new WaitForSeconds(nextSpawnTime)
to wait until it's time to spawn another enemy. This will use the current value of nextSpawnTime
at that moment. But remember that it again uses a copy of the variable. If you change it while the coroutine is waiting, the wait time will not be affected.
public void StartNewGame()
{
StartCoroutine(Spawn);
}
private IEnumerator Spawn() {
while(true) {
yield return new WaitForSeconds(nextSpawnTime);
Vector3 enemySpawnPos = spawnPoint.position;
Instantiate(enemy, enemySpawnPos, Quaternion.identity);
}
}