Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by perikless · Mar 25, 2018 at 12:11 PM · errorstartupdate function

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;
     }

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pako · Mar 25, 2018 at 04:40 PM 0
Share

I can't believe that FixedUpdate() is called before Start().

It seems that rb2d = GetComponent<Rigidbody2D>() isn't finding a Rigidbody2D component for some reason.

Also, put some debug statements in your code to see which gets called first:

 bool fixedUpdateCalled;     
 
 private void FixedUpdate() {
 
 if(!fixedUpdateCalled){
      Debug.Log(name + " FixedUpdate() was called");
      fixedUpdateCalled = true;
 }
          move();
      }

      private void Start() {
           Debug.Log(name + " - Start() called");
 
          animator = GetComponent<Animator>();
          rb2d = GetComponent<Rigidbody2D>();
          readyTo$$anonymous$$ove = true;
      }

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by pako · Mar 26, 2018 at 11:43 AM

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.

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image perikless · Mar 26, 2018 at 03:28 PM 0
Share

@pako Yes this is correct. This will fix the problem however I was hoping I could avoid having it to run on Awake() since that is the way I set up the control flow in my game. (Game$$anonymous$$anagers are on Awake() etc, Physics and Rendering on Start()).

However the problem is that Unity is not very transparent as why Player$$anonymous$$ovement gets executed before Character$$anonymous$$ovement, my best guess is creation time of the script. Something like sorting layer mechanic would be neat to get around that.

avatar image Bunny83 perikless · Mar 26, 2018 at 03:56 PM 1
Share

Why do you insist of that control flow? Awake should be used for the objects initialization. It could be seen as the objects constructor. So Awake should handle all internal references while Start should be used to setup references between different objects.


How is that object actually "created"? Is it placed in a scene and loaded with the scene or do you instantiate it manually? If you instantiate it manually, when do you instantiate it (from which callback)? Are both components already attached and enabled or do you enable it later from code?


You can generally change the script execution order if it's necessary. However it's better to avoid relying on such explicit settings. It's better when the component just works on its own

avatar image perikless Bunny83 · Mar 26, 2018 at 06:15 PM 0
Share

@Bunny83 What you suggest seems like better practice than what I do actually. Thank you.

I have a basic version of the Player saved as prefab with the main components. The scripts in my question are also on this prefab. The prefab gets Instantiated and then further adjusted from a deserialized SaveGame.

And yes I really try to change the script execution order as little as possible to avoid further complications with the engine itself.

avatar image pako perikless · Mar 26, 2018 at 04:05 PM 0
Share

However the problem is that Unity is not very transparent as why Player$$anonymous$$ovement gets executed before Character$$anonymous$$ovement, my best guess is creation time of the script. Something like sorting layer mechanic would be neat to get around that.


It's just random execution order, i.e. you can't rely on a specific order of execution, unless you set it explicitly, but even then, there are certain occasions that the explicitly set order of execution is ignored by Unity. Personally, I prefer to find a solution without explicitly setting the order of execution of scripts.

avatar image
1

Answer by cvid · Mar 25, 2018 at 04:07 PM

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.

Comment
Add comment · Show 5 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pako · Mar 25, 2018 at 04:45 PM 1
Share

Could you please pinpoint the mistake you have spotted. As I see it your code is identical to the OP's code. What am I missing?

Please note, that in your case FixedUpdate() called for Player$$anonymous$$ovement behaviour, so it's guaranteed to be after Start() but only for Player$$anonymous$$ovement, not for Character$$anonymous$$ovement

This is not so. FixedUpdate() is always called after Start() has been called in all scripts.

What you are saying is valid only for Awake() - OnEnabled(): OnEnabled() is always called immediately after the Awake() of the same script, but before the Awake() of other scripts.

avatar image pako · Mar 25, 2018 at 04:54 PM 1
Share

O$$anonymous$$, I see what you mean by "mistake". You moved the if (rb2d.velocity == Vector2.zero) block inside the if (readyTo$$anonymous$$ove) block.

That's not a mistake. It's good as it is, and it any case, it has nothing to do with the problem.

avatar image perikless pako · Mar 25, 2018 at 05:10 PM 1
Share

@pako That is correct , thanks for pointing it out.

