1
\$\begingroup\$

I'm rounding the position of an object (the blue cube) when the player stops pushing it using

Rigidbody2D.MovePosition(transform.position,RoundedPosition,lerpValue);

The object slides toward the desired position, and when it reaches it, it stops and then it moves about 0.05 units over the position it stopped.

Here's the script

bool IsPushing = false;
bool RoundingPosition = false;
Vector3 RoundedPos;
public float lerp;
Rigidbody2D PlayerRb;
Rigidbody2D rb;
void Start()
{
    rb = GetComponent<Rigidbody2D>();
    PlayerRb = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
}

Vector3 GetRoundedPos()
{
    return new Vector3(Mathf.Floor(transform.position.x) + 0.5f, Mathf.Floor(transform.position.y) + 0.5f, 0);
}

void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Player"))
    {
        IsPushing = true;
    }
}

void OnCollisionExit2D(Collision2D collision)
{
    if (collision.gameObject.CompareTag("Player"))
    {
        IsPushing = false;
        RoundingPosition = true;
        RoundedPos = GetRoundedPos();
    }
}

void FixedUpdate()
{
    if (IsPushing)
    {
        if (new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical")) == Vector2.zero)
        {
            RoundingPosition = true;
            RoundedPos = GetRoundedPos();
        }
        else
            RoundingPosition = false;
    }

    if (RoundingPosition)
    {
        rb.MovePosition(Vector2.Lerp(transform.position, RoundedPos, lerp));
        if (Vector3.Distance(RoundedPos,transform.position) <= 0.0001f)
        {
            
            RoundingPosition = false;
            IsPushing = false;
            rb.MovePosition(RoundedPos);
        }
    }
}

Demonstration video: Demonstration

\$\endgroup\$
16
  • \$\begingroup\$ I have not used Unity in a very long time, so I can't be specific in what functions/methods you use to move Rigidbody (it's stuff like ApplyForce(x,y,z) and so on). But by doing MovePosition you are most likely overriding the physics engine and just directly changing it's transform->position. You can use things like ApplyForce, or set the Velocity of the Rigidbody instead of just settings its position. \$\endgroup\$ Jun 6, 2023 at 13:24
  • \$\begingroup\$ How would I implement Adding force to it to make it stop at the wanted position smoothly ? \$\endgroup\$ Jun 6, 2023 at 13:26
  • \$\begingroup\$ To be honest, on a grid based game which this looks to be, you are better off handing collision yourself. Simply check if some solid object occupies the space at say "Rounded Position 9,10" and if it does, then you do not allow that particular movement. If you wish to continue dabbling with the Rigidbody stuff, I would say you can set the velocity using your input values (you will also need to set a Max Velocity and if it goes over that you can use Mathf Clamp to lock it to that max. By doing this when it hits the block it should stop. However, again the rb stuff not perfect for this... \$\endgroup\$ Jun 6, 2023 at 13:29
  • \$\begingroup\$ ...it may over-shoot the border of the colliders. To try doing without Rigidbody, Try to do a "pre move" in your code, and check for collision after doing the pre-move. If the is no collision, you then do the physical move. If there is , just deny the move and consume the input value without actually moving your character. \$\endgroup\$ Jun 6, 2023 at 13:30
  • 1
    \$\begingroup\$ Another shot in the dark I'm afraid, but could it be the object is still carrying some velocity? Perhaps try SetVelocity(0,0) at the same time as MovePosition (in the RoundedPos==true) if block. I do doubt this though, because it seems you are not using the rigidbody physics to actually move it, so the Velocity values probably remain at zero the whole time. \$\endgroup\$ Jun 6, 2023 at 13:55

1 Answer 1

1
\$\begingroup\$

It seems like the Rigidbody may have some velocity remaining from the MovePosition calls. Try to add line "rb.velocity=Vector2.Zero;":

if (Vector3.Distance(RoundedPos,transform.position) <= 0.0001f)
        {
            
            RoundingPosition = false;
            IsPushing = false;
            rb.MovePosition(RoundedPos);
            rb.velocity=Vector2.zero;
        }
```
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .