Search code examples
c#unity-game-enginegame-developmentspawn

Spawn rate doesn't change in Unity game


In my Unity game there are gates spawning and going towards to the player. After every gate, game becomes faster so spawn rate should be decreased according to game speed. I tried to decrease the spawn rate for each spawn but it doesn't work.

public void Start()
{
    InvokeRepeating("SpawnPrefab", .5f, spawnRate);
}

public void SpawnPrefab()
{
    int count = 0;

    int index = Random.Range(0, 5);
    int index2 = Random.Range(0, 5);
    int index3 = Random.Range(0, 5);
    int index4 = Random.Range(0, 5);
    int index5 = Random.Range(0, 5);

    int[] indexler = { index, index2, index3, index4, index5 };

    for (int i = 0; i < indexler.Length; i++)
    {
        
        if(indexler[i] == 2 || indexler[i] == 3 || indexler[i] == 4){ 
            count++;
        }

    }
    if(count == 5)
    {
        indexler[Random.Range(0, 5)] = Random.Range(0,2);
        Debug.Log("Count 5 OLDU");
    }

    Vector3 position5 = new Vector3(25f, 5f, zİlk);

    Instantiate(prefabs[indexler[0]],position5 , prefabs[0].transform.rotation);
    
    
    Vector3 position4 = new Vector3(15f, 5f, zİlk);

    Instantiate(prefabs[indexler[1]], position4, prefabs[0].transform.rotation);
    

    Vector3 position3 = new Vector3(5f, 5f, zİlk);

    Instantiate(prefabs[indexler[2]], position3, prefabs[0].transform.rotation);
    

    Vector3 position2 = new Vector3(-5f, 5f, zİlk);

    Instantiate(prefabs[indexler[3]], position2, prefabs[0].transform.rotation);
    

    Vector3 position1 = new Vector3(-15f, 5f, zİlk);

    Instantiate(prefabs[indexler[4]], position1, prefabs[0].transform.rotation);


    spawnRate -= spawnRate * 15 / 100;

}

I checked the spawnrate value by using Debug.Log: it changes but it can't take the new value in Invokerepeating. I think the reason of the problem is because the ınvokerepeating function called in Start function so its values never changes. But I couldn't find any solutions. Is it possible to call ınvokerepeating in update function ?


Solution

  • The main issue here is you using

    InvokeRepeating("SpawnPrefab", .5f, spawnRate);
    

    this is reading once your value of spawnRate the moment you call it. Later changes to spawnRate don't matter whatsoever!

    => In order to rather keep this dynamic simply don't use InvokeRepeating at all but use a simple timer like e.g.

    const float DECREASE_FACTOR = 15f / 100f;
    
    // Starts negative for initial delay
    float timePassed = -0.5f;
    
    private void Update ()
    {
        // track the passed time every frame
        timePassed += Time.deltaTime;
    
        // if it exceeds the spawn delay spawn
        // this also works now if the spawnRate is decreased/increased at any point
        if(timePassed >= spawnRate)
        {
            timePassed -= spawnRate;
            SpawnPrefab();
        }
    } 
    
    private void SpawnPrefab()
    {
        ...   
    
        spawnRate -= spawnRate * DECREASE_FACTOR;
    }