- Home /
Why does this IF statement loop without finishing?
I have the following code which I use to zoom in and out the main camera with the scroll wheel:
private void Zoom()
{
isZoomLerping = true;
originalPosition = transform.position;
finalPosition = transform.position;
position = transform.position;
timeStartedLerping = Time.time;
scrollCheck = Input.GetAxis("Mouse ScrollWheel");
// Zoom in
if (Input.GetAxis("Mouse ScrollWheel") > 0)
{
finalPosition.y -= scrollSensitivity;
}
// Zoom out
if (Input.GetAxis("Mouse ScrollWheel") < 0)
{
finalPosition.y += scrollSensitivity;
}
}
In order to make the zooming smooth, I have two versions of code that are executed in FixedUpdate which lerps a vector that I am trying to understand:
VERSION 1:
if (isZoomLerping == true)
{
float timeSinceStarted = Time.time - timeStartedLerping;
float percentageComplete = timeSinceStarted / timeToZoom;
Debug.Log(percentageComplete);
position = Vector3.Lerp(originalPosition, finalPosition, percentageComplete);
position.y = Mathf.Clamp(position.y, endCameraPosition.position.y, startCameraPosition.position.y);
transform.position = position;
if (percentageComplete >= 1.0f)
{
isZoomLerping = false;
Debug.Log(isZoomLerping);
}
VERSION 2:
if (isZoomLerping == true)
{
StartCoroutine(ZoomLerp(originalPosition, finalPosition, timeToZoom));
}
IEnumerator ZoomLerp(Vector3 startPosition, Vector3 endPosition, float zoomTime)
{
float startTime = Time.time;
float endTime = startTime + zoomTime;
while (Time.time < endTime)
{
float timeProgressed = (Time.time - startTime) / zoomTime;
position = Vector3.Lerp(startPosition, endPosition, timeProgressed);
position.y = Mathf.Clamp(position.y, endCameraPosition.position.y, startCameraPosition.position.y);
transform.position = position;
yield return null;
}
isZoomLerping = false;
}
VERSION 1 is from this website. I can't remember where I got VERSION 2.
The code from VERSION 1 works well, VERSION 2 not so much. Whenever I scroll back and forth too fast with VERSION 2 the camera jitters back and forth. Are the values of startPosition and endPosition changing midway through the coroutine? Is this the reason why it jitters?
VERSION 1, on the other hand, works perfectly fine even if I scroll back and forth too fast, but I don't know why. I stuck a Debug.Log to check the values of percentageComplete and it seems that even before percentageComplete == 1 and exits the IF statement, whenever I move the scroll wheel the IF statement restarts? I thought that unless percentageComplete == 1 (i.e isZoomLerping == false) then the IF statement has to continue before Unity can do something else with the zoom?
I am quite new to C# and Unity so apologies if the answer seems obvious.
EDIT: I think I understand whats happening in VERSION 1 now. In the UPDATE section I've got the following code:
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
Zoom();
}
So the instance I use the scroll wheel, the variables in Zoom() change however, the values in VERSION 1's code do not change yet in this frame. It is only once FixedUpdate() is executed in the next frame do the values in VERSION 1 get reflect the changes made in Zoom() from the previous frame so when Unity runs through the IF statement it looks like IF statement is reset before completing. Is this thinking correct?
For VERSION 2, I admit that I don't have much understanding of coroutines. I've changed 'yield return null' to 'yield return new WaitForFixedUpdate' just to see what happens and the camera zoom no longer jitters however it kind of freezes in place if I scroll too fast. Is this because of the yield return ___? I have the feeling that using a coroutine is wrong here...