Using time based coroutine not working properly when I start multiple coroutines

Hey there! I have a strange question regarding coroutines. (Code and images provided below.)

The issue I’m having is as follows. I have multiple menu items (Canvases) in my scene. I have them sitting offscreen and when I click a corresponding button I want them to drop down onto the screen. When I click the button again I want it to leave the screen. This part seems to be functional.

The problem comes in, when I click a different button, I want to move that canvas onto the screen while simultaneously moving the active one off of the screen. But when I try to move multiple objects, they seem to be getting… stuck.

I am currently using a coroutine as I have found the code to be quite clean. However, I have also attempted to make it work in Update(), with no success. I have also attempted to use differently named coroutines, while loops, and mathf.lerp instead of smoothdamp.

The strangest thing is, if I move the yield return outside of the for loop, everything works fine, however instead of smoothly moving to a location, the canvases move instantly. But if it is inside the for loop, I get smooth movement, but when I try to move multiple canvases they don’t move at all.

Any help, comments, or insights would be much appreciated!

[SerializeField]
List<Canvas> menuScreens = new List<Canvas>();

public Transform onScreenTarget;
public Transform offScreenTarget;
public float time = 1.0f;
public float smoothValue = 0.2f;
private Vector3 velocity = Vector3.zero;
public int enabledMenu = -1;

private void Start() {
    // Set each of the menu panels to a starting location
    foreach(Canvas menuItem in menuScreens){
        menuItem.transform.position = offScreenTarget.transform.position;
    }
}
public void SetMenuScreen(int index){
    if(index == enabledMenu){
        // run the coroutine moving item off the screen.
        StartCoroutine(MenuAnimation(enabledMenu, time, offScreenTarget));

        enabledMenu = -1;
    }
    else{
        //Run the coroutine moving item on the screen.
        StartCoroutine(MenuAnimation(index, time, onScreenTarget));

        // If a different menu already active, run the coroutine to move the active menu off the screen.
        if(enabledMenu >= 0){
            StartCoroutine(MenuAnimation(enabledMenu, time, offScreenTarget));
        }

        enabledMenu = index;
    }

}

private IEnumerator MenuAnimation(int index, float time, Transform target){
    Canvas menuItem = menuScreens[index];
    for(float i = 0; i <= time; i += Time.deltaTime){
        menuItem.transform.position = Vector3.SmoothDamp(
            menuItem.transform.position,
            target.position,
            ref velocity,
            smoothValue
        );
        yield return null;
    }

}

Some pictures for reference The first picture is the scene after pressing one button. The second is the scene after pressing a different button.

Okay, so I figured it out. Going to post the solution here in case someone has a similar issue one day.

The velocity variable needs to be set INSIDE of the coroutine. Because smoothdamp sets the velocity as it goes. And by only giving it one variable, when two coroutines try to change it, the velocity ends up all over the place.

The new coroutine looks like this:

private IEnumerator MenuAnimation(int index, float time, Transform target){
        Vector3 velocity = Vector3.zero;
        Canvas menuItem = menuScreens[index];

        for(float i = 0; i <= time; i += Time.deltaTime){
            menuItem.transform.position = Vector3.SmoothDamp(
                menuItem.transform.position,
                target.position,
                ref velocity,
                smoothValue
            );
            yield return null;
        }

    }