Moving Rigidbody to specific position over time

Hi there, I’m having some trouble implementing a “dash” move for my rigidbody player controller. I’ve tried a handful of methods and other posted solutions, but I think I’m getting a bit jumbled up between the inputs, Update vs fixedUpdate, using speed and time.(fixed)deltaTime, and the movement system I’m using.

I’m building off of the character controller made by MinionsArt, where movement is controlled by setting rb.velocity directly inside FixedUpdate. I don’t think this is having an effect on the move I’m trying to create, but I figured I’d mention it just in case.

Anyway, what I’m trying to implement is this: when the player holds down the dash key (F) it will show you the final landing location based on your current direction and you will dash to it upon releasing the key.

private void FixedUpdate()
{
dashLocation = transform.position + transform.forward * dashDistance;

        if (Input.GetKeyUp(KeyCode.F))
        {
            Dash();
            Debug.Log("Dashing.");
        }
}

private void Dash()
    {
        //rb.AddForce(transform.forward * dashAmount, ForceMode.Impulse);

        //rb.MovePosition(Vector3.SmoothDamp(transform.position, dashLocation, ref velocity, 1f));

        rb.MovePosition(dashLocation);

    }

private void OnDrawGizmos()
    {
        Gizmos.color = Color.red;
        if (Input.GetKey(KeyCode.F))
        {
            Gizmos.DrawWireSphere(dashLocation, 0.3f);
        }      
    }

Right now, just using rb.MovePosition(dashLocation) is the only thing that slightly works. It moves my rigidbody to the correct place instantaneously. The other two lines I have inside my dash function either only move a tiny bit, or don’t move. However, what I want is for the rigidbody to move to the desired location smoothly over time (ideally a fast time to create a dash effect), or even with a bit of easing in and out at the start and end of the movement. Whenever I try adding any time of deltaTime or fixedDeltaTime * speed, it either barely moves, or completely overshoots the location.

Also, I’m a bit confused about handling inputs and rigidbody movements and what functions to put them in. I know rb physics should go in FixedUpdate, but putting any inputs in fixedUpdate means they don’t always get called when the player presses a button. And what about when all of the implementation exists in a separate function like my Dash() function? Any tips on the best way to handle that?

Any help is greatly appreciated. Thank you!

@fuzzyelves For dash to work smoothly there are number of approaches to do that using rigidbody. I will share one of the solution.

//First make a class boolean variable for dash, next dash location and transform last position.
private bool _isDashing;
private Vector3 nextDashPos, lastPos;
//Make public variable for the dash time 
public float dashTime = 1f; //If you want dash to happen in 1 second. public so you can change it in inspector and check without changing in script.

//If dash timing is more or less than 1 second, then you need to calculate rate
public float rate;
public float progress;
void Start()
{
        //Calculate rate like this. You can add this in update method also so when you make changes in the inspector and press button to dash, this will be calculated again to match your current dash time set in the inspector.
        rate = 1f / dashTime;
        progress = 0f;
}
//Don't check input in FixedUpdate, check it in simple update method like this.
void Update()
{
      if(Input.GetKeyUp(KeyCode.F))
      {
               _isDashing = true;
               nextDashPos = transform.Position + transform.Forward * dashDistance;
               //Reset Progress to 0
               progress = 0f;
               lastPos = transform.position;
               //Optional
               rate = 1f / dashTime;
      }
}
//Update rigidbody in FixedUpdate
void FixedUpdate()
{
      if(_isDashing)
      {
            progress += rate * Time.deltaTime; //Time.deltaTime in fixed update is same as Time.fixedDeltaTime.
            rb.position = Vector3.Lerp(lastPos, nextDashPos, progress);
            //Check if progress greather than or equals to 1 or not.
            if(progress >= 1f)
            {
                  _isDashing = false;
                  rb.Position = nextDashPos; 
            }
      }
}

For smoothing out start and end of the dash, you can use AnimationCurve and evaluate curve value at current progress. Like this,

//Make a class variable type of AnimationCurve;
public AnimationCurve animateCurve;

//and in FixedUpdate make this changes.
rb.position = Vector3.Lerp(lastPos, nextDashPos, animateCurve.Evaluate(progress));

Note that, you need to set animation curve in the inspector window and your animation curve should be like this
207259-screenshot-2023-05-16-at-91903-am.png