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…