Dolly zooms are cool. I watched some TV show today that used it and instantly wanted to figure out how to do it. Thankfully, it’s not that hard! Simple trigonometry (seriously). I put together a demo place that utilizes the cool effect. I unlocked the place too!
For those that don’t know what a dolly zoom is, it’s when the camera’s field-of-view “zooms” in on the subject, but the subject’s size doesn’t change. You do this by adjusting both the FOV and the camera’s distance from the subject.
Here’s the math that I worked out quickly:
Angle
A
is where the camera is. Side b
is the distance from the camera to the subject. Side a
is a pre-determined width from the subject to the edge.
When we change the Field Of View, we calculate side b
from the constant side a
, which gives us our cool dolly zoom effect.
Here's the code to it
(Refer to my math above for references to variable names)
local cam = game.Workspace.CurrentCamera
cam.CameraType = Enum.CameraType.Scriptable
local origin = game.Workspace.Part1
local focus = game.Workspace.Part2
origin.Transparency = 1
focus.Transparency = 1
local b = (origin.Position - focus.Position).Magnitude
local a = b * math.tan(math.rad(cam.FieldOfView * 0.5))
local tanOfA = math.tan(math.rad(cam.FieldOfView * 0.5))
-- Angle and distance calculations:
cam.Changed:Connect(function(property)
if (property == "FieldOfView") then
tanOfA = math.tan(math.rad(cam.FieldOfView * 0.5))
b = a / tanOfA
end
end)
-- Continuous camera update:
game:GetService("RunService"):BindToRenderStep("Test", Enum.RenderPriority.Camera.Value, function()
local pos = focus.Position + (CFrame.new(focus.Position, origin.Position).lookVector * b)
cam.CFrame = CFrame.new(pos, focus.Position)
end)
Now it will calculate the correct distance when the FieldOfView property is changed.
Note: I imagine someone else has probably done this before, but I haven’t seen a post about it here before, so I figured I’d post this anyway.