- Home /
How to do perspective camera zoom?
We have a perspective camera looking at a cube that scales (increasing and decreasing) almost every frame.
The goal is that no matter the scaling of the rectangle we will always see it near the borders as the camera will dynamically adjust itself. When its scale/size is inside of the screen the camera should zoom in and when its scale/size is outside of the screen the camera should zoom out.
To adjust the camera on the cube, we tried to set the field of view (both vertically and horizontally) and we also tried to translate the camera by calculating the distance between the camera and the cube. In both cases we find it difficult to do and we have a little issue where the camera is jumping temporary between bool IsInSceen() when the cube is not scaling. So we would like a little help.
Depending on the size change you might wanna change the fov value of the camera with a specific value like 1.6 times more or less?
Answer by robertbu · Aug 13, 2014 at 11:14 PM
You will find the calculations for a perspective camera here:
http://docs.unity3d.com/Manual/FrustumSizeAtDistance.html
With a bit of algebra, you can solve for whatever you need to...adjust the FOV or move the camera. There are some open questions about exactly what you need from your description. So I'm going to give you a bit of simple starter code for a restricted situation. Let's assume:
The block has some 'z' depth
The block is always taller than the aspect ratio of the camera (i.e. it is the height of the cube that determines the camera zoom.
Zoom is done though movement, not changing the FOV.
The camera is at (0,0,-something) with a rotation of (0,0,0).
The cube is centered in the camera
Here is a bit of code. Start a new scene, attach the script below. Run the app and modify the size of the block in the Inspector.
#pragma strict
function Update() {
var frustumHeight = transform.localScale.y;
var distance = frustumHeight * 0.5 / Mathf.Tan(Camera.main.fieldOfView * 0.5 * Mathf.Deg2Rad);
// Since front side of the block is not at pivot
distance += transform.localScale.z * 0.5;
Camera.main.transform.position = Vector3.back * distance;
}
Using camera movement is almost never used to implement a zoom function. That's simply because you would easily glitch through near objects. Almost all games i know (mainly FPS games) change the FOV to zoom in or out. A movement approach might work for games with a fix camera like RTS games with a top-down / iso camera, but for anything more dynamic you usually want to use the FOV ins$$anonymous$$d.
Thank you robertbu. I'll go with the fov coding. That's a pretty cool link you shared with us. Thank you. We'll start to work with it and we will give you some feedback when it's done.
Thank you Bunny83 for the comment. You are right. And besides, the clipping planes issue is not only for near objects but also for the ones far away especially with an angle to the camera.
@Bunny83 - good to know:
@axCed - a bit of example code with the same restrictions as the previous that zooms using field of view:
#pragma strict
function Update() {
var frustumHeight = transform.localScale.y;
var distance = $$anonymous$$athf.Abs(transform.position.z - Camera.main.transform.position.z) - transform.localScale.z * 0.5;
Camera.main.fieldOfView = 2.0 * $$anonymous$$athf.Atan(frustumHeight * 0.5 / distance) * $$anonymous$$athf.Rad2Deg;
}
Your criteria is fuzzy, so I expect you'll have to do more, but this will get you started.