Dolly Zoom is the well-known visual effect where the camera simultaneously moves towards a target object and zooms out from it. The result is that the object appears roughly the same size but all the other objects in the scene change perspective. Done subtly, dolly zoom has the effect of highlighting the target object, since it is the only thing in the scene that isn’t shifting position in the image. Alternatively, the zoom can be deliberately performed quickly to create the impression of disorientation.
An object that just fits within the frustum vertically will occupy the whole height of the view as seen on the screen. This is true whatever the object’s distance from the camera and whatever the field of view. For example, you can move the camera closer to the object but then widen the field of view so that the object still just fits inside the frustum’s height. That particular object will appear the same size onscreen but everything else will change size as the distance and FOV change. This is the essence of the dolly zoom effect.
Creating the effect in code is a matter of saving the height of the frustum at the object’s position at the start of the zoom. Then, as the camera moves, its new distance is found and the FOV adjusted to keep it the same height at the object’s position. This can be accomplished with the following code:
using UnityEngine;
using System.Collections;
public class ExampleScript : MonoBehaviour {
public Transform target;
public Camera camera;
private float initHeightAtDist;
private bool dzEnabled;
// Calculate the frustum height at a given distance from the camera.
void FrustumHeightAtDistance(float distance) {
return 2.0f * distance * Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
}
// Calculate the FOV needed to get a given frustum height at a given distance.
void FOVForHeightAndDistance(float height, float distance) {
return 2.0f * Mathf.Atan(height * 0.5f / distance) * Mathf.Rad2Deg;
}
// Start the dolly zoom effect.
void StartDZ() {
var distance = Vector3.Distance(transform.position, target.position);
initHeightAtDist = FrustumHeightAtDistance(distance);
dzEnabled = true;
}
// Turn dolly zoom off.
void StopDZ() {
dzEnabled = false;
}
void Start() {
StartDZ();
}
void Update () {
if (dzEnabled) {
// Measure the new distance and readjust the FOV accordingly.
var currDistance = Vector3.Distance(transform.position, target.position);
camera.fieldOfView = FOVForHeightAndDistance(initHeightAtDist, currDistance);
}
// Simple control to allow the camera to be moved in and out using the up/down arrows.
transform.Translate(Input.GetAxis("Vertical") * Vector3.forward * Time.deltaTime * 5f);
}
}
C# script example
var target: Transform;
private var initHeightAtDist: float;
private var dzEnabled: boolean;
// Calculate the frustum height at a given distance from the camera.
function FrustumHeightAtDistance(distance: float) {
return 2.0 * distance * Mathf.Tan(camera.fieldOfView * 0.5 * Mathf.Deg2Rad);
}
// Calculate the FOV needed to get a given frustum height at a given distance.
function FOVForHeightAndDistance(height: float, distance: float) {
return 2 * Mathf.Atan(height * 0.5 / distance) * Mathf.Rad2Deg;
}
// Start the dolly zoom effect.
function StartDZ() {
var distance = Vector3.Distance(transform.position, target.position);
initHeightAtDist = FrustumHeightAtDistance(distance);
dzEnabled = true;
}
// Turn dolly zoom off.
function StopDZ() {
dzEnabled = false;
}
function Start() {
StartDZ();
}
function Update () {
if (dzEnabled) {
// Measure the new distance and readjust the FOV accordingly.
var currDistance = Vector3.Distance(transform.position, target.position);
camera.fieldOfView = FOVForHeightAndDistance(initHeightAtDist, currDistance);
}
// Simple control to allow the camera to be moved in and out using the up/down arrows.
transform.Translate(Input.GetAxis("Vertical") * Vector3.forward * Time.deltaTime * 5);
}
JS script example
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Is something described here not working as you expect it to? It might be a Known Issue. Please check with the Issue Tracker at issuetracker.unity3d.com.
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thanks for helping to make the Unity documentation better!