Text destroyed?

Hello

I got a error here and im stuck :slight_smile: .

This error appear after i implemented singleton.
whem i play a game in scene 1 everything is working perfectly .But on the moment i load scene 2 and hit the brick i got a error >>>MissingReferenceException: The object of type ‘Text’ has been destroyed but you are still trying to access it.<<<. (I dotn´t using a TextMesh PRO just a siple text )

whem i don´t put a GameStatus on scene 2 everything is working perfectly.
so my quess is error apears whem if/else Destroy(gameObject); start working.

i use prefab GameStatus,
his child canvas
and his child Text

and i noticed i don´t see Text as child in prefab wondering why … :slight_smile:

Thx for help :slight_smile:

Hey Mac,

I was having the same problem. I went to my 2nd scene and deleted the “Game Status” prefab and it fixed the issue. Not entirely sure what the problem was, but it worked!

Hopefully this works for you as well!

1 Like

Heyo,

I had the same problem, but I believe I fixed it.

TL;DR;

  • in Block.cs, make sure you don’t cache a reference to the GameStatus on start, but rather dynamically find it each time you destroy a block:
void OnCollision2D(...) {
  // do this here. don't cache this reference..it gets cleaned up I guess?
  FindObjectOfType<GameStatus>().AddPoints();
 // ...other collision things with blocks
}

would be nice to hear why this is from someone who is more familiar with the memory model and the lifecycle of Destroy().

This also allows you to not have to delete GameStatus prefab from subsequent scenes so you can continue to test each scene individually.

Hope this helps!

Alex

Hi Alex,

Whilst this may work, the use of any of the Find methods Unity provide are fairly slow, so from a performance perspective, this may not be the best approach. If you consider what the method is doing, it’s iterating through every GameObject in the scene in order to find the GameObject you desire, so to then do that every time there is a collision with a block, which by the nature of this game there will a lot of, isn’t ideal.

I’ve not looked at the updated version of Block Breaker, so I’m not sure whether perhaps the issue that has been experienced is resolved in a later lecture or whether perhaps something has just been missed when progressing through the lectures, but I just wanted to dip in and mention the above.

The idea behind the singleton approach would be to create an instance once, if subsequent attempts to instantiate the object are made, these would be destroyed, leaving only the original. Often the constructor is wrapped up inside a property, so when you try to access it, if one doesn’t exist it is created and returned, if one does exist, its just returned.

Hope this is of use :slight_smile:


See also;

Hey Rob,

Yeah that makes sense on how Find methods traverse the scene. I did read in the optimization sections of the unity docs for mobile games that limiting Find methods is good for performance.

I don’t know how this section has changed but the Singleton pattern is fairly common in other programming settings. I guess what I was hoping for was a class annotation vs hard coding singleton logic into Unity’s script lifecycle hooks (kinda seems like a gotcha).

Excited (and hopeful) to see other implementations of the pattern later in the course! Sharing state between components/scenes was the first major question I had when starting to learn Unity.

Thanks for the informative reply!

Alex

1 Like

Hi Alex,

It will definitely come up again throughout the course, from memory there’s a Music Player in Glitch Garden (original content), I’m less familiar with the more recent content updates though so hard to advise on that front.

You’re very welcome for the reply and I hope you enjoy the rest of the course, I will look forward to seeing what you make and share :slight_smile:

I was having this same problem - After I read the docs, I realized that the Start method is called is called before the first frame is updated, where Destroy doesn’t actually occur until after the current update loop, which won’t happen until after start. That makes me believe that since the block grabs the GameStatus object type when Start is called, it is grabbing the second instantiated GameStatus object, which then gets destroyed immediately on the first call to update in GameStatus.cs - therefore, it leaves the block objects with a null reference. You can test this by using Debug.Log after calling destroy in gameStatus and seeing that there are still 2 instances, but in the first call to Update there is only 1. Not sure if Destroy’s implementation has changed since the video or not, but that’s what I’ve been able to deduce.

Oh and using DestroyImmediate instead of Destroy fixes the issue.

1 Like

This fixed it for me, thank you. I’d added a check for null on the object and re-find if it was missing but immediate destruction seems cleaner. I’d have figured this out sometime around never so thanks!

Thanks for the DestroyImmediate tips, it worked “almost” just fine for me.
“Almost”, because for some reason, the score starts to be counted only from the moment I destroy the second block.
The first time it goes to 0, and the second time I get the correct amount of points.
Score at start is of course set to 0, and I don’t see any difference between my coding and the one from Rick.

Any idea of what could be causing this?

EDIT : Ok, I found the reason myself !
My AddToScore method had a very basic problem :

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

I accidentally switched the two variables as you can see above. The result was it was first displaying current score, and then only adding the point. Thus a kind of “lag” in the calculation.
I don’t think it’s an issue many people will face here, but since order can really mess up your scripts without you noticing it, maybe it’ll be of any use to someone. At least it sure will to me :slight_smile:

Privacy & Terms