- Home /
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;
}
Answer by Hellium · May 11, 2021 at 12:54 PM
It seems you don't understand how coroutines work and I invite you to read the documentation again.
https://docs.unity3d.com/Manual/Coroutines.html
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;
}
Answer by eneIr · May 11, 2021 at 11:27 AM
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!
Your answer
Follow this Question
Related Questions
Can't figure out While Loop crash? 1 Answer
Yield WaitForSeconds not working > once in coroutine 1 Answer
How to spawn evenly spaced game objects and move them in a circular path? 1 Answer
How to ''stack'' coroutines, and call each one till all are executed? 5 Answers
Coroutine not running to end? 1 Answer