avatar image cvid pako · Mar 25, 2018 at 05:39 PM 1
Share

@pako You are right. But only in case of objects that already exist on scene load. FixedUpdate for some behaviour can be called earlier than Start for another in case of instanciating.

avatar image pako cvid · Mar 25, 2018 at 05:51 PM 1
Share

Thanks for pointing out. That, would explain the problem. As I said in my other comment, I have never tested this, because I generally use pooling rather than "Instantiate on demand", and I have all pooled objects pre-existing in the scene, i.e. they all exist on scene load.

avatar image
0

Answer by perikless · Mar 25, 2018 at 05:09 PM

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

Comment
Add comment · Show 7 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pako · Mar 25, 2018 at 05:23 PM 1
Share

@perikless have you seen the comment I posted just below your question? I have to ask this, because it seems that you haven't, and many times the system automatically hides these comments, and you have to click on the "Show" link to see them.

avatar image pako · Mar 25, 2018 at 05:35 PM 1
Share

@perikless I'm not sure, but I would think that this is applicable for scripts on different GameObjects:

... Naturally, this cannot be enforced when an object is instantiated during gameplay

If you include the debug statements I mentioned in my comment, we'll see if it's applicable for scripts on the same GameObject too. If so, it would explain the problem.

I avoid Instantiating GameObjects during gameplay, this is why I have never come across this issue. Instantiation is rather heavy on performance. I prefer to pool all the necessary GameObjects, and enable/disable them when I need them. Enabling/Disabling is "light" on performance, especially when compared to Instantiated/Destroy.

avatar image perikless pako · Mar 25, 2018 at 07:56 PM 0
Share

@pako Yes I did miss your comment below the question. With the Debug Statements I was able find out that the script Player$$anonymous$$ovement.cs is executed before the Character$$anonymous$$ovement.cs But since Player$$anonymous$$ovement depends on my Character$$anonymous$$ovement character$$anonymous$$ovement = GetComponent<Character$$anonymous$$ovement>();

Is there some way to work around that besides Unitys Script Execution Order, because I don´t want to put Character$$anonymous$$ovement before default time.

This is only one object: The players character. Thats why I don't have object pooling here. But would you even recommend object pooling for single objects? I don't know what the best practice is here.

avatar image pako perikless · Mar 26, 2018 at 11:47 AM 1
Share

Pooling is for multiple GamObjects. However, since you always need a player in the scene :-) you could have the player GameObject preexisting in the scene. This player GameObject could be disabled by default, if you need it so before action starts, and enable it when the action starts.

Show more comments
avatar image pako · Mar 26, 2018 at 11:31 AM 1
Share

I wanted to get to the bottom of this, so I made some tests.

  • If all GameObjects are already in the scene, Start() is always called before Update() and FixedUpdate() (as expected)

  • If not all GameObjects are already in the scene, Start() is called first for the Objects that are in the scene, and then Start() is called for Objects that get Instantiated. Also, Start() always gets called before Update() (as expected), but not FixedUpdate(). FixedUpdate() for instantiated objects is called immediately after their Start(). So, if an object pre-exists in the scene and has an Update() but an instantiated objects has a FixedUpdate(), the Start() of the preexisting object will be called first, followed by the Start() of the Instantiated object, immediately followed by the FixedUpdate() of the Instantiated object, and finally the Update() of the preexisting object.

  • If the Instantiated object has 2 scripts as in this case, again, the FixedUpdate() of each script will follow immediately after the Start() of the same script. The order of execution of these 2 scripts seem random.

  • If the Instantiated object has 2 scripts with Update() ins$$anonymous$$d of FixedUpdate() the Start() of each script would execute first and then the Update() of each script (as expected).


avatar image perikless pako · Mar 26, 2018 at 03:29 PM 1
Share

@pako Thank you so much for your research. This clears a lot of things up. I further elaborated in a comment to your answer.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

101 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Weird Spring Oscillation Error 1 Answer

A Script error With Void Start 2 Answers

UPDATE: FixedUpdate Issue: AngleAxis stops all other rotation within FixedUpdate. Two types of rotation cannot be calculated? 0 Answers

Start() of Instantiated Prefabs Not Being Carried Out? 1 Answer

How do I access variables initialized in a start function from another script? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges