Search Unity

Can I Change Variable Values Within an Invoke Command?

Discussion in 'Scripting' started by AdamCNorton, Jul 25, 2014.

  1. AdamCNorton

    AdamCNorton

    Joined:
    Apr 16, 2013
    Posts:
    57
    So I'm spawning clouds. I want them to spawn at a much slower speed when my character is standing still, and then spawn faster when he's running, to keep the sky from filling with clouds when you're standing still. My code for spawning actually works just fine. The problem is I'm not able to change spawnMax and spawnMin while the level is running. Actually, debug shows me the values are changing, but the Invoke command seems to ignore them. It won't even let me change the value in the Inspector as the level is running. Is there a better way to do this?

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class CloudSpawn : MonoBehaviour
    5. {
    6.     public GameObject player;
    7.  
    8.     public GameObject[] cloud;
    9.     public float spawnMin = 25f;
    10.     public float spawnMax = 35f;
    11.  
    12.     // Use this for initialization
    13.     void Start ()
    14.     {
    15.         SpawnCloud();
    16.         player = GameObject.FindGameObjectWithTag("Player");
    17.     }
    18.    
    19.     // Update is called once per frame
    20.     void Update ()
    21.     {
    22.         if(player.rigidbody2D.velocity.x > 0)
    23.         {
    24.             spawnMin = 1f;
    25.             spawnMax = 3f;
    26.             Debug.Log("SpawnMin: " + spawnMin + "  " + "SpawnMax: " + spawnMax);
    27.         }
    28.         else
    29.         {
    30.             spawnMin = 25f;
    31.             spawnMax = 35f;
    32.             Debug.Log("SpawnMin: " + spawnMin + "  " + "SpawnMax: " + spawnMax);
    33.         }
    34.     }
    35.  
    36.     void SpawnCloud()
    37.     {
    38.         Instantiate(cloud[Random.Range(0, cloud.GetLength(0))], transform.position, Quaternion.identity);
    39.         Invoke("SpawnCloud", Random.Range(spawnMin, spawnMax));
    40.     }
    41. }
     
  2. Patico

    Patico

    Joined:
    May 21, 2013
    Posts:
    886
    I don't like Invoke() there :-/
    You can rewrite your SpawnCloud() as coroutine and replace Invoke method with yeild new WaitForSeconds().
     
  3. Patico

    Patico

    Joined:
    May 21, 2013
    Posts:
    886
    Here is an example:
    Code (csharp):
    1.  
    2.   // Use this for initialization
    3.   void Start ()
    4.   {
    5.   StartCoroutine(SpawnCloud());
    6.   player = GameObject.FindGameObjectWithTag("Player");
    7.   }
    8. ...
    9.    Enumerator SpawnCloud()
    10.   {
    11.      while(true)
    12.      {
    13.        Instantiate(cloud[Random.Range(0, cloud.GetLength(0))], transform.position, Quaternion.identity);
    14.        yield retun new WaitForSeconds(Random.Range(spawnMin, spawnMax));
    15.      }
    16.   }
    17.  
     
  4. AdamCNorton

    AdamCNorton

    Joined:
    Apr 16, 2013
    Posts:
    57
    Ah, that works, and I like that better too. Thanks!