Moving Rigidbody2D relative to the mouse.

I made this script to slide a ball with a mouse:

public class Movable : MonoBehaviour { 
    private Rigidbody2D rb2d;
    private Vector2 deltaPos  = Vector2.zero;
    private Vector2 currentPosition;
    private Vector2 lastPositon;
    
    void Start() {
        rb2d = GetComponent<Rigidbody2D>();
    }

    void Update() {
        
        if (Input.GetMouseButtonDown(0)) {
            lastPositon = Input.mousePosition;
        }

        if (Input.GetMouseButton(0)) {
            currentPosition = Input.mousePosition;
            deltaPos = currentPosition-lastPositon;
            lastPositon = currentPosition;
        } else {
            deltaPos = Vector2.zero;
        }
        
        if (Input.GetMouseButtonUp(0)) {
            deltaPos = Vector2.zero;
        }
    }

    void FixedUpdate()
    {
        rb2d.MovePosition(rb2d.position + deltaPos *Time.fixedDeltaTime );
    }
}

The issue here is that the ball is not 100% in sync with the mouse. Here is a gif to demonstrate:

  • A) Code used from this video: Unity Tutorial How To Move Gameobject With Offset Between Touch Position And Objects Position - YouTube
  • B) Script I posted above. Compared to option A where the ball tries to go to the target position and just jumps once obstacle is not in the way in this option ball is moved with delta and will just stop moving when it cant.
  • C) Just to highlight the issue with my own approach. The ball should follow the mouse 1:1 as long as there are no obstacles. It is ok for the ball to stay behind when there is an obstacle, but once the obstacle is gone it should start following the mouse again.

Is the delta calculation wrong or what is causing the ball to not follow the mouse precisely?

Hi @Dubmulik, my guess is that the problem has to do with the fact that Update and FixedUpdate don’t execute in sync. For example, your Update function might run twice before FixedUpdate runs, so if your mouse moves 1 pixel each Update and it runs twice, deltapos is only 1 pixel and the other pixel is not processed by the FixedUpdate code. Have you tried just putting all of the logic into Update? That’s what the Youtube video shows. If you really want to leave the MovePosition in FixedUpdate, you could create a value to store all the movement in Update, add to it in Update and then clear it in FixedUpdate when it’s processed. Something like what you have plus the following:
`
private Vector2 movementSinceLastFU = Vector2.zero;

void Update(){
movementSinceLastFU += deltaPos;
}

void FixedUpdate(){
rb2d.MovePosition(rb2d.position + movementSinceLastFU);
movementSinceLastFU = Vector2.zero;
}
`
So yeah, I would first try just putting that MovePosition (without deltaTime) into Update to see if that is what is causing your issue. Then you can decide if leaving it there is OK or if you want to try the additive approach. Hope that helps!