New Object Pooling Problem

As of right now i have a spawning script that is randomly choosing a prefab from an array of prefabs and randomly picking a transform to spawn into from a set array. This works perfectly, however ive been reading into object pooling because for what im doing (mobile) i need all the optimization i can get. So i have an object pooling script thats meant for multiple prefabs, however im still having trouble in the generation script as far as implementing the object pooling for the objects in my arrays. Here are the scripts.

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

public class Generation : MonoBehaviour {

    // These are the spawn point arrays that are being used as placement for what's being spawned
    public Transform[] terrainPoints;
    public Transform[] obstaclePoints;
    public Transform[] middlePoints;
    // These are the actual list of prefabs that will be spawning
    public GameObject[] terrainSpawn;
    public GameObject[] obstacleSpawn;
    public GameObject[] middleSpawn;
    // These are the time intervals in which the spawnings will occur
    public float terrainTimer = 2;
    public float obstacleTimer = 2;
    public float middleTimer = 2;
    public float newTime = 2;
    // This is the bool that determines whether the game will be pause (this is accessed by another script, not set by this one)
    public bool isPause;
    // This is accessing the level ring of the level, this isn't set in the inspector this is set dynamically
    public GameObject theGround;

    public static Generation S;

    void Awake()
    {
        S = this;
        theGround = GameObject.Find("level ring");
    }
	
	// Update is called once per frame
	void Update () {
        // If isPause is set to false then we proceed to spawn the clones using the custom functions
		if(isPause == false)
        {
            TerrainSpawn();
            ObstacleSpawn();
            MiddleSpawn();
        }
	}
    // This is the function thats being called thats doing the spawning for terrain prefabs
    void TerrainSpawn()
    {
        // This is taking the duration of time and decreasing it by a set frame
        terrainTimer -= Time.deltaTime;
        // If this is below or equal to zero, it spawns a new clone
        if(terrainTimer <= 0)
        {
            // This randomly chooses an indexed prefab and transform and spawns something at those points
            GameObject terrainClone = Instantiate(terrainSpawn[Random.Range(0, terrainSpawn.Length)], terrainPoints[Random.Range(0, terrainPoints.Length)].transform.position, transform.rotation);
            terrainClone.transform.parent = theGround.transform;
            // This resets the duration of time for the next spawn
            terrainTimer = newTime;

            ObjectPoolerScript.instance.GetObjectForType("ice_env1", true);
            ObjectPoolerScript.instance.GetObjectForType("ice_env2", true);
        }
    }
    // This is the function called to spawn the obstacle clones
    void ObstacleSpawn()
    {
        obstacleTimer -= Time.deltaTime;
        if(obstacleTimer <= 0)
        {
            GameObject obstacleClone = Instantiate(obstacleSpawn[Random.Range(0, obstacleSpawn.Length)], obstaclePoints[Random.Range(0, obstaclePoints.Length)].transform.position, transform.rotation);
            obstacleClone.transform.parent = theGround.transform;
            obstacleTimer = newTime;
        }
    }
    // This is the function being called to spawn clones for the middle section prefabs
    void MiddleSpawn()
    {
        middleTimer -= Time.deltaTime;
        if(middleTimer <= 0)
        {
            GameObject middleClone = Instantiate(middleSpawn[Random.Range(0, middleSpawn.Length)], middlePoints[Random.Range(0, middlePoints.Length)].transform.position, transform.rotation);
            middleClone.transform.parent = theGround.transform;
            middleTimer = newTime;
        }
    }
}

Thats the generation script that does the spawning.

here is the object pooler

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


/// <summary>
/// Repository of commonly used prefabs.
/// </summary>
[AddComponentMenu("Gameplay/ObjectPool")]
public class ObjectPoolerScript : MonoBehaviour
{

    public static ObjectPoolerScript instance { get; private set; }

