- Home /
Reference to Object error but script works fine
Hello to all I got this script (below) Which I use to get a variable from another gameobject stocked onto this one. It check for what item is colliding with this one, and then get the script Cell3 from the colliding item, and stock the gridX variable from it. It's an instantiated object so I can't use ColliderStay, it simply doesn't work, so I used OverlapSphere as a workaround.
The problem is that I get an error message with this when I play, even though the game play perfectly fine. "NullReferenceException: Object reference not set to an instance of an object virustir.Update () (at Assets/scripts/virustir.cs:26)"
I thought at first it was because the collider was detected wrong but after many check, I realize the item also detect itself and there is no Cell3 on itself. Is there a way to tell it that if there is no Cell3 script, then to just ignore the item? Or maybe to not have it check itself? (I tried to use layers, but to no avail).
I really want to understand what is that error, and how to remove it, I'm worried it might break my code later in my project...
Thanks in advance!
using UnityEngine;
using System.Collections;
public class virustir : MonoBehaviour {
public Cell3 gridX;
public int gix;
public Collider[] colliding;
// Update is called once per frame
void Update () {
colliding = Physics.OverlapSphere(transform.position, this.GetComponent<SphereCollider>().radius);
if(colliding != null && colliding.Length > 0){
for (int i = 0; i < colliding.Length; i++) {
Cell3 c = colliding[i].GetComponent<Cell3> ();
gix = c.gridX; //line with the error on it
}
}
}
}
It is not quite clear what you want to do, but this is what I make of the the code I read:
You define gridX as an instance variable of the virustir class, which is of type Cell3. Then in the line with the error you are trying to assign the gridX instance variable, which belongs to the 'c' instance, which is also of type Cell3. I don't know the type of this c.gridX, but you are assigning it to gix, which is an int. So, if c.gridX is not an int, it would not work, even if you didn't get the error you're getting.
The NullReference error is most probably because c.gridX is not an int but of type Cell3, and nothing has yet been assigned to it. In other words you're trying to access the c.grid object, but it in null, so there's nothing to access.
You can put a null check to get rid of the error... try
if(c!=null) gix = c.gridX
@pako But a) c.gridX
is a different gridX
to the one shown in the code, presumably there's a gridX
in Cell3
which is an int
(otherwise this wouldn't compile).
$$anonymous$$ore importantly though, b) there's nothing to check that the members of colliding
all have Cell3 components. colliding
could be non-null and have oodles of members without c ever being set to something that's non-null (ie when none of them have Cell3
components). So the null check would help to protect against NREs as well as helping to track down what's going wrong.
@Sawula The effect of the NRE is just that gix doesn't get set for that object, or for any subsequent objects in the colliding
array. So gix stays at whatever value it was before. That'll be why things appear to run ok despite the NR$$anonymous$$ So add the null check, and put some logging in when c is null so you can see which if any of the colliders returned by OverlapSphere don't have Cells3 components.
Also, back to my first point, you'll find it easier to debug things (and it'll be easier for people to help you) if you get into the habit of not using the same variable name for different types of things in different classes.
@pako Sorry but you're misunderstanding what I said, your last comment contains virtually nothing which is correct.
It's not that c.gridX
belongs to a different instance, it's that c
is an instance of a different class ( Cell3
, the code for which we have not been shown and in which gridX
must be a int
or something that can be implicitly cast to one in order for the above code to compile).
Also, the compiler does not pick up on NREs. NREs happen at runtime. The fact that they're getting NREs from the above code means that it compiled and so your int
/Cell3
analysis is not correct.
And the c
variable has been set using GetComponent()
, so checking c
against null
is exactly what they need to do to check if the object has a Cell3
component.
"It's not that c.gridX belongs to a different instance, it's that c is an instance of a different class" Actually, that's what I meant, I just didn't phrase it properly.
"Also, the compiler does not pick up on NREs. NREs happen at runtime". Glad to know, thanks! I just fix them, when I get them.
"And the c variable has been set using GetComponent(), so checking c against null is exactly what they need to do to check if the object has a Cell3 component." You are absolutely right! Thanks for correcting me, I don't know what I was thinking... $$anonymous$$ind block maybe :-(
Answer by Bonfire-Boy · Jun 01, 2015 at 05:16 PM
Cell3 c = colliding[i].GetComponent<Cell3> ();
gix = c.gridX; //line with the error on it
The only way that line can throw a NRE is if the c
variable is null
, and it will be null
only if the object that colliding[i]
is on has no Cell3
component (because GetComponent<>
returns null
if it can't find a component of the required type) .
The easy way to avoid the NRE is, as Saad_Khan said in a comment, to check c against null. If you want to know more about what's going on, add some logging when it fails. Something like...
if (c != null)
{
gix = c.gridX;
}
else
{
Debug.LogWarning("Collided with "+colliding[i].gameObject.name+", which has no Cell3 component");
}