hello guys, basically wanted to make a custom camera for my game, that have the mouse center locked, and make the player’s camera be able to be vertically rotated 90 degrees instead of the default roblox 80 degrees, and yes, i know about the existence of this note:
Note: DotProduct check in CoordinateFrame::lookAt() prevents using values within about 8.11 degrees of the +/- Y axis, that’s why these limits are currently 80 degrees.
but i know that is possible to override that 80 default values with a custom camera script, here’s an example clip of what type of camera exactly i want to make:
To finish my explanation about the custom camera, here is what i have achieved with a script located in starter gui, and disabling the player’s default camera with another script that for the moment i will not show it because it is not necessary.
script:
-- services
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
-- player
local player = game.Players.LocalPlayer
repeat wait() until player.Character
local character = player.Character
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local Humanoid = character:WaitForChild("Humanoid")
-- variables
local CurrentCamera = workspace.CurrentCamera
local cameraRotation = Vector2.new(0, 0) -- horizontal (X) and vertical (Y) rotation
local lastCameraRotation = Vector2.new(0, 0) -- for smooth interpolation
local smoothingFactor = 0.15 -- controls smoothness of camera motion
local cameraOffset = Vector3.new(0, 2, 8) -- offset for third-person view
-- constants
local maxVerticalAngle = math.rad(90) -- 90-degree vertical rotation limit
-- cam's pos and orient
local function updateCamera()
if Humanoid.Health > 0 then
-- mouse center locking
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
local mouseDelta = UserInputService:GetMouseDelta() * 0.01
-- update rot values
cameraRotation = cameraRotation + Vector2.new(-mouseDelta.X, -mouseDelta.Y)
cameraRotation = Vector2.new(cameraRotation.X, math.clamp(cameraRotation.Y, -maxVerticalAngle, maxVerticalAngle))
-- smooth interpolation for the rotation
lastCameraRotation = lastCameraRotation:Lerp(cameraRotation, smoothingFactor)
-- camera pos calculation
local horizontalRotation = CFrame.Angles(0, lastCameraRotation.X, 0)
local verticalRotation = CFrame.Angles(lastCameraRotation.Y, 0, 0)
local rotationCFrame = horizontalRotation * verticalRotation
-- camera new pos calculation
local cameraPosition = HumanoidRootPart.Position - (rotationCFrame.LookVector * cameraOffset.Z) + Vector3.new(0, cameraOffset.Y, 0)
-- update cframe
CurrentCamera.CFrame = CFrame.new(cameraPosition, HumanoidRootPart.Position + Vector3.new(0, cameraOffset.Y, 0))
end
end
-- body rot with cam
local function updateCharacterOrientation()
if Humanoid.Health > 0 then
local lookDirection = CurrentCamera.CFrame.LookVector
local targetOrientation = Vector3.new(lookDirection.X, 0, lookDirection.Z).Unit
-- smooth body rotation
if targetOrientation.Magnitude > 0 then
HumanoidRootPart.CFrame = CFrame.new(
HumanoidRootPart.Position,
HumanoidRootPart.Position + targetOrientation
)
end
end
Humanoid.AutoRotate = false
end
-- bind functions to renderstep for smooth execution
RunService:BindToRenderStep("UpdateCamera", Enum.RenderPriority.Camera.Value, updateCamera)
RunService:BindToRenderStep("UpdateCharacterOrientation", Enum.RenderPriority.Character.Value, updateCharacterOrientation)