Problem with calling functions and "object reference not set to an instance of an object"

Hello everybody.
I don’t understand what’s wrong with my code:

public class Mover : MonoBehaviour {

    private Rigidbody2D rb;
    private Vector2 velocity;

    public float speed;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        ChangeVelocity();
    }

    public void ChangeVelocity()
    {
        velocity = new Vector2(0f, speed);

        rb.velocity = velocity;
	}
}

Here it says that in the ChangeVelocity() method, rb is not set to an instance of an object. I know I’m doing it the right way, however, because when the same exact code was put into an Update() method, there were no errors spit at me. I don’t understand what’s wrong.

Also here’s my “speed addition script” which has a problem as well.

public class GameSpeed : MonoBehaviour {

    public GameObject player;
    public Mover _mover;
    public float setSpeedTime; 

    void Awake()
    {
        //player.GetComponent<Mover>().speed = 4.4f;
        _mover.speed = 4.4f;
        StartCoroutine(SetSpeed());
    }


    IEnumerator SetSpeed()
    {
        while (true)
        {
            _mover.speed += 0.1f;
            _mover.ChangeVelocity();

            yield return new WaitForSeconds(1);

          if (_mover.speed >= 8.99f)
                yield break;
        }
    }
}

It doesn’t want to call the ChangeVelocity method of the Mover script. As if it weren’t enough, when the _mover.ChangeVelocity is present in the SetSpeed() coroutine, it doesn’t even change the speed in the Mover script! However, when I commented out the _mover.ChangeVelocity part, and adjusted the Mover script, so everything was running in the Update() function, everything worked perfectly fine.

The issue is just because you are calling things on Awake in the GameSpeed script but the Mover script doesn’t have a definition for rb until Start. The GameSpeed script is therefore looking for something which doesn’t exist yet.

If you change Mover to use Awake instead then it will work fine. Of course that isn’t the best idea to use though… you just want to remove the commands from Awake in the GameSpeed script and have them triggered another way. Like giving it a brief delay before trying to set the speed of the Mover script. Just using yield return new WaitForSeconds(0.1); before SetSpeed does anything else would probably fix it.