/// Autofocus on target public static void Autofocus(Camera cam, Transform target, bool useColliderDistance = true) { #if HAZE_POSTPROCESSING if (cam == null) { cam = Camera.main; } if (target == null) { Debug.LogWarning("Cannot focus on anything; target is null."); return; } Collider targetColl = null; if (useColliderDistance) { targetColl = target.GetComponent <Collider>(); } float currentDistance = distanceToTarget(cam.transform, target, targetColl); //set depth of field focus distance if we have post processing stack PostProcessingBridge.SetDepthOfField_FocusDistance(currentDistance, cam); #endif }
/// Alternatively use this from a MonoBehaviour as: StartCoroutine(DollyZoom.play(Camera.main, ...)); /// Or within another IEnumerator: yield return DollyZoom.play(Camera.main, ...); public static IEnumerator play(Camera cam, Transform target, float distance, Easing easing = null, float time = 1, bool useColliderDistance = false, bool useFixedDeltaTime = false, bool modifyDepthOfField = false, bool lookAt = false, UnityEvent onEnd = null) { if (easing == null) { easing = Easing.Linear; } if (cam == null) { cam = Camera.main; } // checks if (!target) { Debug.LogWarning("Cannot execute dolly zoom; target is null."); yield break; } // cache Transform camT = cam.transform; float oneOverTime = 1.0f / time; Vector3 initialPosition = camT.position; Collider targetColl = null; if (useColliderDistance) { targetColl = target.GetComponent <Collider>(); } float initialDistance = distanceToTarget(camT, target, targetColl); float initialHeight = frustumHeight(initialDistance, cam.fieldOfView); for (float elapsed = 0; elapsed < time; elapsed += (useFixedDeltaTime ? Time.fixedDeltaTime : Time.deltaTime)) { easing.T = elapsed * oneOverTime; //move camera in/out float distanceMoved = distance * easing.T; camT.position = camT.forward * distanceMoved + initialPosition; //get current distance to target float currentDistance = distanceToTarget(camT, target, targetColl); //modify fov cam.fieldOfView = fov(initialHeight, currentDistance); //set depth of field focus distance if we have post processing stack if (modifyDepthOfField) { PostProcessingBridge.SetDepthOfField_FocusDistance(currentDistance, cam); } if (lookAt) { LookAt.Look(cam, target, 0, false, false); } yield return(null); } if (onEnd != null) { onEnd.Invoke(); } }
/// Or, if you want to keep the effect while moving the camera yourself from somewhere else /// Use as StartCoroutine(DollyZoom.playNoMovement(Camera.main, ...); /// (Don't yield return DollyZoom.playNoMovement(Camera.main, ...) as you will not be able to stop it). public static IEnumerator playNoMovement(Camera cam, Transform target, bool useColliderDistance = false, bool modifyDepthOfField = false, bool lookAt = false) { if (cam == null) { cam = Camera.main; } //checks if (!target) { Debug.LogWarning("Cannot execute dolly zoom; target is null."); yield break; } // cache Transform camT = cam.transform; Collider targetColl = null; if (useColliderDistance) { targetColl = target.GetComponent <Collider>(); } //get initial distance to target float initialDistance = distanceToTarget(camT, target, targetColl); float initialHeight = frustumHeight(initialDistance, cam.fieldOfView); while (true) { //get current distance to target float currentDistance = distanceToTarget(camT, target, targetColl); //modify fov cam.fieldOfView = fov(initialHeight, currentDistance); //set depth of field focus distance if we have post processing stack if (modifyDepthOfField) { PostProcessingBridge.SetDepthOfField_FocusDistance(currentDistance, cam); } if (lookAt) { LookAt.Look(cam, target, 0, false, false); } yield return(null); } }