- Home /
Missing Reference after null Check
On start I try to run this, but get "MissingReferenceException: The object of type 'Transform' 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."
if(thing!=null){//thing is referenced in the editor, so i know its there
print(thing.name.ToString());//I can access the name value of the object
//^that prints its name
print(thing.position.ToString());//error here
if(thing.childCount>0){//also error here saying it got destroyed or is missing
//it will only let me access its name
Whats going on? T.T
Edit: Can parts of objects die? I can only access the name value so far. I get the missing Reference error when i try to access this thing's position or child count.
what the hell.. I had a class, $$anonymous$$enuState, that had
Transform[] trans;
and i was tring to pull from it with a foreach
foreach(Transform thing in $$anonymous$$enuState.trans){
but was getting the missingReferenceExeptoion when trying to access attributes (exept the name) of the thing transform.
I dont know why this solved it, so im not posting this as answered, but in my struggle i tried
Transform[] transList=$$anonymous$$enuState.trans;
foreach(Transform thing in transList){
//Now i can access things without problems or errors
Im still pulling my hair out wondering why this works?
Could you double-check that code in your comment? It suggests that $$anonymous$$enuState.trans
is a nested array.
right, fixed. And further research showed i had to end up treating that array of Transforms as if it was in a 2 dimensional array
Array of lists
list of transforms
But its
Class
list of transforms
I say i had to treat it as a 2D Array, by basicaly redefining the list of transforms as a new list of transforms when reading the first dimension in a 2D array.
Just to chime in I'm seeing the exact same issue on Unity 4.5.4, I tried to post an in depth analysis but the moderators here don't seem to like public evidence of bugs in their product.
Answer by tigriscraig2 · Dec 17, 2015 at 10:48 AM
I encountered this error myself in Unity 5.2 2, and was able to diagnose and repair the problem.
I had a prefab with a Soldier. The original version of the code had a variable weapon.
public class Soldier : MonoBehavior {
public GameObject weapon;
public void Attack()
{
if (weapon != null) {
Vector3 pos == weapon.transform.position;
}
}
}
However, this was later refactored to change the type of weapon.
public class Soldier : MonoBehavior {
public Transform weapon;
public void Attack()
{
if (weapon != null) {
// MissingReferenceException in Editor
// Crash on device.
Vector3 pos == weapon.position;
}
}
}
Turns out the prefab was still pointing to the fileID of the original weapon GameObject , and not its transform. I was still able to see the variable assigned in the Inspector, and even click-follow it to the right place. However, the icon was a blue square signifying a GameObject.
To resolve the issue, I manually reassigned the variable by dragging the same exact GameObject in the inspector, and observed the icon change to the 3-line transform icon (with the same name).
I suspect might have gotten into this state due to a merge conflict or some other file related error, but I'm not sure.
Answer by AntiLunchBox · Jun 13, 2013 at 05:25 PM
Most likely that fixed worked because you are changing MenuState.trans in another script or another place. foreach doesn't work if you modifiy whatever list it's looping through. So since you stored a local copy, that wasn't changing.
the contents of $$anonymous$$enuState.trans do not change. All changes to the attributes of the contents are made in this foreach loop. I think having the local copy identified it as a Transform[], somehow only the name cound be accessed, like a generic object i assume would have.
Answer by Brady · Mar 24, 2014 at 09:43 PM
I had this same problem. I had a List of some transforms in the hierarchy. Then in a custom inspector, I have that script iterate over that list looking for any null references which might indicate that the transform has been removed from the hierarchy, like so:
if (sceneItems[i] == null || sceneItems[i].parent != transform)
sceneItems.RemoveAt(i);
But to my frustration, the transform references pass the null check but throw a MissingReferenceException when I dereference the transform's parent! Even if I separate it out as an "else" case, it still passes the null check but then throws an exception when I check the .parent member. As in your case, I was able to safely dereference the .name property, but not the .parent property. That doesn't make sense to me at all. As you said, it seems like the component is only "partially dead" - with certain members still safely accessible, but others throwing an exception.
This isn't really an answer, but I finally just had to nest the code in question in a try/catch block. For my purposes, it's okay because it should only ever encounter a destroyed transform while in-editor. But were this code that had to run on a mobile device, this approach would mean you couldn't use the "Fast but no exceptions" script call optimization setting in the player build settings.
whats the "Fast but no exceptions" script call optimization setting in the player build settings?
The .parent property will be null if there is no parent. Objects have the name property but you may need to cast the Object as another type, like (sceneItems[i] as Tranform).parent
If you're asking what the setting is set to, it is irrelevant because as I said, it is an editor script. The call optimization setting only applies to a built player. If you're asking what it does, it disables runtime exception handling on a built player.
Regarding the .parent property, it isn't the .parent property that is null, it is the act of accessing the .parent property, meaning the reference itself (which is already of type Transform) is null. Again, accessing the .parent property triggers a runtime exception. If it was a type casting issue, it would generate a compiler error. But it isn't, because the list I mentioned about is already of type List, so typing is not the issue either.
play with casting it more specifically. $$anonymous$$y fix was to basically cast a list of Transform to another new Transform list, but i was using a 2D array. From what i understand of your situation you have a list of Transform and you cant access the properties of the .parent of the transform your getting from the list. sceneItems[i].parent you know .parent isnt null but you cant access the properties from .parent or else youll you get an exception?
I would try something like this..
for(int i;sceneItems.Length;i++){ if(sceneItems[i] == null || sceneItems[i].parent ==null|| sceneItems[i].parent !=transform) sceneItems.RemoveAt(i); else{ Transform par=sceneItems[i].parent; par.positionAndOtherProertys = stuffNThings; } }
and it always helps to see the error
No, I'm not accessing the properties of the .parent member. Look at the code, I'm not accessing any of the .parent's members. It is when I access the properties of the Transform itself that it is raising the exception. I just happen to be accessing the .parent member. If I access the .position or .rotation members, it does the same thing. But accessing the .name member doesn't. It's bizarre. They're all members/properties of the same reference to a Transform, but accessing certain members raises an exception, while accessing others does not.
ok, you dont need to access the properties of the transform, but when you do , like for position, its null. Though you can access the .name. You can also get the .name from an Object type, wich makes me think you need to re$$anonymous$$d unity that your trying to access a Transform type. you still havent really given me anymore information, so i say again set the transform into a new Transform variable. Transform newThing=sceneItems[i]; newThing.position=stuff;//use the new var to do stuff with so unity knows your using a Transform type. yes its redundant, this solves some issues though.
Answer by Steazy · Oct 24, 2014 at 12:15 AM
Wish I had an answer, but wanted to chime in that as of Unity 4.5.4 this is still an issue. Confirmed on several unity installations on several operating systems. It seems that any time Transforms and Arrays get together in a non-trivial fashion the deserialized Transforms are corrupted in some fashion.
I have a MonoBehaviour with an array of structs, each struct containing a Transform reference and a float value. When they deserialize all the data is valid (looking in the Editor you can see all the Transforms are linked correctly and clicking on one will property select it). Once any C# code attempts to access any properties on the Transform though,
MissingReferenceException: The object of type 'Transform' 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.
The code throwing the exception is as follows
f( layer != null ) {
m_startingLocalPosition = layer.localPosition;
}
In case it's not clear... I am NEVER destroying layer and it is already inside a null check (as you can see). So thanks for the patronizing error message.
If I serialize "layer" as a GameObject and grab the GO's transform property everything works fine, except I don't to have the interface I want in the editor and am forced to make a bunch of unnecessary (and perplexingly expensive) calls to GameObject.get_Transform.
So this problem has existed for over a year and hasn't been fixed... as far as I can tell it hasn't even been acknowledged by any Unity employees. Geez. Here's a tip Unity, bugs like this... handled this poorly... Well, if you wanted Epic to have my money that badly you could have just asked instead of wasting so much of my time.