I am creating a camera system that toggles between first and third person smoothly. The third person perspective should be over the shoulder at a specific offset, while first person works normally. Current the code below works, however, there is a small bug seen in the video attached:
local CameraOffset = Vector3.new(4,2,8) -- Camera Offset
local running = true
local cameraAngleX = 0
local cameraAngleY = 0
local startCFrame
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
player.CameraMinZoomDistance = 8
player.CameraMaxZoomDistance = 8
function POV.FocusControl(actionName, inputState, inputObject)
if inputState == nil or inputState == Enum.UserInputState.Begin then
camera.CameraType = Enum.CameraType.Scriptable
player.CameraMode = Enum.CameraMode.Classic
end
end
UserInputService.WindowFocused:Connect(function()
if running then
UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
end
end)
POV.FocusControl()
local function playerInput(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Change then
cameraAngleX -= inputObject.Delta.X
cameraAngleY = math.clamp(cameraAngleY - inputObject.Delta.Y * 0.4, -75,75)
end
end
ContextActionService:BindAction("PlayerInput", playerInput, false,
Enum.UserInputType.MouseMovement, Enum.UserInputType.Touch)
RunService:BindToRenderStep("CameraUpdate", Enum.RenderPriority.Camera.Value, function()
startCFrame = CFrame.new(rootPart.CFrame.Position) * CFrame.Angles(0,math.rad(cameraAngleX),0) * CFrame.Angles(math.rad(cameraAngleY), 0,0)
local cameraCFrame = startCFrame:PointToWorldSpace(CameraOffset)
local cameraFocus = startCFrame:PointToWorldSpace(Vector3.new(CameraOffset.X, CameraOffset.Y, -100000))
if running then
camera.CFrame = CFrame.lookAt(cameraCFrame, cameraFocus)
local lookingCFrame = CFrame.lookAt(rootPart.Position, camera.CFrame:PointToWorldSpace(Vector3.new(0,0,-100000)))
rootPart.CFrame = CFrame.fromMatrix(rootPart.Position, lookingCFrame.XVector, rootPart.CFrame.YVector)
end
end)
UserInputService.InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.Z and running then -- FirstPerson
running = false
repeat
camera.CameraType = Enum.CameraType.Custom
until camera.CameraType == Enum.CameraType.Custom
player.CameraMode = Enum.CameraMode.LockFirstPerson
elseif input.KeyCode == Enum.KeyCode.Z then -- ThirdPerson
running = true
POV.FocusControl()
end
end)
After returning from first-person back to third-person. The more input.Delta.X that occured while in first person the more the camera’s CFrame will snap a random X direction while the camera’s Y CFrame stays relatively the same when transitioning back to third-person.
After hours of debugging I have realized that Roblox’s mouse sensitivity and how long it would take to do a 360 turn when in first-person vs third-person is different. Although I never change mouse.DeltaSensitivity, inputObject.Delta.X scales different when in first-person vs third-person. Is there a way around this or to account for the change in sensivity, looking at other bug threads I saw Roblox’s mouse sensitivity system has been an issue for a long time.