Hello,
I have made an orthographic camera script that if you press and hold the Left Control it zooms out and when release, it returns to its original size.
But if i only tap the Left Control, the camera zooms out but can’t zoom in, i need to cancel the zoom out anytime i release the Left Control.
Here is the snippet:
using UnityEngine;
using System.Collections;
public class cameraController : MonoBehaviour {
public float zoomDuration = 0.5f;
private bool zooming = false;
public Transform target;
public float originalPos;
public float cameraZoom = 250f;
void Start() {
originalPos = Camera.main.orthographicSize;
}
void Update() {
transform.LookAt(target.transform);
if ( !zooming ) {
if(Input.GetKeyDown(KeyCode.LeftControl)) {
StartCoroutine("zoomOut");
}else if(Input.GetKeyUp(KeyCode.LeftControl)){
StartCoroutine("zoomIn");
}
}
}
private IEnumerator zoomIn() {
float deltaT = 0;
zooming = true;
if (Camera.main.orthographicSize <= cameraZoom) {
while ( deltaT < zoomDuration ) {
deltaT += Time.deltaTime;
yield return true;
Camera.main.orthographicSize = Mathf.Lerp(Camera.main.orthographicSize, originalPos, deltaT / zoomDuration);
}
}
zooming = false;
}
private IEnumerator zoomOut() {
float deltaT = 0;
zooming = true;
while ( deltaT < zoomDuration ) {
deltaT += Time.deltaTime;
yield return true;
Camera.main.orthographicSize = Mathf.Lerp(originalPos, cameraZoom, deltaT / zoomDuration);
}
zooming = false;
}
}
You should stop the coroutine which zoomes out before starting the one zooming in so they don’t overlap:
else if(Input.GetKeyUp(KeyCode.LeftControl)) {
StopCoroutine("zoomOut");
StartCoroutine("zoomIn");
}
You’re missing the key up event because zoomOut is running. There are two alternatives: change the logic so that zoomIn is called whenever the camera has zoomed out and the key is not pressed, or forget about coroutines and do the job inside Update. The behaviours are different: in the first case, a complete zoom out/in sequence will be executed when you tap the key, and in the second case the zoom out will will be interrupted when the key is released.
The first alternative (using coroutines) requires an extra boolean and changes in the logic:
bool zoomedOut = false;
void Update() {
transform.LookAt(target.transform);
// zoomOut only if not already zooming or zoomed out:
if (!zoomedOut && !zooming && Input.GetKeyDown(KeyCode.LeftControl)){
StartCoroutine("zoomOut");
}
// zoomIn when zoomed out, not zooming and key not pressed:
if (zoomedOut && !zooming && !Input.GetKey(KeyCode.LeftControl)){
StartCoroutine("zoomIn");
}
}
private IEnumerator zoomIn() {
float deltaT = 0;
zooming = true;
if (Camera.main.orthographicSize <= cameraZoom) {
while ( deltaT < zoomDuration ) {
deltaT += Time.deltaTime;
yield return true;
Camera.main.orthographicSize = Mathf.Lerp(Camera.main.orthographicSize, originalPos, deltaT / zoomDuration);
}
}
zooming = false;
zoomedOut = false; // not zoomed out anymore
}
private IEnumerator zoomOut() {
float deltaT = 0;
zooming = true;
while ( deltaT < zoomDuration ) {
deltaT += Time.deltaTime;
yield return true;
Camera.main.orthographicSize = Mathf.Lerp(originalPos, cameraZoom, deltaT / zoomDuration);
}
zooming = false;
zoomedOut = true; // camera zoomed out
}
The second alternative (no coroutines) is much simpler:
// declare these two new floats:
float targetZoom;
float curZoom;
void Start() {
originalPos = Camera.main.orthographicSize;
// initialize them at Start:
curZoom = targetZoom = originalPos;
}
void Update() {
transform.LookAt(target.transform);
// left control defines the target zoom
if (Input.GetKey(KeyCode.LeftControl)){
targetZoom = cameraZoom;
} else {
targetZoom = originalPos;
}
// if target changed, lerp to it at constant speed:
if (curZoom != targetZoom){
curZoom = Mathf.MoveTowards(curZoom, targetZoom, Time.deltaTime/zoomDuration);
Camera.main.orthographicSize = curZoom;
}
}