I’m at work right now, so I can’t go in to much detail and the examples will look dirty, and please excuse any errors 
You could try to store the destination position where the roll will end, and use a timer to periodically move the player towards the destination.
You’ll also need a timer of some sort to determine the roll duration, and the step lengths.
As for collisions, you should probably Raycast on the updates based on the distance you are ABOUT to move the player, if it collides, move player on that position and stop the roll. If you’re new, raycast usage might seem a little bit complicated at first (it was for me), but it’s worth to look in to as you will end up using it in almost every situation when dealing with movement, guns, etc.
if (rolling)
rb.MovePosition(Vector3.MoveTowards(transform.position, target.position, step));
//you can change Vector3 to Vector2 reference but generally it doesn't matter, just looks //prettier depending on if project is 2d or 3d.
And determine step by
//distance should be the total distance you want your roll to be. You said you want 3 units, so 3f maybe.
//rollDuration should be, well... the max roll duration!
float step = distance * time.DeltaTime * rollDuration;
You also need to take note the time elapsed, and a checker for movement with a bool;
float timer = 1f;
float originalTimer = 1f;
bool rolling;
...
.
.
.
...
void Update(){
if (!rolling){
return;
}
//some movement logic here maybe?
...
.
.
.
...
timer -= time.deltaTime;
if (timer <= 0){
rolling = false;
//here you could do some stuff to lock the player in to the intended position maybe?
timer = originalTimer;
}
}
I hope I could at least point you to the right direction.
EDIT: damn spam filter??