# Force applied twice on rigid body

Hi all,

I don’t understand how Unity applies forces. After I had trouble on a project with slight offsets between Unity’s results and mines, I decided to make a simple study case to understand where was the problem comming from. What I found is that on the first FixedUpdate, the AddForce seems to be applied twice, and I don’t understand why.

So, my study case is a ball falling down, with mass 1kg, initial speed 0m.s-1 and only affected by gravity with g = 10m.s-2 (no linear/angular drag)

I compare the balls’transform position with analytic ones obtained with y(t) = -0.5 * gt^2

So, now the results :

1 : When applying on the ball’s rigidBody an addforce of (g * mass) every fixedUpdate frame, I have slightly off results. I notice that there is an exact 2 times difference between the Unity and analytic results. Afterwards, the results tend toward each other, but still carrying the slight offset from the first frame.

``````public LineRenderer _lineRenderer;
[SerializeField] int nPoints = 10;
[SerializeField] float tIncrement = 0.02f;
[SerializeField] float gravityAcceleration = Vector3.Magnitude(Physics.gravity);
Rigidbody _rb;
float _mass;
bool _startFall = false;
bool _falling = false;
void Start()
{
_rb = GetComponent<Rigidbody>();
_mass = _rb.mass;
_lineRenderer.positionCount = nPoints;
_lineRenderer.SetPosition(0, Vector3.zero);
for (int i = 1; i < nPoints; i++)
{
_lineRenderer.SetPosition(i, Vector3.down * gravityAcceleration * Mathf.Pow(i * tIncrement, 2) * 0.5f);
}
}
private void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.A))
{
_falling = !_falling;
}
if (_falling)
{
Debug.Log("UnityPos = " + this.transform.position.y);
}
if (!_falling)
{
this.transform.position = Vector3.zero;
_rb.velocity = Vector3.zero;
}
}
``````

2 : So, I tried applying an addforce of (g * mass) / 2 the first fixedUpdate frame, and (g * mass) on all other frames, I get perfectly identical results between Unity and analytic

`````` public LineRenderer _lineRenderer;
[SerializeField] int nPoints = 10;
[SerializeField] float tIncrement = 0.02f;
[SerializeField] float gravityAcceleration = Vector3.Magnitude(Physics.gravity);
Rigidbody _rb;
float _mass;
bool _startFall = false;
bool _falling = false;
void Start()
{
_rb = GetComponent<Rigidbody>();
_mass = _rb.mass;
_lineRenderer.positionCount = nPoints;
_lineRenderer.SetPosition(0, Vector3.zero);
for (int i = 1; i < nPoints; i++)
{
_lineRenderer.SetPosition(i, Vector3.down * gravityAcceleration * Mathf.Pow(i * tIncrement, 2) * 0.5f);
}
}
private void FixedUpdate()
{
if (Input.GetKeyDown(KeyCode.A))
{
//Debug.Log("aaa");
_falling = !_falling;
if (_falling) { _startFall = true; }
}
if (_falling)
{
Debug.Log("UnityPos = " + this.transform.position.y);
if (_startFall)
{
Debug.Log("YYY");// to check how many times the force is applied

_rb.AddForce(gravityAcceleration * _mass * 0.5f * Vector3.down);// weight force divided by 2
_startFall = false;
}
else
{
}
}
if (!_falling)
{
this.transform.position = Vector3.zero;
_rb.velocity = Vector3.zero;
}
}
``````

Does anyone have an idea of why only the first frame is “miscalculated” and/or what I am missing?

Ah and i know that a getkeydown in a fixedUpdate is stupid, but in this case it was to be sure that I only apply force once, without juggling between update to get inputs and fixedupdate to apply the forces. By the way I first tried this way and had the same problem, so it doesn’t come from it.

I suspect what you’re seeing is the inaccuracy of the stepped simulation in Unity. The analytic calculation will perfectly reflect the acceleration curve of the object but Unity’s stepped physics simulation will have a stairway curve, with a step for each frame. These inaccuracies should average out over many frames, which seems to be the case. The analytic result and the simulated position is pretty accurate after e.g. 1s. Maybe the doubling has to do with the timestep being 0.02 but I don’t know how a physics step is calculated exactly in Unity.

``````_rb.AddForce(gravityAcceleration * _mass * Vector3.down);
``````

you can just do:

``````_rb.AddForce(gravityAcceleration * Vector3.down, ForceMode.Acceleration);
``````

In the first case, you multiply by the mass and then the physics engine will divide by the mass later. Using `ForceMode.Acceleration` prevents this and also removes the dependency on the mass.