How to start a coroutine with WaitForSeconds on key down?

I’m using the below code in an attempt to create a simple camera zoom. If the player presses Left Control it should smoothly zoom out or in but it doesn’t work. I assume this is because it stops running the coroutine on the next update frame but I’m not sure how to correct it.

What am I doing wrong?

void FixedUpdate(){
        //Zoom
        if(Input.GetKeyDown(KeyCode.LeftControl)){
            if(zoomedOut){
                StartCoroutine(ZoomIn());
            }else{
                StartCoroutine(ZoomOut());
            }
        }
}

IEnumerator ZoomOut(){
    t += Time.deltaTime / .4f;
    cinecam.m_Lens.OrthographicSize = Mathf.Lerp(13.0f, 30.0f, t);
    yield return new WaitForSeconds(3);
    zoomedOut = true;
    Debug.Log("zoomed out");
    lastZoomTime = Time.time;
}

IEnumerator ZoomIn(){
    t += Time.deltaTime / .4f;
    cinecam.m_Lens.OrthographicSize = Mathf.Lerp(30.0f, 13.0f, t);
    yield return new WaitForSeconds(3);
    zoomedOut = false;
    Debug.Log("zoomed in");
    lastZoomTime = Time.time;
}

Maybe it’s because the StartCoroutine() function is called multiple times. I think you can try adding another bool value and use Update() instead of FixedUpdate() to make sure it won’t happen. Here is an example:

bool coroutineCalled; 
void Update(){
         //Zoom
         if(Input.GetKeyDown(KeyCode.LeftControl) && !coroutineCalled){
             if(zoomedOut){
                 StartCoroutine(ZoomIn());
                 coroutineCalled = true;
             }else{
                 StartCoroutine(ZoomOut());
                 coroutineCalled = true;
             }
         }
 }

and remember to add “coroutineCalled = false;” at the end of each IEnumerator.
Hope it helps!

It seems you don’t understand how coroutines work and I invite you to read the documentation again.

Here is a suggested rework of your code:

// You don't need FixedUpdate here since you aren't dealing with Physics
void Update(){
    if(Input.GetKeyDown(KeyCode.LeftControl)){
        StopAllCoroutines();
        zoomedOut = !zoomedOut;
        if(zoomedOut){
            StartCoroutine(Zoom(30, 3));
        }else{
            StartCoroutine(Zoom(13, 3));
        }
    }
}
IEnumerator Zoom(float targetSize, float duration){
    float initialSize = cinecam.m_Lens.OrthographicSize;
    for(float t = 0 ; t < duration ; t += Time.deltaTime)
    {
        cinecam.m_Lens.OrthographicSize = Mathf.Lerp(initialSize, targetSize, t / duration);
        yield return null;
    }
    lastZoomTime = Time.time;
}