Search Unity

(noob query) Instantiate a number of prefab objects over time and on destruction

Discussion in '2D' started by N1ghtrunner, Nov 20, 2018.

  1. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    Hi all,

    I am having a challenging time trying to get a Balloon Spawner to work properly! I'm new to this. What I am trying to do is:

    1. In a scene, spawn balloons at various/random points along the x axis (i think we're ok here)
    2. I'd like to spawn up to, say, 30 maximum, every 2 seconds apart
    3. I'd like to check the active number of these objects in the scene (i.e. the non-destroyed) and if its less than the maximum, spawn more balloons. - This is the bit I'm struggling with! I've tried various things (if / for loops) in update to no avail, and ultimately ended up freezing Unity on pressing the play button. Below is the code. I would appreciate any help - I've been searching for hours and can't quite seem to get this right:

    Code (CSharp):
    1. public class SpawnBalloon : MonoBehaviour {
    2.  
    3.     public GameObject TestBalloon;
    4.     private float timetospawn = 2f;
    5.     public int MaxBalloons;
    6.  
    7.  
    8.  
    9.     void Start ()
    10.     {
    11.         SpawnNow();
    12.     }
    13.  
    14.     public void SpawnNow ()
    15.     {    
    16.         Vector2 spawnPoint = new Vector2(Random.Range(-8f, 8f), -5.7f);
    17.         GameObject balloon = Instantiate(TestBalloon, spawnPoint, Quaternion.identity);
    18.  
    19.     }
    20.  
    21.     private void Update()
    22.     {
    23.  
    24.     }
    25.  
    26. }
    I have a seperate script on the Balloon prefab which has code to Destroy object etc. I am thinking to use this script to trigger a new instance on destruction but would prefer the Update on my spawner script to handle it if I can.
     
  2. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    try this
    Code (CSharp):
    1. public class SpawnBalloon : MonoBehaviour
    2. {
    3.  
    4.     public GameObject TestBalloon;
    5.     private float timetospawn = 2f;
    6.     public int MaxBalloons;
    7.     bool canSpawn = true;
    8.     //you can decrease this int when the balloon was destroyed
    9.     public int currentBalloon;
    10.  
    11.     void Update ()
    12.     {
    13.         if (canSpawn && currentBalloon <= MaxBalloons)
    14.         {
    15.             StartCoroutine(SpawnNow());
    16.         }
    17.     }
    18.  
    19.     IEnumerator SpawnNow()
    20.     {
    21.         canSpawn = false;
    22.         currentBalloon++;
    23.         Vector2 spawnPoint = new Vector2(Random.Range(-8f, 8f), -5.7f);
    24.         GameObject balloon = Instantiate(TestBalloon, spawnPoint, Quaternion.identity);
    25.         yield return new WaitForSeconds(timetospawn);
    26.         canSpawn = true;
    27.     }
    28. }
     
  3. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    Thanks for this. Next challenge: how to update the CurrentBalloons value once an instantiated object is destroyed? The script I have on my Balloon prefab is as follows (very simple):
    Code (CSharp):
    1. public class Poptracker : MonoBehaviour {
    2.  
    3.  
    4.    
    5.     void Start ()
    6.     {
    7.      
    8.     }
    9.    
    10.    
    11.     void Update () {
    12.    
    13.          
    14.     }
    15.  
    16.     private void OnMouseDown()
    17.     {
    18.         Destroy(gameObject);
    19.                          
    20.     }
    21. }
     
  4. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    Code (CSharp):
    1. public class SpawnBalloon : MonoBehaviour
    2. {
    3.  
    4.     public GameObject TestBalloon;
    5.     private float timetospawn = 2f;
    6.     public int MaxBalloons;
    7.     bool canSpawn = true;
    8.     //you can decrease this int when the balloon was destroyed
    9.     public int currentBalloon;
    10.  
    11.     void Update ()
    12.     {
    13.         if (canSpawn && currentBalloon <= MaxBalloons)
    14.         {
    15.             StartCoroutine(SpawnNow());
    16.         }
    17.     }
    18.  
    19.     IEnumerator SpawnNow()
    20.     {
    21.         canSpawn = false;
    22.         currentBalloon++;
    23.         Vector2 spawnPoint = new Vector2(Random.Range(-8f, 8f), -5.7f);
    24.         GameObject balloon = Instantiate(TestBalloon, spawnPoint, Quaternion.identity);
    25.         balloon.GetComponent<Poptracker>().spawner = gameObject;
    26.         yield return new WaitForSeconds(timetospawn);
    27.         canSpawn = true;
    28.     }
    29. }
    Code (CSharp):
    1. public class Poptracker : MonoBehaviour {
    2.  
    3.     public GameObject spawner;
    4.  
    5.     private void OnMouseDown()
    6.     {
    7.         spawner.GetComponent<SpawnBalloon>().currentBalloon--;
    8.         Destroy(gameObject);
    9.     }
    10. }
    or set tag to Spawner and
    GameObject.FindWithTag("Spawner").GetComponent<SpawnBalloon>().currentBalloon--;
     
  5. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    Thanks so much for your assistance. Your approach is really elegant. unfortunately there is another hurdle:

    UnassignedReferenceException: The variable spawner of Poptracker has not been assigned.
    You probably need to assign the spawner variable of the Poptracker script in the inspector.

    I try to drag my BalloonSpawner from the Hierarchy but it wont let me (this is where the SpawnBalloon script is). It only allows me to drag the TestBalloon prefab there, which...doesnt work..
     
  6. N1ghtrunner

    N1ghtrunner

    Joined:
    Jan 5, 2015
    Posts:
    104
    Solved. Thank you SO MUCH! I've learnt a tremendous amount from this interaction :D
    Code (CSharp):
    1. public class Poptracker : MonoBehaviour {
    2.  
    3.     public GameObject spawner;
    4.  
    5.     void Start ()
    6.     {
    7.      
    8.     }
    9.    
    10.    
    11.     void Update () {
    12.    
    13.          
    14.     }
    15.  
    16.     private void OnMouseDown()
    17.     {
    18.        
    19.         spawner = GameObject.Find("BalloonSpawner");
    20.         spawner.GetComponent<SpawnBalloon>().currentBalloon--;
    21.         Destroy(gameObject);
    22.         //spawner.GetComponent<SpawnBalloon>().currentBalloon--;
    23.  
    24.     }
    25. }
     
  7. vakabaka

    vakabaka

    Joined:
    Jul 21, 2014
    Posts:
    1,153
    maybe you have forgot to add 25 line in the SpawnBalloon:
    balloon.GetComponent<Poptracker>().spawner = gameObject;
    or I have did something wrong and the line should be,
    balloon.GetComponent<Poptracker>().spawner = this.gameObject;

    also your solution with .Find is good too, only it can take bit more time for search the object in the scene.

    if (canSpawn && currentBalloon <= MaxBalloons) this should be
    if (canSpawn && currentBalloon < MaxBalloons) or there is one balloon to much