Object returns null despite if (conditions)

I have 2 scripts which in 1 of them I’m attempting to set a Transform to the gameObject.transform of the other script which is handled by a Raycast (I log this to make sure it does exist), but all I receive is a NullReferenceException next to the logged object (despite specifically setting it to an actual public object (“GroundPlane”) in inspector when it IS null.

Script with Raycast:

if (Physics.Raycast(transform.position + new Vector3(0f, 0.05f 0f), Vector3.down, out RaycastHit Hit, 10f, GroundLayer))
{
       Debug.Log(Hit.transform.gameObject.name);
}

Script with Transform

public Transform GroundPlane;

void Update()
{
       if (Hit.transform.gameObject != null) ObjTag = Hit.transform;
       else ObjTag = FootSounds.GroundPlane;
}


Note: I’ve also tried this in the same script with the Transform.

The answer is always the same… ALWAYS!

How to fix a NullReferenceException error

https://forum.unity.com/threads/how-to-fix-a-nullreferenceexception-error.1230297/

Three steps to success:

  • Identify what is null ← any other action taken before this step is WASTED TIME
  • Identify why it is null
  • Fix that
2 Likes

Im afraid there is too little context for me to help with the problem. From the error message i assume the exception comes from the lower script. It would be nice if i didnt have to guess which of the two lines there originally was line 297 tho… and it’s supposed to be thrown in FixedUpdate too. Is Hit null? Is ObjTag null? How is the thing that’s null supposed to be set?

Find out what is null, find out why it’s null, then fix that. Based on the code shown i cant do that for you.
Edit: Guess @Kurt-Dekker was faster :stuck_out_tongue:

2 Likes

out RaycastHit Hit creates a local variable. The Hit in Update is null, never used.

4 Likes

Exactly. And if you want to use the field you’d have to write:

out Hit

It is best practice to follow a naming convention for field variables vs local variables. Most use a prefix: _hit or m_Hit are the most common naming conventions for fields.

1 Like

Actually thats exactly how I have it. I tried to break down the little bits of code I use in each (both scripts are around 400 to 600 lines but nothing modifies the RaycastHit, and if it is null then why does it set it to so?). Im usually quick to figure why Im getting these errors but this one has been taking a lil bit of my night up. Unless u mean local as-in THAT void

I’m not sure what void means here. Void is a return type.

if (Physics.Raycast(transform.position + new Vector3(0f, 0.05f 0f), Vector3.down, out RaycastHit Hit, 10f, GroundLayer))
{
      // Hit is a local variable only living in this code block between these two {} braces.
      // Outside of this code block another Hit variable lives (I guess) with no connection to this.
      Debug.Log(Hit.transform.gameObject.name);
}

Im aware of this, what I mean is because it is in a FixedUpdate, and the RaycastHit IS public like I stated in the post

I’m sorry, I don’t understand what you’re trying to say. RaycastHit is a public type, it has nothing to do with anything.
The reason you see “Plane” in your Console, because of the local variable and Debug.Log of it in the piece of code I quoted. The reason you get null in your Update piece of code, because you do not raycast there and the other Hit variable is a local variable, hence unreachable for you in Update.
If you want to keep the raycast in the quoted code, follow @CodeSmile 's instruction and change out RaycastHit Hit to out Hit IF you have that variable as public class member.

Just to make this very clear:

^ This declares a new variable called Hit within the if scope.

RaycastHit hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask)){...}

^ This is from the documentation and fills a preexisting variable hit.

If you do that at all, from your shown snipplets it is not possible to tell how you set the Hit variable of one script based on the detected Hit from the other script. Thus, unless something happens that is not shown in those snipplets, of course it’s Null. And if something else happens, we cant further help you without being shown the full relevant code.

I hope this makes our troubles in understanding your troubles more clear :smile:

1 Like

Could u try to understand at the least despite my knowledge on technical terms and experience with Unity in general.

Ive said it twice now (not sure if u are catching on my lack of terminology) it is written before ANY methods which ALLOWS me to access the “RaycastHit Hit” in this script using another. Ive also tried setting the Transform within the raycast (both in the same script, as to recieve the same treatment as the debug.log inside it but to no avqil.

Im not sure anyone understands, it isnt a local or private variable (again nt sure if Im hitting the right terms. I might jus have to sho 1million screenshots), and it is written exactly like that.

Well, you don’t understand what everybody is telling you. When you use this specific code snippet:

out RaycastHit Hit

you are creating a new local variable which is also named “Hit”. So inside that method there is a new completely unrelated variable Hit that only exists inside this block of code.

If you want to use a member variable of your script, you have to remove the “RaycastHit” from that snippet and just use out Hit, as it was mentioned several times alread.

However you stated several times that your code is as you have shown. Though your code shows an Update method but the error you get is in FixedUpdate. You also cut down your code to very small snippets and things like your additional Hit variable which may be declared in some of your classes is completely omitted.

You said you have two scripts. How do they communicate? If you declare a Hit member variable in one script, it does not magically be available in the other script. The other script would need a reference to the first one in order to access a field / variable of that script. You really make this whole thing unnecessary difficult for everyone here, including yourself. You simply haven’t provided the necessary context and the code you posted is also partially wrong / does not match the error.

Yoreki said:

and I agree with that. This is not a guessing game for us. You need the help, so provide all the information necessary. What do your two scripts look like and how are they communicating with each other?

4 Likes

Without running this code what do you think it will do?

using UnityEngine;

public class MyScript : MonoBehaviour
{
    public int number = 1;

    void Start()
    {
        Debug.Log(number);
       
        Run();
    }

    void Run()
    {
        if (DoAction(out int number))
        {
            Debug.Log(number);
        }

        RunSomeMore();
    }

    void RunSomeMore()
    {
        Debug.Log(number);
    }

    bool DoAction(out int x)
    {
        x = 2;

        return true;
    }
}
3 Likes

All variables have a scope. Scope is either local or global.

Member variables (the ones you declare as part of a class/struct) have an access modifier: public, protected or private.

Everybody here is talking about the scope of your variable, which you are confusing with it being public/private.

The Hit variable in your code is local to the “if (Physics.Raycast…” instruction, which means you can’t use it outside the “if” brackets. As your code is written, this Hit variable is only used to write the name of the hit GameObject to the console using Debug.Log(). After the Debug.Log(), this local Hit variable is completely discarded.

Chances are you have declared another RaycastHit variable also named Hit elsewhere (probably as a member of your class, since you mention it being declared “before any methods”), that you are accessing in Update() but it’s always null because it is not the one being modified inside your “if” clause. Despite having the same name, they’re two completely different variables with different scopes.

3 Likes

I easily shouldve left some screnshots instead. The next time I started it I seen I was missing the initial reference to the other script (should spend more time messing with my other scripts) thanks 4 trying everyone (despite my repetitive response to the same answer)