Pooling a (GameObject?) Particle System

Hi guys,

I am stumped, I am trying to create a pooling system for an explosion that is a prefab (which I think means then it is a GameObject?) but what is on that GameObject is a partical of said explosion.

I am using a modified version of a pooling system I already have working fine for creating enemy objects (prefabs). The problem occurs when (I think) Unity goes to return the object/explosion to the pool. The explosion happens, I have it time 5 seconds and after that send it back to its pool.

I get a ‘nullreferenceexception object reference not set to an instance of an object’ from unity, which from doing research is about something is happening is null? (I assume it means the pool is null?) Unity directs me to my 3rd script below and is aimed at this section;

private void Update()
   {
       lifeTime += Time.deltaTime;
       if (lifeTime > maxLifetime)
       {
           pool.ReturnToPool(this.gameObject); // null exception here
       }
   }

Should I be using a particle system instead of a gameobject through my code? I’m confused why it works for the rest of my setup but not this.

Below is my code if that helps.

Location control of where explosions happen:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExplosionEnemySpawnerGameObjectPooled : MonoBehaviour
{
   [Header("Pool")]
   [SerializeField]
   private ExplosionEnemyObjectPool explosionPool; // change this
     



   private void OnTriggerEnter(Collider other)
   {
       if (other.tag == "Shot" || other.tag == "Player" || other.tag == "Asteroid" || other.tag == "Enemies" || other.tag == "HunterEnemies")
       {
           var ExplosionsEnemy = explosionPool.Get();
           ExplosionsEnemy.transform.rotation = transform.rotation;
           ExplosionsEnemy.transform.position = transform.position;
           ExplosionsEnemy.gameObject.SetActive(true);
       }     
   }
}

My pooling queue system:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExplosionEnemyObjectPool : MonoBehaviour
{ 
   public GameObject explosionPrefabs;

   public static ExplosionEnemyObjectPool Instance { get; private set; }
   private Queue<GameObject> objects = new Queue<GameObject>();

 
   private void Awake()
   {
       Instance = this;
   }

   public GameObject Get()
   {
       if (objects.Count == 0)
           AddOjbects(1);
       return objects.Dequeue();
   }

   public void ReturnToPool(GameObject objectToReturn)
   {
       objectToReturn.SetActive(false);
       objects.Enqueue(objectToReturn);
   }

   private void AddOjbects(int count)
   {
       var newObject = GameObject.Instantiate(explosionPrefabs);
       newObject.SetActive(false);
       objects.Enqueue(newObject);

       #region GetComponentPooled
       newObject.GetComponent<IExplosionEnemyPooled>().Pool = this;
       #endregion
   }

}

my timer/re-queuer to send the object back to the pooler

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExplosionEnemyGameObjectPooled : MonoBehaviour, IExplosionEnemyPooled
{   
   private float lifeTime;
   private float maxLifetime = 5f;
   private ExplosionEnemyObjectPool pool; // change this


   public ExplosionEnemyObjectPool Pool // this is a method, not variable, dont be confused. Not sure why not void? cos we return something?
   {
       get { return pool; }
       set
       {
           if (pool == null)
               pool = value;
           else
               throw new System.Exception("Bad pool use, this should only get set once!");
       }
   }
 
   private void OnEnable()
   {
       lifeTime = 0f;
   }

 
   private void Update()
   {
       lifeTime += Time.deltaTime;
       if (lifeTime > maxLifetime)
       {
           pool.ReturnToPool(this.gameObject);
       }
   }
}

my interface:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IExplosionEnemyPooled
{
   ExplosionEnemyObjectPool Pool { get; set; }  
}

You’ll always be pooling game objects. If you’re using a particle system, that’s just a component added to a game object and you can’t pool components by themselves. Your problem seems to be elsewhere.

When you get a null reference exception, it’s sometimes hard to tell what exactly is null. Don’t just assume, put a Debug.Log statement above the line and print out the variables to verify what exactly is null. Then try to follow back the variable to figure out why it ends up being null (likely it either never gets assigned or is assigned null, then follow where that null is coming from).

Looking at the code, nothing immediately jumps out. Maybe you have multiple IExplosionEnemyPooled scripts on your prefab and only one gets the pool set? Or you have an instance in your scene that wasn’t loaded from the pool and therefore the pool was never assigned?

Okay thanks man. Still haven’t found the problem, time to de-bug!