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; }
}