# rigidbody.MovePosition() vs transform.position

As per the title, I have 3 gameobjects with slightly different movement code.

The first sets its position with Transform.position.

``````using UnityEngine;

public class Tr_Position : MonoBehaviour
{
[SerializeField] private float movementSpeed = 5f;

private void Update()
{
Vector3 nextPos = transform.position + transform.forward * movementSpeed * Time.deltaTime;
transform.position = nextPos;
}
}
``````

The 2nd uses rigidbody.MovePosition() in Update().

``````using UnityEngine;

public class RB_Movement_Update : MonoBehaviour
{
[SerializeField] private float movementSpeed = 5f;
private Rigidbody rigid;

private void Start()
{
rigid = GetComponent<Rigidbody>();
}

private void Update()
{
Vector3 nextPos = transform.position + transform.forward * movementSpeed * Time.deltaTime;
rigid.MovePosition(nextPos);
}
}
``````

The 3rd also uses a rigidbody but this time it calls MovePosition() in FixedUpdate().

``````using UnityEngine;

public class RB_Movement_FixedUpdate : MonoBehaviour
{
[SerializeField] private float movementSpeed = 5f;
private Rigidbody rigid;

private void Start()
{
rigid = GetComponent<Rigidbody>();
}

private void FixedUpdate()
{
Vector3 nextPos = transform.position + transform.forward * movementSpeed * Time.fixedDeltaTime;
rigid.MovePosition(nextPos);
}
}
``````

To calculate its next position, I am using the below formula:
nextPosition = currentPosition + direction * movementSpeed * deltaTime.

Upon having all 3 gameobjects move off at the same time, the 1st and 3rd objects appear to move at the same rate while the 2nd lags severely behind. Why is that?

1 Like

The physics simulation runs on a fixed update time, hence why `FixedUpdate` should be used for physics tasks like moving a Rigidbody.

On the other hand, `Update` is tied to frame-rate; your frame-rate is how many times `Update` executes per second.
Since the physics simulation isnâ€™t tied to frame-rate, itâ€™s possible for nothing to happen on a frame where you try to execute some physics task, because the next fixed time step hasnâ€™t been updated yet on that frame.

2 Likes

Thank you for the reply. In that case, could you confirm that the logic in the below code is flawed for gameobjects with rigidbodies? (Assuming FinalizePosition is called in Update() and the supplied parameter â€śnextPositionâ€ť is calculated in Update() with Time.deltaTime)

``````private void FinalizePosition(Vector3 nextPosition)
{
if (rigid != null) rigid.MovePosition(nextPosition)
else tr.position = nextPosition;
}
``````

If it is true that the above code is flawed, would it be appropriate for one to add checks in the calculation of â€śnextPositionâ€ť to have different calculations for gameobjects with rigidbodies? Below is an example to illustrate what I am thinking of:

``````void Update()
{
Vector3 nextPosition = CalculateNextPosition();
FinalizePosition(nextPosition);
}

private Vector3 CalculateNextPosition()
{
if (rigid != null) return rigid.position + direction * movementSpeed * Time.fixedDeltaTime;
else return transform.position + direction * movementSpeed * Time.deltaTime;
}
``````

The typical way to share data between `Update` and `FixedUpdate` is to just use a global variable.
I may be wrong here, but in your `CalculateNextPosition` method, I believe `transform.position + direction * movementSpeed * Time.deltaTime;` should work fine regardless if youâ€™re using a Transform or Rigidbody for movement; you just need to make sure the next position is calculated from `Update`, and used in `FixedUpdate` when applicable:

``````Rigidbody2D rigid;
Vector3 nextPosition;

bool ShouldUsePhysics => rigid != null;

void Update()
{
nextPosition = CalculateNextPosition();

if(!ShouldUsePhysics)
{
FinalizeTransformPosition(nextPosition);
}
}

void FixedUpdate()
{
if(ShouldUsePhysics)
{
FinalizeRigidbodyPosition(nextPosition);
}
}

void FinalizeTransformPosition(Vector3 position) =>  tr.position = position;

void FinalizeRigidbodyPosition(Vector3 position) => rigid.MovePosition(position);

Vector3 CalculateNextPosition() => transform.position + direction * movementSpeed * Time.deltaTime;
``````

Thanks for getting back, that indeed sounds like a good way to share data between Update() and FixedUpdate(). I have already incorporated it into my project and its working well so far.

I also went ahead to test out your script. However, it seems that gameobjects with a rigidbody still moves slower compared to the ones without. I think this is because when a position is calculated in `Update`, as you said, some frames are rendered without the physics simulation have run its update cycle, thus making it possible for `CalculateNextPosition `to calculate the same position over a few frames, hence leading to the object moving slower than intended.

Thanks again for the replies

1 Like