Snappy zoom behaviour

I’m trying to have “snappy” zooming when going into first person. When the camera is about ~2 away from the focus, I want it to immediately go to 0.5, instead of the smooth zooming.

local snapped = false
run.RenderStepped:Connect(function()
	local head : BasePart = char.Head
	local dist = (camera.CFrame.Position - head.Position).Magnitude
	
	print(dist)
	
	if dist <= 2 and (not snapped) then
		plr.CameraMaxZoomDistance = 0.5
		plr.CameraMinZoomDistance = 0.5
		
		wait()
		
		plr.CameraMaxZoomDistance = 32
		plr.CameraMinZoomDistance = 0
		
		snapped = true
	end
	
	if dist >= 2 then
		snapped = false
	end
end)

I tried the above, however it’s missing the “snappy” action when zooming out. It works just how I want it to work when zooming in. Any ideas?

3 Likes

i suggest you look into modifying roblox’s cameramodule, more specifically the zoomcontroller inside of it, you can find it in starterplayerscripts during an active studio session

I already modify it to smooth the inputs, I looked into ZoomController but was honestly confused. Do you have any suggestions on how to modify it?

What does the code in there look like?

Expected behavior. First off, do not use RenderStepped; it’s deprecated and should be replaced with a modern equivalent. Second is this one wait call; this causes your code to pause at the heartbeat event, nullifying any benefit from RenderStepped.

Please write your code without using any scheduling functions; PreRender should be more than enough. Also as noted by other people you need to edit the player controllers scripts in order to archive this kind of behavior.

you can change the returned value, this should do it

function Zoom.Update(renderDt: number, focus: CFrame, extrapolation)
		local poppedZoom = math.huge
		
		if zoomSpring.goal > DIST_OPAQUE then
			-- Make a pessimistic estimate of zoom distance for this step without accounting for poppercam
			local maxPossibleZoom = max(
				zoomSpring.x,
				stepTargetZoom(zoomSpring.goal, zoomDelta, cameraMinZoomDistance, cameraMaxZoomDistance)
			)

			-- Run the Popper algorithm on the feasible zoom range, [MIN_FOCUS_DIST, maxPossibleZoom]
			poppedZoom = Popper(
				focus*CFrame.new(0, 0, MIN_FOCUS_DIST),
				maxPossibleZoom - MIN_FOCUS_DIST,
				extrapolation
			) + MIN_FOCUS_DIST
		end

		zoomSpring.minValue = MIN_FOCUS_DIST
		zoomSpring.maxValue = min(cameraMaxZoomDistance, poppedZoom)
		
		return zoomSpring.goal < 2 and MIN_FOCUS_DIST or zoomSpring:Step(renderDt)
	end

however, the zoomcontroller doesnt even determine whether or not the player should be locked in first person, you will have to edit the “currentSubjectDistance” in basecamera

1 Like

Thank you! Marked as solution.

For future readers: I would reccomend also modifying TransaprencyController found inside of the Camera module as it can be slow-to-react causing it to appear as if the transparency is still “fading”.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.