Achieving the feel of "translate" while setting velocity.

Hey all, I’m toying around with a 2D character controller, and I have a question concerning setting velocity. I liked the instantaneous stopping and starting of using transform.translate, but it got problematic when I tried translating into walls. Setting the velocity took care of that, and movement started immediately.
The problem I have is that stopping isn’t instantaneous. Even after I let go of a movement key, the player continues to slide for a distance before stopping, even though I tried to take care of it in the code. Could anyone advise on how immediate stopping could be achieved, and why my current code does not work as expected? Any help is appreciated.

I’ll post the controller below because the formatting is strange when creating the thread.

Here is the controller.

public class player_script : MonoBehaviour {
    public float maxSpeed = 5f;
    public float jumpForce = 700f;
    private Rigidbody2D myRigid;
    private bool grounded = false;

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

    void FixedUpdate () {
        float move = Input.GetAxis("Horizontal");
        float jump = Input.GetAxis("Vertical");

        if(jump > 0 && grounded)
        {
            grounded = false;
            myRigid.AddForce(new Vector2(0, jumpForce));
        }

        if (move > 0)
        {
            myRigid.velocity = new Vector2(maxSpeed, myRigid.velocity.y);
        }
        else if (move < 0)
        {
            myRigid.velocity = new Vector2(-maxSpeed, myRigid.velocity.y);
        }
        else
        {
            myRigid.velocity = new Vector2(0, myRigid.velocity.y);
        }
    }

    void OnCollisionEnter2D(Collision2D col)
    {
        if (col.gameObject.tag == "ground")
            grounded = true;
    }
}

Calculate the position you want to move to per fixed-update and simply use Rigidbody2D.MovePosition. This will calculate the velocity required to move the body to the specified position in a single update. It does this internally, the body won’t have its velocity adjusted. The body will also collide normally so will stop at ‘walls’. It is also compatible with body interpolation for smooth movement per-frame.

2 Likes

Thank you for the advice. MovePosition works very well. In case anyone has a similar problem finds this in the future, I will also add that using GetAxis like I did was not the right approach, because the return value can remain above 0 even after a key is released.

That’s a feature. :slight_smile: But yeah, if it’s not a feature you want, then you should use GetAxisRaw instead.