Fixed update called before start

Hello guys I have problem where my FixedUpdate() on movment is called before the Start() function. Afterwards the game runs fine. But there is an exception thrown. From the Documentation it should be clear however that Start() will always be called before the FixedUpdate(). The GameObject this happens on is instantiated if that makes a difference.
Help would greatly appreciated and maybe it will help someone else too.

Here is the Error I get:

UnassignedReferenceException: The variable rb2d of CharacterMovement has not been assigned.
You probably need to assign the rb2d variable of the CharacterMovement script in the inspector.
UnityEngine.Rigidbody2D.get_velocity () <0x151247b0 + 0x0005f> in <0938a4547c9748338e40726420dfbb1d>:0
CharacterMovement.move (UnityEngine.Vector2 velocity) (at Assets/Scripts/CharacterMovement.cs:25)
PlayerMovement.move () (at Assets/Scripts/PlayerMovement.cs:20)
PlayerMovement.FixedUpdate () (at Assets/Scripts/PlayerMovement.cs:12)

Here are the relevant code snippets: Class Movement

using UnityEngine;

[RequireComponent(typeof(CharacterMovement))]
public class PlayerMovement : MonoBehaviour {
    private CharacterMovement characterMovement;

    private void Start() {
        characterMovement = GetComponent<CharacterMovement>();
    }

    private void FixedUpdate() {
        move();
    }

    public void move() {
        float horizontalMovement = Input.GetAxisRaw("Horizontal");
        float verticalMovement = Input.GetAxisRaw("Vertical");

        characterMovement.resolveDirection(horizontalMovement, verticalMovement);
        characterMovement.move(new Vector2(horizontalMovement, verticalMovement));
}

Class CharacterMovement

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class CharacterMovement : MonoBehaviour {
    [SerializeField] protected float moveSpeed;
    [HideInInspector] public Rigidbody2D rb2d;
    [SerializeField] public Direction direction;
    [HideInInspector] public bool readyToMove;
    [HideInInspector] public Animator animator;

    private void Start() {
        animator = GetComponent<Animator>();
        rb2d = GetComponent<Rigidbody2D>();
        readyToMove = true;
    }

    public void move(Vector2 velocity) {
        if (readyToMove) {
            rb2d.velocity = velocity * moveSpeed;
            rb2d.velocity = Vector2.ClampMagnitude(rb2d.velocity, moveSpeed);
            playWalkingAnimation();
        }

        //Stop animation if player doesn't move
        if (rb2d.velocity == Vector2.zero) {
            animator.speed = 0;
        }
    }

    public void stopMovement() {
        rb2d.velocity = Vector2.zero;
    }

Hi, @perikless

Here is a mistake in CharacterMovement.cs line 25. Correct version for move method will be:

 public void move(Vector2 velocity) {
         if (readyToMove) 
        {
             rb2d.velocity = velocity * moveSpeed;
             rb2d.velocity = Vector2.ClampMagnitude(rb2d.velocity, moveSpeed);
             playWalkingAnimation();

         //Stop animation if player doesn't move
         if (rb2d.velocity == Vector2.zero) 
         {
             animator.speed = 0;
         }

        }
     }

Please note, that in your case FixedUpdate() called for PlayerMovement behaviour, so it’s guaranteed to be after Start() but only for PlayerMovement, not for CharacterMovement.

Since PlayerMovement.FixedUpdate() executes before CharacterMovement.Start() on the instantiated GameObject, you should move the code that you currently have in CharacterMovement.Start() inside CharacterMovement.Awake() :

     private void Awake() {
         animator = GetComponent<Animator>();
         rb2d = GetComponent<Rigidbody2D>();
         readyToMove = true;
     }

All Awake() calls are always made before any Start() calls, even for Instantiated GameObjects.

Thank you very much for your answer. @cvid

If I see this correctly you suggest the second if statement to be nested. However other parts of the game interact with the bool readyToMove and I need it outside.

My current workaround to the problem is to remove the [HideInInspector] tag and drop the components of the prefab into that field. I was unware that is possible with components on the same object.

Nonetheless I am a bit confused as to why this issue happens. The Unity Manual states the following:

For objects added to the scene, the Start function will be called on all scripts before Update, etc are called for any of them. Naturally, this cannot be enforced when an object is instantiated during gameplay.

However I would assume the Start() in the Instantiated Object would run before the FixedUpdate() on the same Object