So here's the thing. I have a game in which I have a spawner - to spawn obstacles. And I want after every 5th obstacle to increase the speed. Example: 1st, 2nd, 3rd, 4th, 5th obstacles have default speed = 5 and I want 6th, 7th, 8th, 9th, 10th to have an increased speed to speed = 10 and etc. I already have some nested if statements,but I want to inscrease the speed infitely for example to have speed = 1000 for the 100th obstacle. Here's my code:
IEnumerator SpawnObstacles()
{
int i = 0;
do
{
var randomTime = Random.Range(minTime, maxTime);
var randomObstacle = Random.Range(0, obstacles.Length);
yield return new WaitForSeconds(randomTime);
var obstacle = Instantiate(obstacles[randomObstacle], transform.position, Quaternion.identity);
Destroy(obstacle, 10f);
i++;
if(i >= 10)
{
IncreaseSpeed();
if(i >= 20)
{
IncreaseSpeed();
if(i >= 30)
{
IncreaseSpeed();
}
}
}
}
while (true);
}
private void IncreaseSpeed()
{
Obstacle obs = FindObjectOfType<Obstacle>();
obs.speed += 5f;
}
The modulo operator % helps with things like this. It gives the remainder of the division operation, for example:
3%5 is 3
4%5 is 4
5%5 is 0
6%5 is 1
7%5 is 2
8%5 is 3
9%5 is 4
10%5 is 0
So if your x is starting at 0, and you want to increase speed every 5, you just look at whenever the modulo is 4..
x can go as high as you like (well, int.MaxValue) but the modulo will always be 0..4:
//do some stuff
//should we increase speed?
if(x % 5 == 4)
IncreaseSpeed();
Handy tool for making circular arrays too.. someArray[i % someArray.Length] will never go out of bounds, because the result of a modulo is always between 0 and one less than the length
What you could do instead is either :
%. You can take a look for more information here : https://blog.mattclemente.com/2019/07/12/modulus-operator-modulo-operation.htmlA quick introduction to Modulos:
//It essentially shows the rest of a division
5 / 5 == 1
//Since there's no rest there,
5 % 5 == 0
//But in the case of where there is a rest
6 / 5 == 1 (Rest 1)
//Hence
6 % 5 == 1
//Other examples :
7 % 5 == 2
8 % 5 == 3
9 % 5 == 4
10 % 5 == 0 //!! The result is back to zero here as 10/5 == 2 with no Rest
You have a Coroutine in an infinite loop anyway ... why not simply do
IEnumerator SpawnObstacles()
{
do
{
for(var x = 0; x < 5; x++)
{
var randomTime = Random.Range(minTime, maxTime);
var randomObstacle = Random.Range(0, obstacles.Length);
yield return new WaitForSeconds(randomTime);
var obstacle = Instantiate(obstacles[randomObstacle], transform.position, Quaternion.identity);
Destroy(obstacle, 10f);
}
// These lines are automatically reached after every 5 iterations
// no need for any módulo or other magic check
Obstacle obs = FindObjectOfType<Obstacle>();
obs.speed += 5f;
}
while (true);
}
Or since I'm not sure of this entire FindObjectWithTag thingy ... actually it seems to me it is the same object you Instantiate right? So why not simply
IEnumerator SpawnObstacles()
{
var speed = 5;
do
{
for(var x = 0; x < 5; x++)
{
var randomTime = Random.Range(minTime, maxTime);
var randomObstacle = Random.Range(0, obstacles.Length);
yield return new WaitForSeconds(randomTime);
var obstacle = Instantiate(obstacles[randomObstacle], transform.position, Quaternion.identity);
obstacle.GetComponent<Obstacle>().speed = speed;
Destroy(obstacle, 10f);
}
// These lines are automatically reached after every 5 iterations
// no need for any módulo or other magic check
speed += 5f;
}
while (true);
}
Though to me it stays a bit unclear how exactly your speed shall grow. From your description it sounds like you want to add 5 after every group of iterations .. however this would mean you have speed = 100 (20*5) for the 100th object .. not speed = 1000 as you wrote