Null Reference Exception ONLY (sometimes) when loading the scene...

Trying to set up a simple menu, which works. I load my “main scene” with the following script attached to a button:

public class ChangeScene : MonoBehaviour {

	public void ChangeToScene (string sceneToChangeTo)
    {
        SceneManager.LoadScene(sceneToChangeTo);
    }
}

This all works. The issue is, when I use that to load my “Main Scene”, I get a Null Reference Exception error.

NullReferenceException: Object reference not set to an instance of an object
ObjectPooler.GetPooledObject () (at Assets/Scripts/ObjectPooler.cs:33)
WorldGenerator.Update () (at Assets/Scripts/WorldGenerator.cs:51)

This only occurs sometimes. If I play the scene directly from within that scene, it never occurs, but if I load it by clicking on a button it will occur around 70% of the time. As far as I can tell, it doesn’t actually affect anything in the game, and only triggers once at the start, but I’d still like to fix it.

Here is the world generator script:

using System.Collections.Generic;
using UnityEngine;

public class WorldGenerator : MonoBehaviour
{
    public int worldType;

	public Transform generationPoint;
	public float distanceBetween;

    public CreateLevelSO[] levelsSO;
    public GameObject pooler;
    public GameObject poolFolder;
    public GameObject obstacleFolder;

    List<GameObject> objectPools;


    void Start ()
    {
        // List of pools.
        objectPools = new List<GameObject>();

        // Iterate through all prefabs on SO.
        for (int i = 0; i < levelsSO[worldType].Prefabs.Length; i++)
        {
            // Get the game object held on the SO.
            GameObject prefabType = levelsSO[worldType].Prefabs*;*

// Instantiate a pool under the correct folder.
GameObject newPool = Instantiate(pooler, poolFolder.transform);

// Set the properties of the new object and add it to the list.
newPool.GetComponent().prefab = prefabType;
newPool.GetComponent().obstacleFolder = obstacleFolder;
objectPools.Add(newPool);
}
}

void Update ()

  • {*
  •  if (transform.position.z < generationPoint.position.z)* 
    
  •  {*
    
  •  	transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z + distanceBetween);*
    

// Randomly select obstacle.
int type = Random.Range(0, levelsSO[worldType].Prefabs.Length);

// Get pooled object from the correct object pool.
GameObject newObstacle = objectPools[type].GetComponent().GetPooledObject();

// Activate and move recieved object.
newObstacle.transform.position = transform.position;
newObstacle.SetActive(true);

  •  }	*
    
  • }*
    }
    Here is the object pooler script:
    using System.Collections.Generic;
    using UnityEngine;

public class ObjectPooler : MonoBehaviour
{

public GameObject prefab;
public GameObject obstacleFolder;
public int initialPooledAmount;

List pooledObjects;

void Start()
{
// pooledObjects is a list of Game Objects to be pooled.
pooledObjects = new List();

// Instantiate the initial pool.
for (int i = 0; i < initialPooledAmount; i++)
{
GameObject newObject = Instantiate(prefab, obstacleFolder.transform);
newObject.SetActive(false);
pooledObjects.Add(newObject);
}
}

// Function called to return an available pooled object.
public GameObject GetPooledObject()
{

// Iterates through current pooled objects, returning the first deactivated object.
for(int i = 0; i < pooledObjects.Count; i++)
{
if(!pooledObjects*.activeInHierarchy)*
{
return pooledObjects*;*
}
}

// If there are no deactivated objects, expand the pool and return it.
GameObject newObject = Instantiate(prefab, obstacleFolder.transform);
newObject.SetActive(false);
pooledObjects.Add(newObject);
return newObject;

}
}
Any help is appreciated, this is incredibly confusing for me…

My best guess, looking at the code, is that your WorldGenerator.Update()'s first call happens before all of the ObjectPooler.Start() functions have been called.

Honestly, I would remove the Start() function from ObjectPooler entirely and add this to the beginning of the GetPooledObject() function:

if(pooledObjects == null)
    pooledObjects = new List<GameObject>();