Fixed Update Nullifies rigidbody2d

I was getting a “Null Reference Object” error on my rigidbody2d component when I had move functionality inside of FixedUpdate. When I moved the movement into Update, the rigidbody2d. Any idea why?

using System;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]

public class CharacterController2D : MonoBehaviour
{

    Rigidbody2D rigidbody2d;
    [SerializeField] float speed = 2.0f;
    Vector2 motionVector;
    public Vector2 lastMotionVector;
    Animator animator;
    public bool moving;


    void Awake()
    {
        rigidbody2d = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        ... DO OTHER STUFF...
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        Move();
    }

    private void Move()
    {
        rigidbody2d.linearVelocity = motionVector * speed;
    }
}

printing “rigidbody2d” above the final line reveals it to be null, but it is NOT null when printed during Awake();

Any ideas why?

Perhaps it’s being nulled in the ‘DO OTHER STUFF’?. Try removing the Update stuff and see what happens.

I commented out everything in Update(), but no success, same errors.

It seems like anywhere within Update is safe, but that every other call to FixedUpdate() results in a null object. You can see in the screenshot below that it prints “Fixed Update Start” (indicating we entered FixedUpdate successfully) followed by “MainCharacter” when printing the rigidbody, which is the expected functionality, but then immediately below this “Fixed Update Start” is followed by “Null” when printing the rigidbody.

In contrast, Update always returns the rigidbody “MainCharacter” as expected. (Note that Move(); is called within Update right now to suppress the extra console messages.)

using System;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]

public class CharacterController2D : MonoBehaviour
{

    Rigidbody2D rigidbody2d;
    [SerializeField] float speed = 2.0f;
    Vector2 motionVector;
    public Vector2 lastMotionVector;
    Animator animator;
    public bool moving;


    void Awake()
    {
        rigidbody2d = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
    }
    // Start is called once before the first execution of Update after the MonoBehaviour is created

    private void Update()
    {
        print("U1" + rigidbody2d);
        float horizontal = Input.GetAxisRaw("Horizontal");
        float vertical = Input.GetAxisRaw("Vertical");
        print("U2" + rigidbody2d);
        motionVector = new Vector2(
            horizontal,
            vertical
            );
        animator.SetFloat("horizontal", horizontal);
        animator.SetFloat("vertical", vertical);

        moving = horizontal != 0 || vertical != 0;
        animator.SetBool("moving", moving);
        
        print("U3" + rigidbody2d);
        if (horizontal != 0 || vertical != 0)
        {
            lastMotionVector = new Vector2(
                horizontal, 
                vertical
                ).normalized;
            animator.SetFloat("lastHorizontal", horizontal); 
            animator.SetFloat("lastVertical", vertical);
        }
        print("U4" + rigidbody2d);
        Move();
    }

    // Update is called once per frame
    void FixedUpdate()
    {
        print("Fixed Update Start");
        print(rigidbody2d);
    }

    private void Move()
    {
        rigidbody2d.linearVelocity = motionVector * speed;
    }
}

I don’t know what’s causing it yet, but my guess is that there are other controllers inheriting from this class that are causing the issue. I’ll poke around a bit more. Thanks for the ideas!

Then maybe you changed it or else you have two or more of these scripts in the same scene.

Print the gameObject.name to see.

Also, what’s with all the GetComponent<>T() crazy ninja madness in Awake()? Just drag the references in the good old Unity way until you’re more confident with crazy ninja approaches. See below.

Whatever it is, NullReferenceException is always solved the same way.

The answer is always the same… ALWAYS!

How to fix a NullReferenceException error

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

NullReference is the single most common error while programming. Fixing it is always the same.

Some notes on how to fix a NullReferenceException error in Unity3D:

http://plbm.com/?p=221


Keep in mind that using GetComponent() and its kin (in Children, in Parent, plural, etc) to try and tease out Components at runtime is definitely deep into super-duper-uber-crazy-Ninja advanced stuff.

Here’s the bare minimum of stuff you absolutely MUST keep track of if you insist on using these crazy Ninja methods:

  • what you’re looking for:
    → one particular thing?
    → many things?
  • where it might be located (what GameObject?)
  • where the Get/Find command will look:
    → on one GameObject? Which one? Do you have a reference to it?
    → on every GameObject?
    → on a subset of GameObjects?
  • what criteria must be met for something to be found (enabled, named, etc.)
  • if your code expects one instance and later you have many (intentional or accidental), does it handle it?

If you are missing knowledge about even ONE of the things above, your call is likely to FAIL.

