if (Something != null) not good enough
Hello, it seems that I have been having a problem multiple times where I might have a GameObject variable called "Target" which may or may not exist, so I first check by doing:
if (Target != null){
//Something that requires Target to not be null will happen;
}
This is apparently not good enough though, because my game will randomly crash sometimes when apparently my check is ignored, and I get this error:
MissingReferenceException: The object of type 'GameObject' 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. StatsManagerScript.Update () (at Assets/Scripts/StatsManagerScript.cs:52)
Answer by FlyingHighUp · Oct 14, 2017 at 10:07 PM
Object.Equals is overridden by the UnityEngine, and it checks for destruction.
So instead of Target != null
go Target != null && !Target.Equals(null)
Variables don't become null once Unity destroys an object. Internally the C# object still exists until it is no longer referenced, then it is garbage collected.
This is usually not required as long as the variable type is a type derived from UnityEngine.Object.
imagine those variables:
GameObject obj1 = new GameObject();
UnityEngine.Object obj2 = obj1;
System.Object obj3 = obj2;
DestroyImmediate(obj1);
if (obj1 == null) // true
if (obj2 == null) // true
if (obj3 == null) // false
He said the Target variable is of type GameObject in which case the overridden ==
and !=
operator is used. Also a nullreference exception doesn't crash the game, it just ter$$anonymous$$ates the current callback execution. The question isn't really clear. It would be great if we can actually see the declaration of the variable and if he would be more clear what he mean by crash
As @Bunny83 alreayd said, the second check is not necessary for objects of classes that inherit from UnityEngine.Object because that class implements custom == and != operators that not only check for null, but also check if the underlying object has been destroyed. Notice that your $$anonymous$$onoBehaviour might still live even after you've called Destroy on it. That happens because the lifetime of Unity native components are deter$$anonymous$$ed by Destroy calls, but the lifetime of C# scripts is deter$$anonymous$$ed by the garbage collector. Thus, a $$anonymous$$onoBehaviour might still exist when its underyling components (transform, game object...) have been destroyed.
This article explains it more throughly .
Answer by atulvi · Dec 16, 2020 at 11:26 AM
Any Unity Component Check null or not.
1) Create Script : InternalComponentExtension.cs
public class InternalComponentExtension : MonoBehaviour
{
[SerializeField]private static GameObject _gameObject;
[SerializeField]public static GameObject GameObject
{
get{
if(_gameObject == null)
{
GameObject g1 = new GameObject();
_gameObject = g1;
}
return _gameObject;
}
}
}
2) Access or Check Component Create Script : Demo.cs and add in to any GameObject in scene.
public class Demo: MonoBehaviour
{
[SerializeField]private GameObject myGameObject;
[SerializeField]private GameObject MyGameObject
{
get
{
if(myGameObject == null)
{
myGameObject = InternalComponentExtension.GameObject;
}
return myGameObject;
}
}
void Start()
{
//Access any GameObject property.
MyGameObject.name = "ATUL PATEL";
}
}
Not sure what this code is supposed to do but it will most definitely produces unexpected behaiour and is simply wrong.