Notifications
Article
Why we add forces in FixedUpdate(), not in Update()? [ENG]
Updated 5 months ago
729
1

An example of a situation in which we add forces to the body in the Update () and FixedUpdate () methods.

At the beginning, we simulate the fall of the body with the force of gravity.
I have 3 balls.
The first falls due to the fact that it has a Rigidbody component influenced by the force of gravity.

The second and the third sphere also have the Rigidbody component but the "Use gravity" is turned off.

These balls will drop because we'll add acceleration to them using the AddForce () method.
We will add an acceleration to the green sphere in the FixedUpdate () method;
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AddingForceInFixedUpdate : MonoBehaviour { Rigidbody rb; void Start () { rb = GetComponent<Rigidbody> (); rb.useGravity = false; } void FixedUpdate () { //We add acceleration to sphere equal to gravitational acceleration rb.AddForce (Physics.gravity, ForceMode.Acceleration); } }
We will add an acceleration to the yellow ball in the Update () method;
using System.Collections; using System.Collections.Generic; using UnityEngine; public class AddingForceInUpdate : MonoBehaviour { Rigidbody rb; void Start () { rb = GetComponent<Rigidbody> (); rb.useGravity = false; } void Update () { //We add acceleration to sphere equal to gravitational acceleration rb.AddForce (Physics.gravity, ForceMode.Acceleration); } }

Test number 1

Let's see what the movement of these 3 balls looks like. Example for 800 FPS.
The red and green ball fell simultaneously. Yellow fell faster.

Test number 2

Now we are entering QualitySetting tab in Project Settings (Menu Edit-> Project Settings).
We change the default value of V Sync Count (option Don't Sync - the application refreshes as often as possible) to Every Second V Blank so that the application will refresh at approximately 30 FPS.
Let's put the balls in motion again. Example for 30 FPS.
This time the yellow ball fell later than the other two balls.
When we added forces in the FixedUpdate () the body fell exactly the same as the body with the Rigidbody component and gravity on.
When we added forces in Update (), the falling velocity depended on the number of FPS.

Why should we add forces in the FixedUpdate () method?

At the beginning I will show you a drawing showing the timeline.
In the timeline, I have marked the places on the axis when FixedUpdate () and Update() are called.
First, let's look at calling the FixedUpdate () method.
Below is an example code with the help of which we give the body acceleration.
// reference to rigidbody which we will move public Rigidbody rb; void FixedUpdate() { rb.AddForce(force: Vector3.right, mode: ForceMode.Acceleration); }
The figure shows that the FixedUpdate () method is called at a fixed frequency of 50 Hz, ie every 0.02 seconds.
(0.02s is the default time at which the physical loop is called - this setting can be changed in the Project Settings-> Time -> FixedTimestep )
Suppose we give the body acceleration 1m / s^2.
Let's look at how the acceleration and speed of the body will change.
When we add forces in FixedUpdate () we ensure that the acceleration will be constant over time.
In the case of velocity, its value will increase by constant values at fixed time intervals.
This is how the bodies will move under the influence of constant forces. We expect such kind of motion of bodies when we add forces to them.

We will now look at calling the Update () method and adding forces to bodies in this method.

At the beginning, an example code fragment that we want to call.
// reference to rigidbody which we will move public Rigidbody rb; void Update() { rb.AddForce(force: Vector3.right, mode: ForceMode.Acceleration); }
The following figure is shown on the timeline when the Update () method is called. The Update() method is related to the logic and rendering loop.
https://docs.unity3d.com/2017.1/Documentation/uploads/Main/monobehaviour_flowchart.svg
https://docs.unity3d.com/Manual/ExecutionOrder.html
Logic and rendering loop is called as often as possible, so Update () also.
However, the AddForce () method will not work when you call Update ().
The forces will be added only when the physical loop is called, and more specifically, when the physics loop is updated internally.
So in reality forces will be added in these moments of time.
And thus, the added forces will act on the body only from the moment of calling the physical loop and adding forces to the body.

What are the consequences of this situation?

In the picture above, we see that we do not add a constant force to the body. The total force acting on the body depends on the number of calls to the Update () method over a given time interval, because the forces add up.
From the above figure it can be seen that when the Update () method was called twice in the time interval 0.02 - 0.04, the double force will operate in the time interval from 0.04-0.06.
Look at the individual time intervals and forces acting on the body.
The acceleration value and speed value change continuously depending on the number of calls to the Update () method.
The body will not move with constant acceleration.

What are the consequences of adding forces in Update ()?

The body movement will depend on the performance of the application. Weaker forces will be addedto bodies on weaker devices. On better devices, larger forces will be added to the rigidbodies.
The velocity of the bodies will depend on the performance of the device.
The motionof the body will be jerky and unpredictable.
You had the opportunity to see him in the first examples with spheres.

Where to add forces to rigidbodies?

Methods such as AddForce () / AddTorque () should be called in FixedUpdate () (or other methods related to the physical loop).
If any method will cause the body to move with constant acceleration for a longer period of time, it should be called in FixedUpdate ().
In the case when we add force to the body only once, we can use the AddForce () / AddTorque () method also in Update (). An example of such a situation can be firing a projectile, where only at the beginning of motion we add force on the projectile.
Rafał Tadajewski
I haven't duck. I took dino. - Programmer
10
Comments
NG
Nikita Goncharuk
5 months ago
Thats awesome article. I will post it in my channel https://t.me/Game_Dev_Channel
1