This sort of coding is to be avoided at all costs unless you know exactly what you are doing.

Botched attempts at using Get- and Find- are responsible for more crashes than useful code, IMNSHO.

If you run into an issue with any of these calls, start with the documentation to understand why.

There is a clear set of extremely-well-defined conditions required for each of these calls to work, as well as definitions of what will and will not be returned.

In the case of collections of Components, the order will NEVER be guaranteed, even if you happen to notice it is always in a particular order on your machine.

It is ALWAYS better to go The Unity Way™ and make dedicated public fields and drag in the references you want.

For the “crazy ninja madness” you mention, I’m following a tutorial online. I’m new to this, and trying to learn best practices.

As for the rest of your comment, I appreciate that you took the time to copy-paste your answer to other peoples’ similar issues, but at this point I’m mostly confused why the failure only happens every other time FixedUpdate is called (and not, for instance, every time). Perhaps that information could help me with step 2 of your outline to succes.

Perhaps printing the name of the GameObject where you do the GetComponent and where you attempt to use it and find out that it is null would be enlightening to you.

I believe I already did that. Unless I’m misunderstanding you, this is what I meant by “printing rigidbody2d…is NOT null when printed during Awake()” as well as in the other locations. This is what you are suggesting, right?

What you did just prints a rigidbody.

But what GameObject is the script even on?

What I’m suggesting prints the NAME… this can enlighten you as to which GameObject this script is on.

“Oh no Mario, the rigidbody is in the other GameObject!”

I obviously don’t understand what you’re suggesting then. Are you suggesting to print rigidbody2d.gameObject.name instead? As far as I can tell, the difference between printing rigidbody2d.gameObject.name and rigidbody2d is minuscule (I get basically the same information). If you’re suggesting something else when you say “what GameObject is the script even on?” then I really am lost about what you’re suggesting, but I appreciate the attempt to help!

To understand why I say the difference is minuscule, the first line below is printing just rigidbody2d and second prints rigidbody2d.gameObject.name.

So how about in the line right BEFORE the nullref happens you print out gameObject.name or just name ?

You have to think like a detective and PROVE that the actual nullref is happening on your MainCharacter and not something else.

It sounds like the question I should ask is “how can I print a line before the call to FixedUpdate();?” Anywhere else in this script, things are peachy.

As I explained in my second reply to zulo3d, I have other controllers inheriting from this class that I may need to poke around a bit more. That seems more promising than what I’m doing right now.

Before you get too frustrated… sometimes this sort of “it can’t do this” stuff seems to surface. It will almost certainly turn out to be something the developer has done (or failed to have done).

So come up with a system for debugging that you can use consistently and avoid ad hoc things. Part of the messages here mention consistency with log messages. I don’t expect everyone to follow my convention but I never output “foo” or “this ran” or non-informational stuff. Mine include the class, the method and optionally some data. I also include an instance id to differentiate between multiple instances of the same object.

All the messages are color coded (by level) and include a timestamp and (as of recently) a TimeSpan representing how long the app has been running. I include log lines “everywhere” so I know that things have been called, when they were called and the order they were called. This can become problematic in “update” type methods so I include a conditional logging type and can opt to log those when a particular condition is met (like every 60th call or something).

If I was experiencing the issue you see I would comment out just about everything and just test an example using Update and one using FixedUpdate. Again the thought is “this cannot be happening” so reducing the area to analyze is a good thing. Oh I just about never log an object. I know it works but I would log (rigidbody2d == null) so I get an actual answer to my question.

2 Likes

After some more experimentation with the subclasses inheriting from this one, I have found that they are the cause of the issue—commenting out everything in the child classes resolves the error, but leaving anything uncommented perpetuates it. I have suspicions that the tutorial will fix this later on, since there’s a “refactoring” stage upcoming.

Thanks! This is very helpful for figuring out how to find the source of the issue. I really appreciate it!

The solution ended up being that the subclasses weren’t supposed to be subclasses, and how they both ended up being cast that way is a bit of a mystery. I appreciate all the advice and ideas, and it turns out the answer was to comment out everything possible like @tleylan suggested. Thanks!

Oh… there’s your problem: you’re not doing the tutorial correctly.

Remember, it’s only two steps:

Two steps to tutorials and / or example code:

  1. do them perfectly, to the letter (zero typos, including punctuation and capitalization)
  2. stop and understand each step to understand what is going on.

If you go past anything that you don’t understand, then you’re just mimicking what you saw without actually learning, essentially wasting your own time. It’s only two steps. Don’t skip either step.