    #region member
    /// <summary>
    /// Member class for a prefab entered into the object pool
    /// </summary>
    [Serializable]
    public class ObjectPoolEntry
    {
        /// <summary>
        /// the object to pre instantiate
        /// </summary>
        [SerializeField]
        public GameObject Prefab;

        /// <summary>
        /// quantity of object to pre-instantiate
        /// </summary>
        [SerializeField]
        public int Count;
    }
    #endregion

    /// <summary>
    /// The object prefabs which the pool can handle
    /// by The amount of objects of each type to buffer.
    /// </summary>
    public ObjectPoolEntry[] Entries;

    /// <summary>
    /// The pooled objects currently available.
    /// Indexed by the index of the objectPrefabs
    /// </summary>
    [HideInInspector]
    public List<GameObject>[] Pool;

    /// <summary>
    /// The container object that we will keep unused pooled objects so we dont clog up the editor with objects.
    /// </summary>
    protected GameObject ContainerObject;

    void OnEnable()
    {
        instance = this;
    }

    // Use this for initialization
    void Start()
    {
        ContainerObject = new GameObject("ObjectPool");

        //Loop through the object prefabs and make a new list for each one.
        //We do this because the pool can only support prefabs set to it in the editor,
        //so we can assume the lists of pooled objects are in the same order as object prefabs in the array
        Pool = new List<GameObject>[Entries.Length];

        for (int i = 0; i < Entries.Length; i++)
        {
            var objectPrefab = Entries*;*

//create the repository
Pool = new List();

//fill it
for (int n = 0; n < objectPrefab.Count; n++)
{

var newObj = Instantiate(objectPrefab.Prefab) as GameObject;

newObj.name = objectPrefab.Prefab.name;

PoolObject(newObj);
}
}
}

///


/// Gets a new object for the name type provided. If no object type exists or if onlypooled is true and there is no objects of that type in the pool
/// then null will be returned.
///

///
/// The object for type.
///
///
/// Object type.
///
///
/// If true, it will only return an object if there is one currently pooled.
///
public GameObject GetObjectForType(string objectType, bool onlyPooled)
{

for (int i = 0; i < Entries.Length; i++)
{
var prefab = Entries*.Prefab;*

if (prefab.name != objectType)
continue;

if (Pool*.Count > 0)*
{

GameObject pooledObject = Pool*[0];*

Pool*.RemoveAt(0);*

pooledObject.transform.parent = null;

pooledObject.SetActiveRecursively(true);

return pooledObject;
}
if (!onlyPooled)
{
GameObject newObj = Instantiate(Entries*.Prefab) as GameObject;*
newObj.name = Entries*.Prefab.name;*
return newObj;
}
}

//If we have gotten here either there was no object of the specified type or non were left in the pool with onlyPooled set to true
return null;
}

///


/// Pools the object specified. Will not be pooled if there is no prefab of that type.
///

///
/// Object to be pooled.
///
public void PoolObject(GameObject obj)
{

for (int i = 0; i < Entries.Length; i++)
{
if (Entries*.Prefab.name != obj.name)*
continue;

obj.SetActiveRecursively(false);

obj.transform.parent = ContainerObject.transform;

Pool*.Add(obj);*

return;
}
}
}

Could someone please point me into the right direction? I’m confused.

Null Reference Exception questions are forbidden at UA. Check out the FAQ.

The reason is they always have the same answer: You’re trying to access a variable that is not populated with data.

Most likely you were trying to indicate this line, but if you don’t format it as code, UA cuts out stuff inside less-than and greater-than symbols:

GetComponent<DestroyClones>().ID = pO.id;

The likely culprit is that the object with this script attached does not also have a DestroyClones script attached. Ergo when you attempt to access its “ID” variable, you encounter a null ref exception.

Are you expecting the DestroyClones script to lie on the instantiated prefabs? In that case, you need to call GetComponent on the instance. Simply call

myObjectWhichHasADestroyClonesScriptAttached.GetComponent<DestroyClones>().ID