Camera CFrame snaps when moving cursor past certain points

  1. What do you want to achieve?
    Make the mouse able to guide the camera while holding a certain key
  2. What is the issue?
    The camera’s CFrame snaps when the cursor moves past the horizontal and vertical centers of the screen
  3. What solutions have you tried so far?
    I’ve tried changing the formula several times and lerping the values, but neither worked.

local function moveCamera()
	if not rootPart then
		return
	end
	
	local mouseLocation = UserInputService:GetMouseLocation()
	local mouseX = if mouseLocation.X < viewportSize.X
		then mouseLocation.X - viewportSize.X else mouseLocation.X
	local mouseY = if mouseLocation.Y < viewportSize.Y
		then mouseLocation.Y - viewportSize.Y else mouseLocation.Y

	currentCamera.CFrame = CFrame.new(rootPart.Position.X + (mouseX / viewportSize.X * 2),
		rootPart.Position.Y + 15,
		rootPart.Position.Z + (mouseY / viewportSize.Y * 2) + 15)
		* CFrame.Angles(math.rad(-52.5), 0, 0)
end

RunService:BindToRenderStep("CameraAngle", Enum.RenderPriority.Camera.Value, cameraAngle)

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then
		return
	end

	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		movingCamera = true
		RunService:BindToRenderStep("MovingCamera", Enum.RenderPriority.Camera.Value, moveCamera)
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then
		return
	end
	
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		movingCamera = false
		RunService:UnbindFromRenderStep("MovingCamera")
	end
end)```
3 Likes

So, this might be an issue, it might not, just tell me if it is or isn’t, but you should probably find the area of the screen before going into the main script. Right now you’re basing it off of Y and X, but you should add the two to have an area defined first? I’m not sure, try it out.

1 Like

ohhh wait, I think I got it. You defined the MouseX and MouseY with absolute values, which mean they will be the same size for different devices (super big for phones, super small for pc). Instead use Scale values.

I think this is how you had the top values listed, you didn’t provide any values from the top so.

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local currentCamera = workspace.CurrentCamera
local rootPart = game.Players.LocalPlayer.Character:WaitForChild("HumanoidRootPart")
local viewportSize = currentCamera.ViewportSize
local movingCamera = false

-- Store the initial center of the screen
local centerScreen = Vector2.new(viewportSize.X / 2, viewportSize.Y / 2)

local function moveCamera()
	if not rootPart then return end
	
	local mouseLocation = UserInputService:GetMouseLocation()
	local deltaX = (mouseLocation.X - centerScreen.X) / viewportSize.X -- Horizontal movement
	local deltaY = (mouseLocation.Y - centerScreen.Y) / viewportSize.Y -- Vertical movement

	-- Adjust the camera position based on the mouse movement
	currentCamera.CFrame = CFrame.new(
		rootPart.Position + Vector3.new(deltaX * 20, 15, deltaY * 20) -- Scale movement to match desired distance
	) * CFrame.Angles(math.rad(-52.5), 0, 0)
end

UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then return end

	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		movingCamera = true
		RunService:BindToRenderStep("MovingCamera", Enum.RenderPriority.Camera.Value, moveCamera)
	end
end)

UserInputService.InputEnded:Connect(function(input, gameProcessedEvent)
	if gameProcessedEvent then return end
	
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		movingCamera = false
		RunService:UnbindFromRenderStep("MovingCamera")
	end
end)

tell me how it works, I love learning from my mistakes

2 Likes

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