local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local player = Players.LocalPlayer local camera = workspace.CurrentCamera local playerModule = require(player:WaitForChild("PlayerScripts"):WaitForChild("PlayerModule")) local controls = playerModule:GetControls() -- // SETTINGS // local currentSpeed, currentSens, currentFOV = 1.5, 0.4, 70 local slideEnabled, isFreecamEnabled, collisionEnabled = false, false, false local is180Mode, isDpadMode = false, false local slipPower, targetFPS, fpsCapEnabled = 1.0, 60, false local CAM_RADIUS = 1.6 -- // STATE // local cameraCFrame = CFrame.new() local yaw, pitch = 0, 0 local velocity = Vector3.new(0,0,0) local joystickTouch = nil local gamepadRotation = Vector2.zero local dpadMove = Vector3.zero local dpadState = {Up=false, Down=false, Left=false, Right=false} -- // UI SETUP // local screenGui = Instance.new("ScreenGui") screenGui.Name = "Freecam_V27_SnapFix" screenGui.ResetOnSpawn = false screenGui.IgnoreGuiInset = true screenGui.Parent = player:WaitForChild("PlayerGui") local container = Instance.new("Frame") container.Size = UDim2.new(0, 135, 0, 630) container.Position = UDim2.new(1, -155, 0.5, 0) container.AnchorPoint = Vector2.new(0, 0.5) container.BackgroundColor3 = Color3.fromRGB(15, 15, 15) container.BackgroundTransparency = 0.2 container.Active = true container.Parent = screenGui Instance.new("UICorner", container) local dragHandle = Instance.new("TextButton") dragHandle.Size = UDim2.new(1, 0, 0, 30); dragHandle.BackgroundColor3 = Color3.fromRGB(60, 60, 60) dragHandle.Text = "::: DRAG :::"; dragHandle.TextColor3 = Color3.new(1,1,1) dragHandle.Font = Enum.Font.GothamBold; dragHandle.Parent = container Instance.new("UICorner", dragHandle) local function quickBtn(text, y, color) local b = Instance.new("TextButton") b.Size = UDim2.new(0.9, 0, 0, 32); b.Position = UDim2.new(0.5, 0, 0, y) b.AnchorPoint = Vector2.new(0.5, 0); b.BackgroundColor3 = color or Color3.fromRGB(40, 40, 40) b.TextColor3 = Color3.new(1,1,1); b.Text = text; b.Font = Enum.Font.GothamBold b.TextScaled = true; b.Parent = container; Instance.new("UICorner", b) return b end local function quickBox(y, def) local bx = Instance.new("TextBox") bx.Size = UDim2.new(0.9, 0, 0, 24); bx.Position = UDim2.new(0.5, 0, 0, y) bx.AnchorPoint = Vector2.new(0.5, 0); bx.BackgroundColor3 = Color3.new(0,0,0) bx.BackgroundTransparency = 0.5; bx.TextColor3 = Color3.new(1,1,1) bx.Text = def; bx.Font = Enum.Font.Gotham; bx.Parent = container Instance.new("UICorner", bx); return bx end -- UI Elements local toggleBtn = quickBtn("CAM: OFF", 40) local modeBtn = quickBtn("180°: OFF", 78, Color3.fromRGB(50, 70, 100)) local speedIn = quickBox(115, "Speed: 1.5") local sensIn = quickBox(145, "Sens: 0.4") local fovIn = quickBox(175, "FOV: 70") local colTog = quickBtn("COLLIDE: OFF", 210) local slideBtn = quickBtn("SLIDE: OFF", 248) local dpadTog = quickBtn("DPAD: OFF", 286, Color3.fromRGB(150, 80, 0)) local slipIn = quickBox(324, "Slip: 1.0") local fpsTog = quickBtn("FPS CAP: OFF", 360, Color3.fromRGB(100, 40, 40)) local fpsIn = quickBox(398, "FPS: 60") local tpBtn = quickBtn("TELEPORT", 550, Color3.fromRGB(80, 50, 150)) local hideBtn = quickBtn("HIDE HUD", 590, Color3.fromRGB(30, 30, 30)) local showBtn = Instance.new("TextButton") showBtn.Size = UDim2.new(0, 70, 0, 30); showBtn.Position = UDim2.new(1, -80, 0, 10) showBtn.BackgroundColor3 = Color3.new(0,0,0); showBtn.Text = "SHOW"; showBtn.TextColor3 = Color3.new(1,1,1) showBtn.Visible = false; showBtn.Parent = screenGui; Instance.new("UICorner", showBtn) -- // DPAD UI // local dpadFrame = Instance.new("Frame") dpadFrame.Size = UDim2.new(0, 180, 0, 180); dpadFrame.Position = UDim2.new(0, 30, 1, -220) dpadFrame.BackgroundTransparency = 1; dpadFrame.Visible = false; dpadFrame.Parent = screenGui local function makeArrow(name, pos, rot) local btn = Instance.new("ImageButton") btn.Size = UDim2.new(0, 55, 0, 55); btn.Position = pos; btn.BackgroundColor3 = Color3.new(0,0,0) btn.BackgroundTransparency = 0.4; btn.Image = "rbxassetid://6031091004"; btn.Rotation = rot; btn.Parent = dpadFrame Instance.new("UICorner", btn); return btn end local btnU, btnD, btnL, btnR = makeArrow("U", UDim2.new(0.5, -27, 0, 0), 0), makeArrow("D", UDim2.new(0.5, -27, 1, -55), 180), makeArrow("L", UDim2.new(0, 0, 0.5, -27), -90), makeArrow("R", UDim2.new(1, -55, 0.5, -27), 90) -- // FPS CAPPER // task.spawn(function() while true do if fpsCapEnabled then local t = os.clock() RunService.Heartbeat:Wait() while (os.clock() - t) < (1/targetFPS) do end else RunService.Heartbeat:Wait() end end end) -- // CORE LOGIC // local function applyRot(delta) if is180Mode then yaw = yaw - math.rad(delta.X) pitch = math.clamp(pitch - math.rad(delta.Y), math.rad(-89), math.rad(89)) cameraCFrame = CFrame.new(cameraCFrame.Position) * CFrame.Angles(0, yaw, 0) * CFrame.Angles(pitch, 0, 0) else cameraCFrame = cameraCFrame * CFrame.Angles(0, -math.rad(delta.X), 0) * CFrame.Angles(-math.rad(delta.Y), 0, 0) end end local function upDpad() local x = (dpadState.Right and 1 or 0) - (dpadState.Left and 1 or 0) local z = (dpadState.Down and 1 or 0) - (dpadState.Up and 1 or 0) dpadMove = Vector3.new(x, 0, z) if dpadMove.Magnitude > 0 then dpadMove = dpadMove.Unit end end local function bindD(b, d) b.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.Touch or i.UserInputType == Enum.UserInputType.MouseButton1 then dpadState[d] = true; upDpad(); b.BackgroundTransparency = 0.1 end end) b.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.Touch or i.UserInputType == Enum.UserInputType.MouseButton1 then dpadState[d] = false; upDpad(); b.BackgroundTransparency = 0.4 end end) end bindD(btnU, "Up"); bindD(btnD, "Down"); bindD(btnL, "Left"); bindD(btnR, "Right") UserInputService.InputBegan:Connect(function(input, gpe) if not isFreecamEnabled then return end if isDpadMode and input.UserInputType == Enum.UserInputType.Gamepad1 then local k = input.KeyCode if k == Enum.KeyCode.DPadUp then dpadState.Up = true elseif k == Enum.KeyCode.DPadDown then dpadState.Down = true elseif k == Enum.KeyCode.DPadLeft then dpadState.Left = true elseif k == Enum.KeyCode.DPadRight then dpadState.Right = true end upDpad() end if input.UserInputType == Enum.UserInputType.Touch and not isDpadMode then if input.Position.X < (camera.ViewportSize.X * 0.45) then joystickTouch = input end end end) UserInputService.InputEnded:Connect(function(input) if input == joystickTouch then joystickTouch = nil end if input.KeyCode == Enum.KeyCode.Thumbstick2 then gamepadRotation = Vector2.zero end if isDpadMode and input.UserInputType == Enum.UserInputType.Gamepad1 then local k = input.KeyCode if k == Enum.KeyCode.DPadUp then dpadState.Up = false elseif k == Enum.KeyCode.DPadDown then dpadState.Down = false elseif k == Enum.KeyCode.DPadLeft then dpadState.Left = false elseif k == Enum.KeyCode.DPadRight then dpadState.Right = false end upDpad() end end) UserInputService.InputChanged:Connect(function(input, gpe) if not isFreecamEnabled or (gpe and input.UserInputType ~= Enum.UserInputType.Gamepad1) then return end if input.KeyCode == Enum.KeyCode.Thumbstick2 then local p = input.Position; gamepadRotation = (p.Magnitude > 0.1) and Vector2.new(p.X * 5, -p.Y * 5) or Vector2.zero elseif input.UserInputType == Enum.UserInputType.MouseMovement or (input.UserInputType == Enum.UserInputType.Touch and input ~= joystickTouch) then if isDpadMode and input.UserInputType == Enum.UserInputType.Touch and input.Position.X < (camera.ViewportSize.X * 0.45) then return end applyRot(Vector2.new(input.Delta.X * currentSens, input.Delta.Y * currentSens)) end end) -- // RENDER ENGINE // RunService:BindToRenderStep("FreecamCore", Enum.RenderPriority.Camera.Value + 101, function(dt) if not isFreecamEnabled then return end camera.CameraType = Enum.CameraType.Scriptable if player.Character and player.Character:FindFirstChild("Humanoid") then if camera.CameraSubject ~= player.Character.Humanoid then camera.CameraSubject = player.Character.Humanoid end end if gamepadRotation.Magnitude > 0 then applyRot(gamepadRotation * currentSens) end local mv = isDpadMode and dpadMove or controls:GetMoveVector() local dir = (cameraCFrame.RightVector * mv.X) + (cameraCFrame.LookVector * -mv.Z) local targetVel = dir * currentSpeed velocity = slideEnabled and velocity:Lerp(targetVel, math.clamp(dt * (10/slipPower), 0.01, 0.5)) or targetVel local subSteps = 4 local moveStep = velocity / subSteps local params = RaycastParams.new(); params.FilterDescendantsInstances = {player.Character} for s = 1, subSteps do local step = moveStep if collisionEnabled and step.Magnitude > 0.001 then for i = 1, 3 do local cast = workspace:Spherecast(cameraCFrame.Position, CAM_RADIUS, step + (step.Unit * 0.2), params) if cast and cast.Instance and cast.Instance.CanCollide then step = step - (step:Dot(cast.Normal) * cast.Normal) if step.Magnitude < 0.001 then step = Vector3.zero break end else break end end end cameraCFrame = cameraCFrame + step end camera.CFrame = cameraCFrame camera.FieldOfView = currentFOV end) -- // UI TOGGLE & SYNC // local function sync(box, var, prefix) box.FocusLost:Connect(function() local val = tonumber(box.Text:match("[%d%.]+")) if val then if var == "speed" then currentSpeed = val elseif var == "sens" then currentSens = val elseif var == "fov" then currentFOV = val elseif var == "slip" then slipPower = math.max(val, 0.01) elseif var == "fps" then targetFPS = math.clamp(val, 1, 240) end end box.Text = prefix .. tostring(val or "??") end) end sync(speedIn, "speed", "Speed: "); sync(sensIn, "sens", "Sens: "); sync(fovIn, "fov", "FOV: "); sync(slipIn, "slip", "Slip: "); sync(fpsIn, "fps", "FPS: ") toggleBtn.MouseButton1Click:Connect(function() isFreecamEnabled = not isFreecamEnabled toggleBtn.Text = isFreecamEnabled and "CAM: ON" or "CAM: OFF" toggleBtn.BackgroundColor3 = isFreecamEnabled and Color3.new(0, 0.7, 0.3) or Color3.fromRGB(40,40,40) if isFreecamEnabled then -- THE SNAP FIX: Teleport to current game camera immediately local currentCamCF = camera.CFrame cameraCFrame = currentCamCF -- Recalculate viewing angles so you don't jump orientation local look = currentCamCF.LookVector yaw = math.atan2(-look.X, -look.Z) pitch = math.asin(math.clamp(look.Y, -0.999, 0.999)) if player.Character then for _, v in pairs(player.Character:GetDescendants()) do if v:IsA("BasePart") then v.Anchored = true end end end else camera.CameraType = Enum.CameraType.Custom if player.Character then for _, v in pairs(player.Character:GetDescendants()) do if v:IsA("BasePart") then v.Anchored = false end end end end end) dpadTog.MouseButton1Click:Connect(function() isDpadMode = not isDpadMode; dpadTog.Text = isDpadMode and "DPAD: ON" or "DPAD: OFF"; dpadFrame.Visible = isDpadMode; dpadTog.BackgroundColor3 = isDpadMode and Color3.fromRGB(255, 120, 0) or Color3.fromRGB(150, 80, 0); player.DevTouchMovementMode = isDpadMode and Enum.DevTouchMovementMode.Scriptable or Enum.DevTouchMovementMode.UserChoice end) fpsTog.MouseButton1Click:Connect(function() fpsCapEnabled = not fpsCapEnabled; fpsTog.Text = fpsCapEnabled and "FPS CAP: ON" or "FPS CAP: OFF"; fpsTog.BackgroundColor3 = fpsCapEnabled and Color3.new(0.8, 0.2, 0.2) or Color3.fromRGB(100, 40, 40) end) modeBtn.MouseButton1Click:Connect(function() is180Mode = not is180Mode; modeBtn.Text = is180Mode and "180°: ON" or "180°: OFF" end) colTog.MouseButton1Click:Connect(function() collisionEnabled = not collisionEnabled; colTog.Text = collisionEnabled and "COLLIDE: ON" or "COLLIDE: OFF" end) slideBtn.MouseButton1Click:Connect(function() slideEnabled = not slideEnabled; slideBtn.Text = slideEnabled and "SLIDE: ON" or "SLIDE: OFF" end) tpBtn.MouseButton1Click:Connect(function() if player.Character then player.Character:MoveTo(cameraCFrame.Position) end end) hideBtn.MouseButton1Click:Connect(function() container.Visible = false; showBtn.Visible = true end) showBtn.MouseButton1Click:Connect(function() container.Visible = true; showBtn.Visible = false end) -- DRAGGING local isDrag, dStart, sPos dragHandle.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then isDrag = true; dStart = i.Position; sPos = container.Position end end) UserInputService.InputChanged:Connect(function(i) if isDrag and (i.UserInputType == Enum.UserInputType.MouseMovement or i.UserInputType == Enum.UserInputType.Touch) then local delta = i.Position - dStart; container.Position = UDim2.new(sPos.X.Scale, sPos.X.Offset + delta.X, sPos.Y.Scale, sPos.Y.Offset + delta.Y) end end) UserInputService.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 or i.UserInputType == Enum.UserInputType.Touch then isDrag = false end end)