-- Shitlock.lol if not game:IsLoaded() then game.Loaded:Wait() end local uniqueKey = "Script_" .. tostring(math.random(100000, 999999)) .. "_" .. tostring(tick()) if getgenv()[uniqueKey] then return end getgenv()[uniqueKey] = true local players = game:GetService("Players") local localPlayer = players.LocalPlayer if not localPlayer then players:GetPropertyChangedSignal("LocalPlayer"):Wait() localPlayer = players.LocalPlayer end local character = localPlayer.Character or localPlayer.CharacterAdded:Wait() local humanoid = character:WaitForChild("Humanoid") local rootPart = character:WaitForChild("HumanoidRootPart") if workspace.CurrentCamera == nil then return end local randomGuiName1 = "GUI_" .. tostring(math.random(1000000, 9999999)) .. "_" .. tostring(math.random(1000000, 9999999)) local randomGuiName2 = "GUI_" .. tostring(math.random(1000000, 9999999)) .. "_" .. tostring(math.random(1000000, 9999999)) local randomGuiName3 = "GUI_" .. tostring(math.random(1000000, 9999999)) .. "_" .. tostring(math.random(1000000, 9999999)) local targetGetHui = (typeof(gethui) == "function" and gethui()) or game:GetService("CoreGui") local ShiftlockStarterGui = Instance.new("ScreenGui") local ImageButton = Instance.new("ImageButton") local ScreenGui = Instance.new("ScreenGui") ScreenGui.Name = randomGuiName1 ScreenGui.Parent = targetGetHui ShiftlockStarterGui.Name = randomGuiName2 ShiftlockStarterGui.Parent = ScreenGui ShiftlockStarterGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling ImageButton.Parent = ShiftlockStarterGui ImageButton.Active = true ImageButton.Draggable = false ImageButton.BackgroundColor3 = Color3.fromRGB(255, 255, 255) ImageButton.BackgroundTransparency = 1.000 ImageButton.Position = UDim2.new(0.921914339, 0, 0.552375436, 0) ImageButton.Size = UDim2.new(0.0636147112, 0, 0.0661305636, 0) ImageButton.SizeConstraint = Enum.SizeConstraint.RelativeXX ImageButton.Image = "http://www.roblox.com/asset/?id=182223762" local CrosshairGui = Instance.new("ScreenGui") CrosshairGui.Name = randomGuiName3 CrosshairGui.Parent = targetGetHui CrosshairGui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling CrosshairGui.ResetOnSpawn = false local CrosshairImage = Instance.new("ImageLabel") CrosshairImage.Parent = CrosshairGui CrosshairImage.BackgroundTransparency = 1 CrosshairImage.AnchorPoint = Vector2.new(0.5, 0.5) CrosshairImage.Position = UDim2.new(0.5, 0, 0.5, -25) CrosshairImage.Size = UDim2.new(0, 48, 0, 48) CrosshairImage.Image = "rbxassetid://10546018744" CrosshairImage.Visible = false local runservice = game:GetService("RunService") local CAS = game:GetService("ContextActionService") local player = players.LocalPlayer local button = ImageButton local uis = game:GetService("UserInputService") local ismobile = uis.TouchEnabled button.Visible = false local states = { OFF = "rbxasset://textures/ui/mouseLock_off@2x.png", ON = "rbxasset://textures/ui/mouseLock_on@2x.png" } local MAX_LENGTH = 900000 local active = false local ENABLED_OFFSET = CFrame.new(1.7, 0.7, 0) local DISABLED_OFFSET = CFrame.new(-1.7, -0.7, 0) local rootPos = Vector3.new(0, 0, 0) local dragging = false local dragStartPos = nil local dragStartButtonPos = nil local DRAG_THRESHOLD = 10 local isFirstPerson = false local shiftlockVisible = false local autoRotateConnection = nil local devMouseLockConnection = nil local function UpdateImage(STATE) button.Image = states[STATE] end local function UpdatePos() if player.Character and player.Character:FindFirstChildOfClass("Humanoid") and player.Character:FindFirstChildOfClass("Humanoid").RootPart then rootPos = player.Character:FindFirstChildOfClass("Humanoid").RootPart.Position end end local function UpdateAutoRotate(BOOL) if player.Character and player.Character:FindFirstChildOfClass("Humanoid") then player.Character:FindFirstChildOfClass("Humanoid").AutoRotate = BOOL end end local function GetUpdatedCameraCFrame() if workspace.CurrentCamera then return CFrame.new(rootPos, Vector3.new(workspace.CurrentCamera.CFrame.LookVector.X * MAX_LENGTH, rootPos.Y, workspace.CurrentCamera.CFrame.LookVector.Z * MAX_LENGTH)) end end local function DisableShiftlock() if autoRotateConnection then autoRotateConnection:Disconnect() autoRotateConnection = nil end if devMouseLockConnection then devMouseLockConnection:Disconnect() devMouseLockConnection = nil end if active then active:Disconnect() active = false end UpdatePos() UpdateAutoRotate(true) pcall(function() player.DevEnableMouseLock = true end) UpdateImage("OFF") if workspace.CurrentCamera then workspace.CurrentCamera.CFrame = workspace.CurrentCamera.CFrame * DISABLED_OFFSET end CrosshairImage.Visible = false end local function EnableShiftlock() UpdatePos() UpdateAutoRotate(false) UpdateImage("ON") if player.Character and player.Character:FindFirstChildOfClass("Humanoid") and player.Character:FindFirstChildOfClass("Humanoid").RootPart then player.Character:FindFirstChildOfClass("Humanoid").RootPart.CFrame = GetUpdatedCameraCFrame() end if workspace.CurrentCamera then workspace.CurrentCamera.CFrame = workspace.CurrentCamera.CFrame * ENABLED_OFFSET end CrosshairImage.Visible = true end local function StartAutoRotateWatcher() if autoRotateConnection then autoRotateConnection:Disconnect() autoRotateConnection = nil end local hum = player.Character and player.Character:FindFirstChildOfClass("Humanoid") if hum then autoRotateConnection = hum:GetPropertyChangedSignal("AutoRotate"):Connect(function() if active then if hum.AutoRotate == true then hum.AutoRotate = false end end end) end end local function StartDevMouseLockWatcher() if devMouseLockConnection then devMouseLockConnection:Disconnect() devMouseLockConnection = nil end devMouseLockConnection = player:GetPropertyChangedSignal("DevEnableMouseLock"):Connect(function() if active then if player.DevEnableMouseLock == true then player.DevEnableMouseLock = false end end end) if player.DevEnableMouseLock == true then player.DevEnableMouseLock = false end end UpdateImage("OFF") local function ShiftLock() if not active then active = runservice.RenderStepped:Connect(function() EnableShiftlock() end) StartAutoRotateWatcher() StartDevMouseLockWatcher() else DisableShiftlock() end end CAS:BindAction("ShiftLOCK", ShiftLock, false, "On") CAS:SetPosition("ShiftLOCK", UDim2.new(0.8, 0, 0.8, 0)) local function ClampButtonPosition(posX, posY) local screenSize = ShiftlockStarterGui.AbsoluteSize local buttonSize = button.AbsoluteSize local minX = 0 local minY = 0 local maxX = screenSize.X - buttonSize.X local maxY = screenSize.Y - buttonSize.Y posX = math.clamp(posX, minX, maxX) posY = math.clamp(posY, minY, maxY) return posX, posY end button.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then dragging = false dragStartPos = Vector2.new(input.Position.X, input.Position.Y) dragStartButtonPos = Vector2.new(button.AbsolutePosition.X, button.AbsolutePosition.Y) end end) button.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseMovement then if dragStartPos and dragStartButtonPos then local currentPos = Vector2.new(input.Position.X, input.Position.Y) local delta = currentPos - dragStartPos if delta.Magnitude > DRAG_THRESHOLD then dragging = true end if dragging then local newX = dragStartButtonPos.X + delta.X local newY = dragStartButtonPos.Y + delta.Y newX, newY = ClampButtonPosition(newX, newY) button.Position = UDim2.new(0, newX, 0, newY) end end end end) button.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.Touch or input.UserInputType == Enum.UserInputType.MouseButton1 then if not dragging then if not active then active = runservice.RenderStepped:Connect(function() EnableShiftlock() end) StartAutoRotateWatcher() StartDevMouseLockWatcher() else DisableShiftlock() end end dragging = false dragStartPos = nil dragStartButtonPos = nil end end) runservice:BindToRenderStep("FirstPersonDetector", Enum.RenderPriority.Camera.Value + 1, function() local camera = workspace.CurrentCamera if camera then local dist = (camera.CFrame.p - camera.Focus.p).Magnitude local nowFirstPerson = dist < 0.75 if nowFirstPerson ~= isFirstPerson then isFirstPerson = nowFirstPerson if isFirstPerson then if ismobile then shiftlockVisible = not shiftlockVisible button.Visible = shiftlockVisible end if active then DisableShiftlock() end end end end end) local mouseLockImages = { "rbxasset://textures/ui/mouseLock_off@2x.png", "rbxasset://textures/ui/mouseLock_on@2x.png" } local function IsMouseLockButton(obj) if obj:IsA("ImageButton") or obj:IsA("ImageLabel") then for _, img in ipairs(mouseLockImages) do if obj.Image == img then return true end end end return false end local foundButton = nil local positionCopied = false local function FindTargetButton(parent) if not parent then return nil end local success, children = pcall(function() return parent:GetDescendants() end) if not success then return nil end for _, obj in ipairs(children) do if IsMouseLockButton(obj) and obj ~= button then return obj end end return nil end runservice.Heartbeat:Connect(function() if not foundButton or not foundButton:IsDescendantOf(game) then foundButton = FindTargetButton(player.PlayerGui) or FindTargetButton(game:GetService("CoreGui")) end if foundButton then pcall(function() if button.Visible then if not positionCopied then positionCopied = true button.Position = foundButton.Position end foundButton.Visible = false else foundButton.Visible = true end end) end end) game:GetService("Players").PlayerRemoving:Connect(function(leavingPlayer) if leavingPlayer == player then DisableShiftlock() end end)