- Home /
self mistake
How to spawn only one GameObject from a list of game objects? Please help.
I writing a game where I need to create only two game objects at y location of say 3.0f and 4.0f at a time, and when both of them has been deactivated, I create another two at -3.0f and -4.0f.
The problem is whenever I call Spawn() once, they will create more than one game object, usually double the number I am creating. The location of the 'extra' game object is usually at the prefab's transform position (0, 0, 0), but not all the time. Here is the game object manager codes:
 using UnityEngine;
 using System.Collections.Generic;
 using System;
 using System.Linq;
 namespace GameScripts.BalloonBalance {
     public class starsManager_Bimanual : MonoBehaviour {
 
 
         // Define if the stars need to be drawn or not (i.e. when the level is launched)
         public static bool shouldDraw = false;
     
         // Star pool
         public List<GameObject> pool = new List<GameObject>();
 
         // Bonus star pool
         public List<GameObject> poolBonus = new List<GameObject>();
 
         // Number of stars in the pools at the beginning
         public int poolSize;
         public int poolBonusSize;
 
         public int currentPoolSize;
         public int currentPoolSizeBonus;
 
         // Total length of the level (world units)
         public static float levelTotalLength;
 
         // To know how many stars have already been created
         public int starCount = 0;
 
         void Awake() {
             shouldDraw = false;
 
             // Create and fill the pool
             pool = new List<GameObject> ();
             for (int i = 0; i < poolSize; i++) {
                 GameObject star = (GameObject)Instantiate (Resources.Load ("Prefabs/StarBimanual"));
                 star.transform.parent = transform;
                 star.GetComponent<StarBimanual>().manager = this;
                 star.SetActive(false);
                 pool.Add(star);
             }
 
             // Create and fill the pool (bonus=
             poolBonus = new List<GameObject> ();
             for (int i = 0; i < poolBonusSize; i++) {
                 GameObject star = (GameObject)Instantiate (Resources.Load ("Prefabs/BigStarBimanual"));
                 star.transform.parent = transform;
                 star.GetComponent<StarBimanual>().manager = this;
                 star.SetActive(false);
                 poolBonus.Add(star);
             }
         }
 
         void drawFirstStars() {
 
             Spawn (new Vector3 (0, 4.0f, 0));
             Spawn (new Vector3 (0, 3.0f, 0));
             shouldDraw = true;
         }
 
 
 
         void FixedUpdate () {
             
             currentPoolSize = pool.Count;
             currentPoolSizeBonus = poolBonus.Count;
 
             if (shouldDraw) {
                 if (starCount >= LevelManager.currentLevel.levelLength) {
                     shouldDraw = false;
                 }
                 ReAddPool ();
             }
             else if (!shouldDraw) {
                 return;
             }
 
             Debug.Log (shouldDraw);
         }
 
 
         GameObject takeStarInPool() {
             GameObject starToTake = pool [0];
             pool.RemoveAt (0);
             starToTake.SetActive (true);
             return starToTake;
         }
 
         GameObject takeStarInBonusPool() {
             GameObject starToTake = poolBonus [0];
             poolBonus.RemoveAt (0);
             starToTake.SetActive (true);
             return starToTake;
         }
 
         void Spawn (Vector3 position) {
             // Put normal star or bonus star depending on the bonus score
             if (scoreBalloon.bonus > 0) { // Big star if bonus
                 takeStarInBonusPool ();
                 takeStarInBonusPool ().transform.position = position;
                 scoreBalloon.bonus--; // Remove the bonus
             } else {
                 takeStarInPool ();
                 takeStarInPool ().transform.position = position;
             }
             starCount++;
 
         }
 
         public void Despawn (GameObject gameObject) {
 
             gameObject.SetActive(false);
 
             if (gameObject.GetComponent<StarBimanual> ().point == 1) {
                 pool.Add (gameObject);
             } else if
                 (gameObject.GetComponent<StarBimanual> ().point == 3) {
                 poolBonus.Add (gameObject);
             }
 
         }
 
         void ReAddPool(){
             if (currentPoolSize == 10) {
                 if (starCount == 2 || starCount ==6 || starCount ==10 || starCount ==14 || starCount ==18 || starCount ==22 || starCount ==26) {
                     Spawn (new Vector3 (0, -3.0f, 0));
                     Spawn (new Vector3 (0, -4.0f, 0));
                 }
 
                 if (starCount == 4 || starCount ==8|| starCount ==12||starCount == 16|| starCount ==20||starCount == 24|| starCount ==28) {
                     Spawn (new Vector3 (0, 3.0f, 0));
                     Spawn (new Vector3 (0, 4.0f, 0));
                 }
             }
             
         }
             
         void OnEnable() {
             LevelManager.EnableLevel += drawFirstStars;
             LevelManager.QuitLevel += stopDrawing;
         }
 
         void OnDisable() {
             LevelManager.QuitLevel -= stopDrawing;
             LevelManager.EnableLevel -= drawFirstStars;
         }
 
         void stopDrawing () {
             shouldDraw = false;
         }
 
         public bool stopDrawing2 () {
             shouldDraw = false;
             return shouldDraw;
         }
 
 
     }
 }
