Using Pool Manager 2 to fire Player's bullets?

Hi,

I am trying to use Pool Manager (link text) to recycle my Player’s bullets as he fires them. My game is a shoot’em up, so there are a number of bullets on screen and they are fired at around 10 per second. The user fires by holding the LMB on the Player, so its full-auto firing, if you will.

The issue I am experiencing is that it appears that some of the bullets are trying to be Despawned (destroyed/recycled) twice (having already been Despawned), and so this causes a freeze accompanied by an error in the console:

SpawnPool Projectiles: Player_bullet_instance has already been despawned. You cannot despawn something more than once!
UnityEngine.Debug:LogError(Object)
SpawnPool:Despawn(Transform) (at Assets/_Plugins/PathologicalGames/PoolManager/SpawnPool.cs:624)
c__Iterator3:MoveNext() (at Assets/_Plugins/PathologicalGames/PoolManager/SpawnPool.cs:667)

I am sure this is the issue as when I remove the Despawn() call, the firing is fine, but of course does not pool any instances.

I was wondering if anyone can spot where I am going wrong and maybe suggest how I may go about resolving this. The code I am using is below.

Many Thanks

    // SPAWN POOL STUFF
    public string poolName;

    public Transform testPrefab;

    private SpawnPool ProjectilesPool;

    public float spawnInterval = 0.1f;

    public int spawnAmount = 50;
    
    private void Start()
    {
       // Set the ProjectilesPool PoolSpawner object to reference the pool name which we set in the Inpector.
        // In this case, the 'Projectiles' pool 
        this.ProjectilesPool = PoolManager.Pools[this.poolName];

        count = this.spawnAmount;
    }
    
    void FixedUpdate()
    {
       if ((Input.GetMouseButton(0))
       { 
           Timer += Time.fixedDeltaTime;
    
           if (Timer >= spawnInterval)
           {
              Timer = 0;

              int count = this.spawnAmount;
    
              StartCoroutine(Spawner());

	          this.StartCoroutine(Despawner());
          }
       }
    }

IEnumerator Spawner()
    {
        Transform inst;

        inst = this.ProjectilesPool.Spawn(this.testPrefab, transform.position, Quaternion.identity);

        count--;

        inst.name = "Player_bullet_instance"; // So we can see it.

        inst.rigidbody.isKinematic = false;

        // We will apply the force by first referring to our variable that represents the newly created object—instance, 
        // then using the AddForce() command to add a force in the direction of the fwd variable—multiplied by the
        // public variable named power that we created earlier. */
        inst.rigidbody.AddForce(transform.forward * bulletPower);

        yield return new WaitForSeconds(2);

       inst.rigidbody.isKinematic = true; // stop!
        
    }

IEnumerator Despawner()
    {
        // create a short reference to the pool
        while (this.ProjectilesPool.Count > 0)
        {
            // Despawn the last instance (like dequeue in a queue because 
            //   Despawn() will also remove the item from the list, so the list
            //   is being changed in place.)
            Transform instance = this.ProjectilesPool[ProjectilesPool.Count - 1];

            this.ProjectilesPool.Despawn(instance, 2);  // Internal count--

            yield return new WaitForSeconds(0);
      }
}

definitely buy and use PM2 as I support the asset store

but here’s a total explanation of everything about pooling, and all the code

if you work through all of that you will know everything there is to know about pools. hope it helps!

pls vote it up if useful, I wanna get 20 votes on an answer! :slight_smile:

Hi,

You should post on our forums when you have an issue: Forums - Support @ Path-o-logical Games. You’ll find a great search feature there as well. This is an issue that comes up a lot.

The cause is usually the async nature of co-routines. It is possible that your despawn code could be getting called twice in one frame. Just add a quick test to make sure the instance is still active. In Unity4 this is now done using instance.gameObject.activeInHierarchy.

By the way, the latest version of PoolManager has a first-in-first-out limit option which can limit instances by despawn the oldest to re-spawn it. This can be great for bullets.

If you don’t mind a shameless plug, TargetPRO is amazing for firing and projectiles and really anything involving detecting things (which is what happens when bullets hit stuff). It has PoolManager integration too.