RigidBody2D MovePosition transition to point

Hi,

I tried to do it many times, without the desired effect.
I want my character to move up 1.5f units above it after clicking the button.

  • I want to see the transition between the previous point and the above one.
  • Collision have to be detected
  • Even though a collision is detected, the player continues to move (only applies to certain elements with a given tag)

I know that I have to use rb.MovePosition but I don’t know how.

public Vector2 deltaPosition = new Vector3(0, 1.5f);
public float MovementSpeed = 0.01f;
private Vector2 desiredPosition;
private Rigidbody2D rigidbody2D;

void Start()
{
    rigidbody2D = GetComponent<Rigidbody2D>();
    desiredPosition = rigidbody2D.position;
}

 // Call this function using your button
 public void TriggerMovement()
 {
        desiredPosition = rigidbody2D.position + deltaPosition;
 }

// Optional, just for easy debug
void Update()
{
    if( Input.GetKeyDown(KeyCode.Space) )
          TriggerMovement();
}

void FixedUpdate()
{
    if( (rigidbody2D.position - desiredPosition).sqrMagnitude > MovementSpeed * 0.01f ) // Change threshold if needed
    {
        rigidbody2D.MovePosition(Vector3.MoveTowards(rigidbody2D.position, desiredPosition, MovementSpeed)) ;
    }
}

ORIGINAL ANSWER

When creating games, having a scientific background is very useful.

In your situation, it seems you want your player to jump at a given height. Jumping is a little bit like throwing something in the air, so the rules of projectile motion apply here.

A formula gives you the maximum height a projectile can reach:

       v_0² * sin²(θ)            v_0 is the initial velocity
 h = ──────────────────          θ is the initial launch angle
            2g                   g is the gravity force (9.1)

Since you know the desired height (1.5), the initial launch angle (90° : straight up => sin²(90°) = 1), you can deduce the initial velocity:

 v_0 = √( 1.5 * 2g )

Pretty simple example of code to make your object jump 1.5 units above it when jumping:

public float JumpHeight = 1.5f;
private float verticalSpeed;
private bool grounded = true;
private Rigidbody2D rigidbody2D;

void Start()
{
    rigidbody2D = GetComponent<Rigidbody2D>();
}

void Update()
{
    if( grounded && Input.GetKeyDown(KeyCode.Space) )
    {
        verticalSpeed = Mathf.Sqrt(-2 * JumpHeight * Physics.gravity.y);
    }
}
void FixedUpdate()
{
    if( verticalSpeed > Mathf.Epsilon )
    {
        rigidbody2D.velocity += Vector2.up * verticalSpeed;
        verticalSpeed = 0;
        grounded = false;
    }
}

private void OnCollisionEnter2D(Collision2D collision)
{
    grounded = true;
}

To prevent collision between objects use layers instead of tags : Unity - Manual: Layer-based collision detection

rb.MovePosition may not be the best way to go about this.


Try this; first make a variable called distance and set it to that 1.5f value you want.

then, wherever you are calling rb.MovePosition, do this instead:

transform.Translate(0, distance, 0);

Not tested, I might need to work on that, but if you try it and it does not work, let me know and I will figure it out for you when I have access to Unity.