and here is the code for the game object prefab:
 using UnityEngine;
 
 namespace GameScripts.BalloonBalance {
     public class StarBimanual : MonoBehaviour {
 
         // Reference to the star manager (pooling)
         [HideInInspector]
         public starsManager_Bimanual manager;
 
         // Number of points depend on the type of objects collected (to be filled in the inspector)
         public int point;
 
         // Information about the position, to reinitialize the stars
         public Vector2 position;
 
         public AudioClip starSound;
 
         AudioSource source;
 
         void Awake () {
             source = Camera.main.GetComponent<AudioSource>();
         }
 
         // Update is called once per frame
         void Update () {
             DestroyUncollected ();
         }
 
         // Destroy collected stars
         void OnTriggerEnter2D (Collider2D other)
 
             {
                 if (other.gameObject.GetComponent<singleCharacter>() || other.gameObject.GetComponent<Character>()|| other.gameObject.GetComponent<Character_Bimanual>()) {
                 scoreBalloon.score += point;
                 source.PlayOneShot(starSound);
                 manager.Despawn(gameObject);
             }
         }
 
         // Destroy uncollected star if out of the FOV
         void DestroyUncollected () {
             if (transform.position.x < Camera.main.transform.position.x - 4.0f) {
                 manager.Despawn(gameObject);
             }
         }
 
         void OnEnable()    {
             LevelManager.QuitLevel += cleanStar;
         }
 
         void OnDisable() {
             LevelManager.QuitLevel -= cleanStar;
         }
 
         // If a level is closed, all stars are put back in the pool
         void cleanStar() {
             manager.Despawn(gameObject);
         }
     }
 }
Answer by Batka · Nov 15, 2016 at 11:14 AM
You call takeStarInBonusPool() more than once in Spawn.
Because it returns a GameObject, you call it twice just to refer to the star:
 void Spawn (Vector3 position) {
               // Put normal star or bonus star depending on the bonus score
               if (scoreBalloon.bonus > 0) { // Big star if bonus
                   takeStarInBonusPool (); //  <----- First Call
                   takeStarInBonusPool ().transform.position = position; <------- Second Call
The thing is, when you call it twice, it removes 2 stars from the pool, and SetsActive 2 stars as well:
   GameObject takeStarInBonusPool() {
              GameObject starToTake = poolBonus [0];
              poolBonus.RemoveAt (0);
              starToTake.SetActive (true);
              return starToTake;
          }
I'd suggest making this in two methods:
- one as 'Getter', that will return the star as GameObject 
- the other as 'Setter', where the logic happens (poolBonus.RemoveAt(0) and starToTake.SetActive(true) - I hope this leads you somewhere 
Tried that, not working. And finally what causing it is this line here:
  void ReAddPool(){
      if (currentPoolSize == 10) {
          if (starCount == 2 || starCount ==6 || starCount ==10 || starCount ==14 || starCount ==18 || starCount ==22 || starCount ==26) {
              Spawn (new Vector3 (0, -3.0f, 0));
              Spawn (new Vector3 (0, -4.0f, 0));
          }
 
          if (starCount == 4 || starCount ==8|| starCount ==12||starCount == 16|| starCount ==20||starCount == 24|| starCount ==28) {
              Spawn (new Vector3 (0, 3.0f, 0));
              Spawn (new Vector3 (0, 4.0f, 0));
          }
      }
      
  }
the second if statement (starCount 4 8) need to be else if! $$anonymous$$an that was unexpected.
Follow this Question
Related Questions
Checking if a position is occupied in 2D? 1 Answer
shrinking objects 1 Answer
How to assign a gameobject to a script that is added dynamically 1 Answer
Spawning GameObject contained within another 1 Answer
Spawn items around GameObject 3 Answers
 koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                