I’ve been trying for a week straight to implement a zoom function to my custom camera but nothing works. I don’t want to use FOV because that looks weird.
In theory, how should I implement a zoom function?
I’ve been trying for a week straight to implement a zoom function to my custom camera but nothing works. I don’t want to use FOV because that looks weird.
In theory, how should I implement a zoom function?
In theory that should work, but there’s much more complex math behind that. You don’t want it to zoom the exact same way in every angle. Like you can’t just say camera.CFrame + Vector3.new(2, 2, 2).
Read a post about animating a camera. You can read it and make use of it in a way. I have not tried it myself but I think it will help you.
The math isn’t that much more complex. You just take the targetPos + (targetPos - cameraPos).Unit * zoomDistance. That accounts for every angle assuming the camera is initially in the correct place since you are effectively just moving the camera back further along the axis it already is on.
I have made systems in the past that use curves to describe a more complex camera path to take with the zoom, but further modifications depend heavily on your exact intent.
Is the RunService function not allowing the camera to zoom or is it some other problem, because it never wants to change the CFrame of the camera no matter what I try
local NormalCamera = {}
local Players = game:GetService("Players")
local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local camera = workspace.CurrentCamera
local player = Players.LocalPlayer
local cameraOffset = Vector3.new(2, 2, 8)
local MIN_ZOOM = 1
local MAX_ZOOM = 20
camera.CameraType = Enum.CameraType.Scriptable
local isMouseButtonDown = false
local sensitivity = 0.1
local cameraAngles = require(script.Parent.CameraAngles)
local function BaseDefaultCamera(character)
if not character then
return
end
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local function playerInput(actionName, inputState, inputObject)
if inputObject.UserInputType == Enum.UserInputType.MouseButton2 then
isMouseButtonDown = inputState == Enum.UserInputState.Begin
if isMouseButtonDown then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
else
isMouseButtonDown = false
UserInputService.MouseBehavior = Enum.MouseBehavior.Default
end
end
end
RunService:BindToRenderStep("CameraUpdateN", Enum.RenderPriority.Camera.Value, function()
if isMouseButtonDown then
cameraAngles.cameraAngleX -= UserInputService:GetMouseDelta().X * sensitivity
cameraAngles.cameraAngleY = math.clamp(cameraAngles.cameraAngleY - UserInputService:GetMouseDelta().Y * sensitivity, -75, 75)
end
local startCFrame = CFrame.new(rootPart.CFrame.Position) * CFrame.Angles(0, math.rad(cameraAngles.cameraAngleX), 0) * CFrame.Angles(math.rad(cameraAngles.cameraAngleY), 0, 0)
local cameraCFrame = startCFrame:PointToWorldSpace(cameraOffset)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(cameraOffset.X, cameraOffset.Y, -100000))
camera.CFrame = CFrame.lookAt(cameraCFrame, cameraFocus)
end)
local function Zoom(actionName, inputState, input)
local scrollDelta = input.Position.Z
local zoomDistance = (camera.CFrame.Position - camera.Focus.Position).Magnitude
zoomDistance = zoomDistance + scrollDelta
zoomDistance = math.clamp(zoomDistance, MIN_ZOOM, MAX_ZOOM)
camera.CFrame = CFrame.new(camera.Focus.Position + (camera.CFrame.Position - camera.Focus.Position).Unit * zoomDistance)
end
ContextActionService:BindAction("PlayerInputN", playerInput, false, Enum.UserInputType.MouseButton2, Enum.UserInputType.Touch)
ContextActionService:BindAction("Zoom", Zoom, false, Enum.UserInputType.MouseWheel)
end
function NormalCamera.NormalCamera()
local character = player.Character
if character then
BaseDefaultCamera(character)
else
player.CharacterAdded:Connect(function(char)
BaseDefaultCamera(char)
end)
end
end
function NormalCamera.ReleaseNormCam()
ContextActionService:UnbindAction("PlayerInputN")
RunService:UnbindFromRenderStep("CameraUpdateN")
end
return NormalCamera
I’ve just noticed. When I walk and try to scroll it rotates my character for some reason
The best solution is to adjust the FOV. I’m not sure what application you’re using where physically moving the camera forward is better.
Doing anything else and you’ll have to take into account the static perspective, which doesn’t feel natural for most zooming applications.
Zooming is just decreasing the camera angle.
Since you have a set camera with a set FOV this becomes more complicated.
“width” is our target screen width, let’s set it to an arbitrary number for now, you should tweak it to your liking when implementing.
tan(camFov) * camD = width/2
camD = width/2 / tan(camFov)
tan(zoomFov) * zoomD = width/2
zoomD = width/2 / tan(zoomFov)
d = zoomD - camD
d is how far you need to shift your camera forward from the original position to achieve the desired zoom angle.
-- put script in character as a local script
local function getZoomDistance(zoomFOV, width)
-- NOTE: zoomFOV must be less than the camera's FOV or you will receive a negative number
local camFOV = workspace.CurrentCamera.FieldOfView
zoomFOV = math.rad(zoomFOV) -- convert to radian
camFOV = math.rad(camFOV)
local camD = width / 2 / math.tan(camFOV)
local zoomD = width / 2 / math.tan(zoomFOV)
return zoomD - camD
end
local humanoidRoot = script.Parent.PrimaryPart
workspace.CurrentCamera.CameraType = "Scriptable"
local n = 0
game["Run Service"].RenderStepped:Connect(function(dt)
n = (n + dt/5) % 1
local zoomValue = math.sin(n * math.pi * 2) * 32.5 + 37.5 -- smoothly slide between 5 and 70 every 5 seconds
print(zoomValue)
workspace.CurrentCamera.CFrame = humanoidRoot.CFrame * CFrame.new(0,0,-2) * CFrame.new(0,0,-getZoomDistance(zoomValue, 10))
end)
Good luck!
Nice post, I was going to say, how do you expect to zoom without FOV since that is basically the definition of zoom.
It depends on what zoom is defined as by the OP. The definition is a bit ambiguous right now until we know what he’s using it for. He mentions that he doesn’t want to use FOV but still wants the effects of zooming. My interpretation is that he’s looking to see things far away without changing the FOV/perspective.
Yeah, FOV is the defenition of the zoom. But the FOV that the roblox has works in a weird way. So i’m kind of looking to replicate the default roblox zoom function since I made a custom camera for the character. It works the exact same way the normal roblox camera works but I just can’t implement the zoom function.
Can you provide an example or a video of what you’re looking for?
Seems like he is trying to make his own ‘I’ ‘O’ (keyboard) or mouse scroll wheel effect. That isn’t really a zoom that is just moving the camera back or into the character’s head.
I was just about to get a video, but this is what I’m trying to do
Maybe change the title to ‘implementing a 3rd person to 1st person view control’ or something, idk
Yeah, but it is basically a zoom function, it zooms in on the character’s head
Thx for the help but i’ve found how to do it
local function Zoom(a,b, input)
local zoomAmount = input.Position.Z * ZOOM_SPEED
local newZoom = math.clamp(cameraOffset.Z - zoomAmount, MIN_ZOOM, MAX_ZOOM)
cameraOffset = Vector3.new(cameraOffset.X, cameraOffset.Y, newZoom)
end
ContextActionService:BindAction("Zoom", Zoom, false, Enum.UserInputType.MouseWheel)
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.