Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Null Reference Exception & Queues

Discussion in 'Scripting' started by AlphaDraconis_SJ-ATX, Mar 19, 2015.

  1. AlphaDraconis_SJ-ATX

    AlphaDraconis_SJ-ATX

    Joined:
    Oct 25, 2014
    Posts:
    5
    Hello,

    I am having a few issues with my code. The game I have been writing for months does not seem to run well when implementing a game level manager to control 'game over' and 'start' game states. The essence of the game is to make a cube jump from platform to platform; nothing really new here. I used Queues to generate the prefab and one of the main issues I'm having is that when I'm able to run level 1, and the cube falls and triggers a game over; I've chosen that for this game the 'game over' call segues into the 'level select screen' composed of a grid like selection of locked and unlocked levels (I used MadLevelManager for this).

    The GameManager prompts the user to initiate the game by pressing the screen.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using System.Collections;
    4. using MadLevelManager;
    5.  
    6. public class GameManager : MonoBehaviour {
    7.  
    8.  
    9.  
    10.  
    11.     private static GameManager instance;
    12.  
    13.  
    14.     public Text scoreText;
    15.  
    16.  
    17.  
    18.  
    19.  
    20.     public GUIText     oneUpText,
    21.                     distanceText,
    22.                     gameOverText,
    23.                     instructionsText,
    24.                     TokenText,
    25.                     FuelText;
    26.  
    27.    
    28.  
    29.     void Start () {
    30.  
    31.  
    32.         GameEventManager.GameStart += GameStart;
    33.         GameEventManager.GameOver += GameOver;
    34.         gameOverText.enabled = false;
    35.      
    36.  
    37.  
    38.     }
    39.  
    40.     void Update () {
    41.  
    42.  
    43.         //First thing called.
    44.         if (Input.GetButtonDown("Fire1")) {
    45.  
    46.             GameEventManager.TriggerGameStart();
    47.         }
    48.  
    49.     }
    50.  
    51.  
    52.  
    53.     private void GameStart () {
    54.  
    55.  
    56.         instance = this;
    57.  
    58.  
    59.         gameOverText.enabled = false;
    60.  
    61.  
    62.         instructionsText.enabled = false;
    63.  
    64.      
    65.         enabled = false;
    66.     }
    67.  
    68.     private void GameOver () {
    69.  
    70.         gameOverText.enabled = true;
    71.  
    72.  
    73.         instructionsText.enabled = true;
    74.         enabled = true;
    75.     }
    76.    
    There is a Platform generator, again nothing new to see here, just your run of the mill prefab generator/spawner.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections.Generic;
    3.  
    4. public class SkylineManager : MonoBehaviour {
    5.  
    6.  
    7.  
    8.  
    9.  
    10.     public PlatformGenerator platformManager= null;
    11.  
    12.  
    13.     public Vector3 nextPosition;
    14.  
    15.  
    16.     //the transform.
    17.     public Transform prefab;
    18.  
    19.     public int numberOfObjects;
    20.     public float recycleOffset;
    21.     public Vector3 startPosition;
    22.     public Vector3 minSize, maxSize;
    23.  
    24.  
    25.     private Queue<Transform> objectQueue;
    26.  
    27.  
    28.     //Awake is always called before any start function.
    29.     void Awake() {
    30.  
    31.         //Check if instance already exists
    32.         if(platformManager== null)
    33.  
    34.             //if not, set instance to this
    35.             platformManager = this;
    36.  
    37.         //If instance already exists and it's not this:
    38.         else if (platformManager != this)
    39.  
    40.             //Then destroy this. This enforces our singleton.
    41.             Destroy (gameObject);
    42.  
    43.         DontDestroyOnLoad(gameObject);
    44.  
    45.  
    46.  
    47.  
    48.  
    49.     }
    50.  
    51.  
    52.  
    53.     void Start () {
    54.  
    55.  
    56.  
    57.         GameEventManager.GameStart += GameStart;
    58.         GameEventManager.GameOver += GameOver;
    59.  
    60.  
    61.         objectQueue = new Queue<Transform>(numberOfObjects);
    62.  
    63.  
    64.  
    65.             for  (int i = 0; i < numberOfObjects; i++)
    66.  
    67.         {      
    68.                   objectQueue.Enqueue ((Transform)Instantiate (prefab, new Vector3(0f,0f,-100f), Quaternion.identity));
    69.         }
    70.  
    71.  
    72.     enabled = false;
    73.     }
    74.  
    75.     private void GameStart () {
    76.         nextPosition = startPosition;
    77.         for(int i = 0; i < numberOfObjects; i++){
    78.             Recycle();
    79.         }
    80.  
    81.  
    82.         enabled = true;
    83.     }
    84.  
    85.     private void GameOver () {
    86.  
    87.      
    88.         enabled = false;
    89.     }
    90.  
    91.     void Update () {
    92.  
    93.         if (objectQueue.Peek().localPosition.x + recycleOffset < Cube.distanceTraveled) {
    94.             Recycle();
    95.         }
    96.     }
    97.  
    98.  
    99.     private void Recycle () {
    100.  
    101.  
    102.  
    103.  
    104.  
    105.  
    106.         //scaling factor
    107.         Vector3 scale = new Vector3(
    108.             Random.Range(minSize.x, maxSize.x),
    109.             Random.Range(minSize.y, maxSize.y),
    110.             Random.Range(minSize.z, maxSize.z));
    111.  
    112.  
    113.  
    114.         Vector3 position = nextPosition;
    115.         position.x += scale.x * 0.5f;
    116.         position.y += scale.y * 0.5f;
    117.        
    118.  
    119.  
    120.  
    121.         Transform o = objectQueue.Dequeue();
    122.         o.localScale = scale;
    123.         o.localPosition = position;
    124.         nextPosition.x +=  scale.x;
    125.  
    126.         objectQueue.Enqueue(o);
    127.        
    128.  
    129.  
    130.     }
    131.  
    132.  
    133. }
    The script above is shared by two prefab objects that automatically generate themselves with different z values although as you can see, the script above has these variables hard coded.

    The platform generator is slightly different than the code above, except it adds a gap between the objects and is rigid so as to allow the cube to hover. I am getting null reference exceptions from the console specifically dealing with my enable = true and enable = false flags.

    The player reaches game over when colliding with a cube lying underneath the main scene at value y= -40

    the code looks something like this:

    Code (CSharp):
    1. using MadLevelManager;
    2.  
    3. void OnTriggerEnter(Collider collider) {
    4.  
    5.         //If the object colliding with this trigger is     //cube itself. Query for values.
    6.  
    7.         if (collider.gameObject.tag == ("Cube")) {
    8.  
    9.      
    10.             GameEventManager.TriggerGameOver();
    11.             MadLevelProfile.SetCompleted (MadLevel.currentLevelName, false);
    12.          
    13.             MadLevel.LoadLevelByName("Level Select");
    14.      
    15.  
    16.             }
    17.  
    18.  
    19.  
    20.  
    21.     }
    Now the GameEventManager looks like this:

    Code (CSharp):
    1. public static class GameEventManager {
    2.  
    3.     public delegate void GameEvent();
    4.  
    5.  
    6.     //GameEvent Delegates
    7.     public static event GameEvent GameStart, GameOver;
    8.  
    9.     public static void TriggerGameStart(){
    10.         if(GameStart != null){
    11.             GameStart();
    12.         }
    13.     }
    14.  
    15.     public static void TriggerGameOver(){
    16.  
    17.         if(GameOver != null){
    18.             GameOver();
    19.         }
    20.     }
    21. }
    The issue is mainly at 'Game Over', the cube exits the scene and then we're prompted to the 'level select scene' -- Very simple mechanism of going from one level to the next. Because we failed to reach an end-of-scene cube that I left-out for brevity (located at the end of the scene with a similar OnTriggerEnter mechanism querying for the 'tag' of the cube) the player is forwarded to the grid-layout level-select screen which is implemented by MadLevelManager by MadPixelMachine(I believe?)
     
    Last edited: Mar 20, 2015
  2. AlphaDraconis_SJ-ATX

    AlphaDraconis_SJ-ATX

    Joined:
    Oct 25, 2014
    Posts:
    5
    I was considering maybe adding a different state/event called 'Level Select Mode' which means, the player is no longer on this scene; keep certain things here and destroy those i don't need; or something or other....