MissingReferenceException: The object of type 'Text' has been destroyed but you are still trying to access it.
Okay so I'm making my own changes to the Roll-a-Ball tutorial from the Unity site: https://unity3d.com/learn/tutorials/projects/roll-ball-tutorial
I'm trying to add multiple levels in different scenes and I'm having trouble bringing the text over between the scenes. I keep getting this error when I touch a collectible in the second scene.
MissingReferenceException: The object of type 'Text' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
My code is here:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class PlayerController : MonoBehaviour {
public float speed;
public int score = 0;
public int thisLevel;
public Text countText;
public Text scoreText;
public Text winText;
public Text startText;
public AudioClip mwam;
public AudioClip sparkle;
public int[] countMax;
public static PlayerController instance = null;
private Rigidbody rb;
private int count;
private int finalLevel = 2;
private bool win;
// Update () is called before rendering a frame.
// FixedUpdate () is called just before computing a physics calculation.
// CTRL + ' searches API for highlighted text.
void Start () {
rb = GetComponent<Rigidbody> ();
count = 0;
win = false;
winText.text = "";
if (thisLevel == 0) {
startText.text = "Welcome!\n" +
"Touch the yellow cubes for points!\n" +
"Collect them all to win!\n" +
"Black cubes take away points; stay away!";
} else {
startText.text = "";
}
SetCountScoreText ();
}
void FixedUpdate () {
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 movement = new Vector3 (moveHorizontal, 0, moveVertical);
rb.AddForce (movement * speed);
if (win && Input.GetButton("Jump") && (thisLevel != finalLevel)) {
Application.LoadLevel (thisLevel + 1);
transform.position = new Vector3 (0, 1, 0);
count = 0;
}
}
void OnTriggerEnter (Collider other) {
if (other.gameObject.CompareTag ("PickUp")) {
other.gameObject.SetActive (false);
count = count + 1;
score = score + 50 * count;
startText.text = "";
}
else if (other.gameObject.CompareTag ("BadItem")) {
score = score / 2;
AudioSource.PlayClipAtPoint (mwam, Camera.main.transform.position);
}
else if (other.gameObject.CompareTag ("GrandPickUp")) {
other.gameObject.SetActive (false);
count = countMax[thisLevel];
score = score + 50 * countMax[thisLevel];
startText.text = "";
winText.text = "You found the secret tree!\n";
AudioSource.PlayClipAtPoint (sparkle, Camera.main.transform.position, 0.25F);
}
SetCountScoreText ();
}
void SetCountScoreText () {
countText.text = "Count: " + count.ToString ()
+ "/" + countMax[thisLevel];
scoreText.text = "Score: " + score.ToString ();
if (count >= countMax[thisLevel] && !win) {
SetWinText ();
}
}
void SetWinText () {
win = true;
winText.text += "Congratulations!\n\n\n\n" +
"You won with a score of " + score.ToString ();
if (thisLevel != finalLevel) {
winText.text += "\nYou may press the Space key"
+ "\nto jump to the next level.";
} else {
winText.text += "\nYou may now close the game.";
}
}
void Awake() {
if (instance == null)
instance = this;
else
Destroy (transform.gameObject);
DontDestroyOnLoad (transform.gameObject);
}
}
I don't know what text I'm destroying but if someone could help, that'd be great. I really just can't pinpoint where the problem is coming from.
Answer by ScienceIsAwesome · Jul 28, 2015 at 05:07 AM
Text is a part of the UI, probably in a separate gameobject which is destroyed upon loading. You need to preserve its gameobject with DontDestroyOnLoad() or it will be wiped out upon scene loading. You can also make it a child of another gameobject with the DontDestroyOnLoad() in effect.
Hmm, does that mean I should make my canvas a child of my player? I don't have a script for the UI; just the player, the camera, and one for rotating an object.
Or drop a DontDestroy$$anonymous$$e script on any gameobject you want to keep alive
Would that honestly just be as simple as just writing a script that only says public static T instance == null; void Awake() { if (instance == null) instance = this; else Destroy (transform.gameObject); DontDestroyOnLoad (transform.gameObject); }
I don't think using T would work but if I wanted to use it multiple times, I wouldn't want to have to write a script for every different type of object in my game.
Answer by Michio-Magic · Oct 25, 2015 at 12:28 AM
Something similar happened to me:
"MissingReferenceException: The object of type __ has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object."
i had this for an hour trying to get rid of it by disabling every script and game object. i finally realised it was because I had a second inspector window locked (upper right icon) so I could set some variables in the inspector. When I unlocked it, this error went away.
Hope this helps someone else to not lose their mind :)
Thank you a lot!! I meet the same situation like you. Just follow what u said: "unlock" the checkbox, then problem is solved... ~"~
Thank You! Sometimes it is always the small things. face palm
can confirm this was exactly the problem for me. I was worried searching for this bug would lead to mostly beginner issues about null references. I had a locked inspector window on second monitor behind other things. Unity should bring all inspector windows to the foreground ideally when play /stop play are pressed in editor. This would've had me scratching my head for an hour if I didn't read this answer!
thank you for this tip $$anonymous$$ichio $$anonymous$$agic
Answer by kenmgrimm · Sep 25, 2017 at 07:01 PM
Another common cause of this kind of thing is not cleaning up event listeners or coroutines that access game objects that aren't set to DontDestroyOnLoad. When you switch scenes and reload the original, if there are any event handlers or coroutines still running that reference the now destroyed (and re-created) game objects you'll get this error.
Thanks for this answer! In my case, the error only occurred when loading a different scene and returning to the original later, and some lingering event handlers were indeed the issue.
I had scene objects subscribed to a delegate in a static class. After unsubscribing them using OnDestroy() it went back to normal. Thank you for the help!
Thanks for the wisdom! Unsubscribing to some events on OnDestroy solved it in my case.
You've deserved my rep point. Holy sh, I was trying to resolve something similar for at least 3 hours, and you've solved it instantly.
Pretty old answer but very useful so I wanted to give it a +1, thank you very much.
As an addendum, here is the code to use in your scripts attached to GameObjects that you are destroying:
// Let's say you have this in the Start method
private void Start()
{
EventManager.onEvent += OnEvent;
}
// And a method that fires when receiving the Event
private void OnEvent()
{
StartCoroutine(MyCoroutine());
}
private IEnumerator MyCoroutine()
{
while(true)
yield return null;
}
private void OnDestroy()
{
// Replace EventManager.onEvent with whatever class is sending event messages to subscribers
// Unsubscribe from event(s)
EventManager.onEvent -= OnEvent;
// And stop all coroutines
StopAllCoroutines();
}
Answer by FlightOfOne · Jan 26, 2018 at 06:17 PM
I had the same problem. I am sharing this in case someone has the same issue, due to a similar scenario as I mine.
I was getting this Error:
MissingReferenceException: The object of type 'TextMeshProUGUI' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
I had nested canvases and one of canvases had a TextMeshPro (text) directly attached to it. Once I removed that, the error went away and the Event system started work again. Guess I can't directly attach a TMPro to a canvas.
Answer by Necrohunter · Jun 16, 2020 at 01:21 AM
i also went into this, but the above answers didnt help me.
My solution was:
i had a static list in some script and i did access it after reloading the scene. because it was static, it saved the old variables (or something like that?) and told me i cant access them because they are destroyed... but still exists in the static list.
so just do on your start method on the very top: YourListName.Clear();