Implementing "DontDestroyObjectOnLoad" preventing blocks from being destroyed?

Hello, folks. I’m pretty new to all of this, but I’m trying my best :slight_smile:

During the lecture at the point where we first input the following:

   private void Awake()
   {
       int gameStatusCount = FindObjectsOfType<GameStatus>().Length;
       if (gameStatusCount > 1)
       {
           Destroy(gameObject);
       }
       else
       {
           DontDestroyOnLoad(gameObject);
       }
   }

…I immediately ran into a bug where instead of seeing the “DontDestroyOnLoad” in the hierarchy I get an error stating _NullReferenceException: Object reference not set to an instance of an object

Block.DestroyBlock () (at Assets/Scripts/Block.cs:25)
Block.OnCollisionEnter2D (UnityEngine.Collision2D collision) (at Assets/Scripts/Block.cs:20)


_

I have gone back through both my Block.cs and my GameStatus.cs and have played with the order of some things but to no avail. Here are the script as they stand:

Block.cs

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

public class Block : MonoBehaviour {

[SerializeField] AudioClip breakSound;

//cached reference
Level level;

private void Start()
{
    level = FindObjectOfType<Level>();
    level.CountBreakableBlocks();
}

private void OnCollisionEnter2D(Collision2D collision)
{
    DestroyBlock();
}

private void DestroyBlock()
{
    FindObjectOfType<GameStatus>().AddToScore();
    AudioSource.PlayClipAtPoint(breakSound, Camera.main.transform.position);
    Destroy(gameObject);
    level.BlockDestroyed();
}

}

GameStatus.cs

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

public class GameStatus : MonoBehaviour {

//config params
[Range(0.1f, 3f)] [SerializeField] float gameSpeed = 1f;
[SerializeField] int pointsPBD = 10; // PBD = Per Block Destroyed
[SerializeField] TextMeshProUGUI scoreText;

// state vars
[SerializeField] int currentScore = 0;

private void Awake()
{
    int gameStatusCount = FindObjectsOfType<GameStatus>().Length;
    if (gameStatusCount > 1)
    {
        Destroy(gameObject);
    }
    else
    {
        DontDestroyOnLoad(gameObject);
    }
}

private void Start()
{
    scoreText.text = currentScore.ToString();
}

// Update is called once per frame
void Update ()
{
    Time.timeScale = gameSpeed;

}

public void AddToScore()
{
    currentScore = currentScore += pointsPBD;
    scoreText.text = currentScore.ToString();
}

}

Ultimately what is happening is that once I fire the ball (raindrop) at the block (umbrella) the error appears, and the block is being tied to the “DontDestroyOnLoad” rather than the GameStatus.

Any guidance would be greatly appreciated.

-Cameron

Hi Cameron, welcome to the community! :slight_smile:

Any chance you could zip up your project and share it with me so I could take a look?

The forum will allow uploads of up to 10MB, if your project files (zipped) are larger than that you would need to use a service such as Google Drive or Dropbox, and then share the URL.

Also, for code, it’s typically better to copy/paste it and then apply the code formatting. Screenshots can be useful for error messages or details from within Unity, but aren’t so useful for code, especially if someone wants to copy/paste a chunk of code back for you.


See also;

Yes, absolutely! And thanks for the welcome. I realized after the fact that I could have just done what I did towards the beginning of the post. If I can update accordingly, I’ll do so :slight_smile:

Here is the link for google drive containing the whole project.
Cloud Breaker

If I can update accordingly, I’ll do so

It’s no biggy, just thought I’d mention it for going forwards, bit easier for those having a look at your code to copy/paste a bit back to you with a suggestion/correction rather than having to type it all out - which makes your chances of getting a response higher :wink:

Here is the link for google drive containing the whole project.

Grabbing it now - give me a few minutes…

Thanks very much. I really appreciate the help. :slight_smile:

1 Like

Just waiting for Unity to open the project, always takes a few minutes for first open…

My gut feeling is that maybe you have the same script added more than once as a component to the object, but I’ll have a look and see.


Updated Wed Sep 26 2018 19:56

Hey @Tocharaeh,

The error is being caused because you don’t have a GameStatus object in your scene when the block is destroyed.

Checking through the Hierarchy in Level1 I see you have GameStatus.cs as a script component on the Score Text GameObject.

image

You also have it as a script component of a GameObject named GameStatus.

image

When you code executes, it gets the count of the number of GameStatus objects, both script components get the value of 2, so both scripts then execute your Destroy method for the GameObject that they are attached to. You end up with no GameStatus objects left and then receive the NullReferenceException error when you try to call a method from that class.

To resolve the issue, remove the GameStatus.cs script component from the Score Text GameObject.
Note, you have this as a prefab, so if you remove it from the prefab it will then correct all of your scenes. Run your game, the umbrella is destroyed and the next level loads.

Note, you could potentially remove either one of the duplicates, but I’m guessing in the section of the course you have moved to have a specific GameObject named GameStatus (which would make more sense).

Hope this helps :slight_smile:

3 Likes

Oh my goodness, how silly of me! Thank you very much. What an easy fix. You’re the best.

1 Like

Hi Cameron,

Thank you very much.

You’re very welcome, happy to help :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms