local P = game:GetService("Players") local UIS = game:GetService("UserInputService") local RS = game:GetService("RunService") local TS = game:GetService("TweenService") local plr = P.LocalPlayer local cam = workspace.CurrentCamera local ps = plr:WaitForChild("PlayerScripts") local pm = ps:WaitForChild("PlayerModule") local ok, mod = pcall(require, pm) local ctl if ok and mod and mod.GetControls then pcall(function() ctl = mod:GetControls() end) end local mob = UIS.TouchEnabled and not UIS.KeyboardEnabled local on = false local keys = {} local pos local yaw = 0 local pit = 0 local oldType local oldSub local oldCf local oldMouse local oldCtl = false local spd = 70 local spr = 180 local ls = 0.0025 local ts = 0.006 local lt local lp local rt local stm = 0 local lastPos local ui = Instance.new("ScreenGui") ui.Name = "FreecamUI" ui.ResetOnSpawn = false ui.IgnoreGuiInset = true ui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling pcall(function() ui.Parent = game:GetService("CoreGui") end) if not ui.Parent then ui.Parent = plr:WaitForChild("PlayerGui") end local btn local stroke local hint local function root() local c = plr.Character return c and c:FindFirstChild("HumanoidRootPart") end local function look() local v = cam.CFrame.LookVector yaw = math.atan2(-v.X, -v.Z) pit = math.asin(math.clamp(v.Y, -1, 1)) end local function vis(v) if not btn then return end TS:Create( btn, TweenInfo.new(0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { BackgroundColor3 = v and Color3.fromRGB(95, 60, 155) or Color3.fromRGB(20, 20, 24) } ):Play() TS:Create( stroke, TweenInfo.new(0.15, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), { Color = v and Color3.fromRGB(175, 125, 255) or Color3.fromRGB(55, 55, 62) } ):Play() end local function st() if on then return end local r = root() if not r then return end cam = workspace.CurrentCamera oldType = cam.CameraType oldSub = cam.CameraSubject oldCf = cam.CFrame oldMouse = UIS.MouseBehavior pos = cam.CFrame.Position look() if ctl then oldCtl = true pcall(function() ctl:Disable() end) end cam.CameraType = Enum.CameraType.Scriptable if not mob then UIS.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition end on = true stm = 0 lastPos = nil vis(true) pcall(function() plr:RequestStreamAroundAsync(pos, 2) end) lastPos = pos end local function sp() if not on then return end on = false lt = nil rt = nil lp = nil cam = workspace.CurrentCamera cam.CameraType = oldType or Enum.CameraType.Custom cam.CameraSubject = oldSub if oldCf then cam.CFrame = oldCf end UIS.MouseBehavior = oldMouse or Enum.MouseBehavior.Default if ctl and oldCtl then pcall(function() ctl:Enable() end) end oldCtl = false pos = nil lastPos = nil vis(false) end local function tg() if on then sp() else st() end end if mob then btn = Instance.new("Frame") btn.Name = "Toggle" btn.Size = UDim2.fromOffset(58, 58) btn.Position = UDim2.new(1, -78, 1, -94) btn.BackgroundColor3 = Color3.fromRGB(20, 20, 24) btn.BorderSizePixel = 0 btn.Active = true btn.ZIndex = 20 btn.Parent = ui local cr = Instance.new("UICorner") cr.CornerRadius = UDim.new(0, 15) cr.Parent = btn stroke = Instance.new("UIStroke") stroke.Thickness = 1.5 stroke.Color = Color3.fromRGB(55, 55, 62) stroke.Parent = btn local ic = Instance.new("ImageLabel") ic.Size = UDim2.fromOffset(25, 25) ic.Position = UDim2.fromScale(0.5, 0.5) ic.AnchorPoint = Vector2.new(0.5, 0.5) ic.BackgroundTransparency = 1 ic.Image = "rbxassetid://7733708692" ic.ImageColor3 = Color3.fromRGB(230, 230, 235) ic.ZIndex = 21 ic.Parent = btn local us = Instance.new("UIScale") us.Parent = btn local drag local start local moved = false btn.InputBegan:Connect(function(i) if i.UserInputType ~= Enum.UserInputType.Touch and i.UserInputType ~= Enum.UserInputType.MouseButton1 then return end drag = i.Position start = btn.Position moved = false end) btn.InputChanged:Connect(function(i) if i.UserInputType ~= Enum.UserInputType.Touch and i.UserInputType ~= Enum.UserInputType.MouseMovement then return end local c c = UIS.InputChanged:Connect(function(x) if x ~= i then return end if not drag or not start then c:Disconnect() return end local d = x.Position - drag if d.Magnitude > 8 then moved = true end btn.Position = UDim2.new( start.X.Scale, start.X.Offset + d.X, start.Y.Scale, start.Y.Offset + d.Y ) end) end) btn.InputEnded:Connect(function(i) if i.UserInputType ~= Enum.UserInputType.Touch and i.UserInputType ~= Enum.UserInputType.MouseButton1 then return end if not moved then TS:Create( us, TweenInfo.new(0.08, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Scale = 0.9} ):Play() task.delay(0.08, function() if us.Parent then TS:Create( us, TweenInfo.new(0.1, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {Scale = 1} ):Play() end end) tg() end drag = nil start = nil moved = false end) else hint = Instance.new("TextLabel") hint.Name = "Hint" hint.AnchorPoint = Vector2.new(1, 0) hint.Position = UDim2.new(1, -18, 0, 18) hint.Size = UDim2.fromOffset(145, 24) hint.BackgroundTransparency = 1 hint.Text = "use f to freecam" hint.TextSize = 14 hint.Font = Enum.Font.GothamMedium hint.TextXAlignment = Enum.TextXAlignment.Right hint.ZIndex = 10 hint.Parent = ui end UIS.InputBegan:Connect(function(i, p) if not mob then if i.KeyCode == Enum.KeyCode.F and not p then tg() return end if on and i.UserInputType == Enum.UserInputType.Keyboard then keys[i.KeyCode] = true end else if not on then return end if i.UserInputType == Enum.UserInputType.Touch then local vp = cam.ViewportSize local x = i.Position.X local y = i.Position.Y local bx = btn.AbsolutePosition local bs = btn.AbsoluteSize local inBtn = x >= bx.X and x <= bx.X + bs.X and y >= bx.Y and y <= bx.Y + bs.Y if inBtn then return end if x < vp.X * 0.45 and y > vp.Y * 0.45 and not lt then lt = i lp = i.Position elseif x >= vp.X * 0.38 and not rt then rt = i end end end end) UIS.InputEnded:Connect(function(i) if i.UserInputType == Enum.UserInputType.Keyboard then keys[i.KeyCode] = nil end if i == lt then lt = nil lp = nil end if i == rt then rt = nil end end) UIS.InputChanged:Connect(function(i) if not on then return end if not mob then if i.UserInputType == Enum.UserInputType.MouseMovement then yaw -= i.Delta.X * ls pit -= i.Delta.Y * ls pit = math.clamp(pit, -math.rad(89), math.rad(89)) end else if i.UserInputType == Enum.UserInputType.Touch then if i == rt then yaw -= i.Delta.X * ts pit -= i.Delta.Y * ts pit = math.clamp( pit, -math.rad(89), math.rad(89) ) end end end end) local rtick = 0 RS.RenderStepped:Connect(function(dt) if hint then rtick += dt * 0.25 hint.TextColor3 = Color3.fromHSV( rtick % 1, 0.8, 1 ) end if not on then return end cam = workspace.CurrentCamera if not pos then pos = cam.CFrame.Position end local cr = CFrame.Angles(0, yaw, 0) * CFrame.Angles(pit, 0, 0) local mv = Vector3.zero if mob then if lt and lp then local d = lt.Position - lp local v = Vector2.new( math.clamp(d.X / 70, -1, 1), math.clamp(d.Y / 70, -1, 1) ) mv += cr.RightVector * v.X mv += cr.LookVector * -v.Y end else local f = 0 local r = 0 local u = 0 if keys[Enum.KeyCode.W] then f += 1 end if keys[Enum.KeyCode.S] then f -= 1 end if keys[Enum.KeyCode.A] then r -= 1 end if keys[Enum.KeyCode.D] then r += 1 end if keys[Enum.KeyCode.U] then u += 1 end if keys[Enum.KeyCode.D] then u -= 1 end mv += cr.LookVector * f mv += cr.RightVector * r mv += Vector3.yAxis * u end if mv.Magnitude > 1 then mv = mv.Unit end local speed = spd if keys[Enum.KeyCode.LeftShift] or keys[Enum.KeyCode.RightShift] then speed = spr end pos += mv * speed * dt stm += dt if stm >= 0.5 then stm = 0 if not lastPos or (pos - lastPos).Magnitude >= 64 then lastPos = pos task.spawn(function() pcall(function() plr:RequestStreamAroundAsync(pos, 2) end) end) end end local cf = CFrame.new(pos) * CFrame.Angles(0, yaw, 0) * CFrame.Angles(pit, 0, 0) cam.CFrame = cf cam.Focus = CFrame.new(pos) end) plr.CharacterAdded:Connect(function() if on then sp() end end)