In this era of visual scripting and drag/drop development, sometimes the base fundamentals are lost and forgotten.
In this example I'll show a simple camera zoom script which functions in a similar way to some games I've seen released on Steam, as well as some improvements adding better functionality using a good old friend - trigonometry :)
Here we have a basic zoom function which smoothly raises the camera height using the SmoothDamp function. From watching the video, straight away something just 'feels' off about this zoom mechanic.
This feeling is caused by expecting the target point at the center of the view to be kept in frame while zooming and the camera having a view angle which is not directly looking down. Instead, the focus point is changing with the camera height, causing the player to then move the camera forward to get back to the point of interest. I have seen this numerous times, specifically in resource management sim games on Steam which tend to use a perspective camera looking at a downwards angle.
What We Need
Rather than raising and lowering the camera height directly, we need to move the camera along it's forward vector which will give the expecting feeling of zoom.
But exactly how much do we move it by? Using a little bit of trigonometry we can find out!
Let's flatten out our camera and draw some lines to see what we're dealing with...
In diagram #1, we see the camera is pointing downwards at a 45 degree angle with it's height set to 5 units. If we draw some straight lines from the camera position to the ground, and the camera position along it's view vector - we get a triangle!
Using the above script for zooming, we are simply moving the camera in the Y axis only.
Diagram #2 now shows the camera's new height at 3, and in turn - a new look direction and target point.
Clearly the new look target does not match the previous look target. In order to keep the target in frame, we need to adjust the new camera position in the X axis by the xDifference shown.
In diagram #3, if we slide xDifference up along the look direction vectors until it hits the edge formed by the camera height, we see it now forms a new triangle.
So - to keep our camera aligned with our view target, we need to shift it in the X axis by the value of xDifference.
We know the angle of our camera and we know the length of HeightDiff. Calling on our knowledge from SOH-CAH-TOA - we can solve xDifference!
Since we have our adjacent edge (HeightDiff) and are solving our opposite edge from our angle (xDifference), we need help from TOA to solve - so our formula is....
And here we have it! A zoom which correctly moves along the view vector using good old fashioned math!
Note, the above change could also be written with camPos = transform.TransformPoint(Vector3.forward * lengthDiff); however I wanted to show what is actually happening.
Using this knowledge, the same formula could be used to do something like make the camera zoom to where the mouse is pointing - see if you can work it out!
The point of this article wasn't so much "how to make a zoom script", rather, don't forget how valuable traditional methods and ways of thinking are.