Freecam
Key RequiredUniversal

Freecam

Universal ScriptKiritopetKiritopet 809 views 19.1K executesUpdated Jul 3, 2026
Unrated
00
Lua Script•350 lines (12488 chars)
-- Freecam – Studio Style Camera

local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local CoreGui = game:GetService("CoreGui")
local TweenService = game:GetService("TweenService")
local StarterGui = game:GetService("StarterGui")

local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
local Humanoid = Character:WaitForChild("Humanoid")

local freecamEnabled = false
local freecamPos = Vector3.zero
local pitchAngle = 0
local yawAngle = 0
local baseSpeed = 50
local shiftSpeed = 150
local currentSpeed = baseSpeed

local keysPressed = {}
local mobileMoveStick = nil
local mobileLookStick = nil
local mobileTouches = {}

local function enableFreecam()
    freecamEnabled = true
    freecamPos = Camera.CFrame.Position
    local look = Camera.CFrame.LookVector
    yawAngle = math.atan2(look.X, -look.Z)
    pitchAngle = math.asin(look.Y)
    Camera.CameraType = Enum.CameraType.Scriptable
    Humanoid.AutoRotate = false
    Humanoid.WalkSpeed = 0
    Humanoid.JumpPower = 0
end

local function disableFreecam()
    freecamEnabled = false
    Camera.CameraType = Enum.CameraType.Custom
    Camera.CameraSubject = Humanoid
    Humanoid.AutoRotate = true
    Humanoid.WalkSpeed = 16
    Humanoid.JumpPower = 50
    mobileMoveStick = nil
    mobileLookStick = nil
    mobileTouches = {}
end

local function toggleFreecam()
    if freecamEnabled then
        disableFreecam()
        toggleBtn.Text = "TOGGLE"
        toggleBtn.BackgroundColor3 = Color3.fromRGB(30,30,30)
    else
        enableFreecam()
        toggleBtn.Text = "TOGGLE [ON]"
        toggleBtn.BackgroundColor3 = Color3.fromRGB(25,45,25)
    end
end

local function teleportToCamera()
    if not freecamEnabled then
        StarterGui:SetCore("SendNotification", {
            Title = "FREECAM",
            Text = "Freecam is not enabled!",
            Duration = 3
        })
        return
    end
    local HRP = Character and Character:FindFirstChild("HumanoidRootPart")
    if HRP then
        HRP.CFrame = CFrame.new(freecamPos)
    end
    disableFreecam()
    toggleBtn.Text = "TOGGLE"
    toggleBtn.BackgroundColor3 = Color3.fromRGB(30,30,30)
end

UserInputService.InputBegan:Connect(function(input, gameProcessed)
    if gameProcessed then return end
    if input.UserInputType == Enum.UserInputType.Keyboard then
        keysPressed[input.KeyCode] = true
    elseif input.UserInputType == Enum.UserInputType.Touch then
        mobileTouches[input] = { startPos = input.Position, currentPos = input.Position, startTime = tick() }
    end
end)

UserInputService.InputEnded:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.Keyboard then
        keysPressed[input.KeyCode] = nil
    elseif input.UserInputType == Enum.UserInputType.Touch then
        mobileTouches[input] = nil
        -- Проверяем, остались ли ещё касания на левой/правой стороне
        local hasLeft = false
        local hasRight = false
        for _, touch in pairs(mobileTouches) do
            if touch.startPos.X < Camera.ViewportSize.X / 2 then
                hasLeft = true
            else
                hasRight = true
            end
        end
        if not hasLeft then mobileMoveStick = nil end
        if not hasRight then mobileLookStick = nil end
    end
end)

UserInputService.InputChanged:Connect(function(input)
    if not freecamEnabled then return end
    
    if input.UserInputType == Enum.UserInputType.Touch then
        local touch = mobileTouches[input]
        if not touch then return end
        touch.currentPos = input.Position
        touch.delta = input.Delta or (input.Position - touch.currentPos)
        
        -- Левый стик - движение
        if touch.startPos.X < Camera.ViewportSize.X / 2 then
            if not mobileMoveStick then
                mobileMoveStick = { position = Vector2.zero }
            end
            mobileMoveStick.position = input.Position - touch.startPos
        end
        
        -- Правый стик - поворот
        if touch.startPos.X > Camera.ViewportSize.X / 2 then
            if not mobileLookStick then
                mobileLookStick = { position = Vector2.zero }
            end
            local delta = input.Delta
            if delta.Magnitude > 0 then
                yawAngle = yawAngle - delta.X * 0.005
                pitchAngle = math.clamp(pitchAngle - delta.Y * 0.005, -1.4, 1.4)
            end
        end
    elseif input.UserInputType == Enum.UserInputType.MouseMovement and not UserInputService.TouchEnabled then
        local delta = input.Delta
        yawAngle = yawAngle - delta.X * 0.003
        pitchAngle = math.clamp(pitchAngle - delta.Y * 0.003, -1.4, 1.4)
    end
end)

local function getMovementDirection()
    local dir = Vector3.zero
    local pitchCF = CFrame.Angles(pitchAngle, 0, 0)
    local yawCF = CFrame.Angles(0, yawAngle, 0)
    local camCF = yawCF * pitchCF
    local forward = camCF.LookVector
    local right = camCF.RightVector

    -- ПК клавиши
    if keysPressed[Enum.KeyCode.W] then dir = dir + forward end
    if keysPressed[Enum.KeyCode.S] then dir = dir - forward end
    if keysPressed[Enum.KeyCode.A] then dir = dir - right end
    if keysPressed[Enum.KeyCode.D] then dir = dir + right end
    if keysPressed[Enum.KeyCode.E] then dir = dir + Vector3.new(0, 1, 0) end
    if keysPressed[Enum.KeyCode.Q] then dir = dir + Vector3.new(0, -1, 0) end

    -- Мобильный стик
    if mobileMoveStick then
        local moveDir = mobileMoveStick.position
        if moveDir.Magnitude > 5 then
            local n = moveDir.Unit
            dir = dir + forward * (-n.Y) + right * n.X
        end
    end

    return dir.Magnitude > 0 and dir.Unit or Vector3.zero
end

RunService.RenderStepped:Connect(function(dt)
    if not freecamEnabled then return end

    local moveDir = getMovementDirection()
    local targetSpeed = (keysPressed[Enum.KeyCode.LeftShift] or UserInputService.TouchEnabled) and shiftSpeed or baseSpeed

    if moveDir.Magnitude > 0 then
        currentSpeed = math.min(currentSpeed + dt * 200, targetSpeed)
        freecamPos = freecamPos + moveDir * currentSpeed * dt
    else
        currentSpeed = baseSpeed
    end

    local pitchCF = CFrame.Angles(pitchAngle, 0, 0)
    local yawCF = CFrame.Angles(0, yawAngle, 0)
    Camera.CFrame = CFrame.new(freecamPos) * yawCF * pitchCF

    local HRP = Character and Character:FindFirstChild("HumanoidRootPart")
    if HRP and HRP.Velocity.Magnitude > 0 then
        HRP.Velocity = Vector3.zero
    end
end)

if CoreGui:FindFirstChild("FreecamUI") then CoreGui.FreecamUI:Destroy() end

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "FreecamUI"
screenGui.ResetOnSpawn = false
screenGui.IgnoreGuiInset = true
screenGui.Parent = CoreGui

local mainFrame = Instance.new("Frame")
mainFrame.Size = UDim2.new(0, 160, 0, 85)
mainFrame.Position = UDim2.new(0.5, -80, 0, 50)
mainFrame.BackgroundColor3 = Color3.fromRGB(12, 12, 12)
mainFrame.BorderSizePixel = 0
mainFrame.ZIndex = 100
mainFrame.ClipsDescendants = true
mainFrame.Parent = screenGui

local function addBorder(parent)
    local t = 1
    local l = Instance.new("Frame"); l.Size = UDim2.new(0, t, 1, 0); l.BackgroundColor3 = Color3.fromRGB(50,50,50); l.BorderSizePixel=0; l.ZIndex=200; l.Parent=parent
    local tp = Instance.new("Frame"); tp.Size = UDim2.new(1,0,0,t); tp.BackgroundColor3 = Color3.fromRGB(50,50,50); tp.BorderSizePixel=0; tp.ZIndex=200; tp.Parent=parent
    local r = Instance.new("Frame"); r.Size = UDim2.new(0, t, 1, 0); r.Position=UDim2.new(1,-t,0,0); r.BackgroundColor3 = Color3.fromRGB(50,50,50); r.BorderSizePixel=0; r.ZIndex=200; r.Parent=parent
    local b = Instance.new("Frame"); b.Size = UDim2.new(1,0,0,t); b.Position=UDim2.new(0,0,1,-t); b.BackgroundColor3 = Color3.fromRGB(50,50,50); b.BorderSizePixel=0; b.ZIndex=200; b.Parent=parent
end
addBorder(mainFrame)

local titleBar = Instance.new("Frame")
titleBar.Size = UDim2.new(1, -2, 0, 20)
titleBar.Position = UDim2.new(0, 1, 0, 1)
titleBar.BackgroundColor3 = Color3.fromRGB(12,12,12)
titleBar.BorderSizePixel = 0
titleBar.ZIndex = 101
titleBar.Parent = mainFrame

local titleLabel = Instance.new("TextLabel")
titleLabel.Size = UDim2.new(1, -30, 1, 0)
titleLabel.Position = UDim2.new(0, 6, 0, 0)
titleLabel.BackgroundTransparency = 1
titleLabel.Text = "Freecam"
titleLabel.TextColor3 = Color3.fromRGB(180,180,180)
titleLabel.Font = Enum.Font.Code
titleLabel.TextSize = 11
titleLabel.TextXAlignment = Enum.TextXAlignment.Left
titleLabel.ZIndex = 102
titleLabel.Parent = titleBar

local collapseButton = Instance.new("TextButton")
collapseButton.Size = UDim2.new(0, 20, 0, 20)
collapseButton.Position = UDim2.new(1, -20, 0, 0)
collapseButton.BackgroundColor3 = Color3.fromRGB(25,25,25)
collapseButton.BorderSizePixel = 0
collapseButton.Text = "-"
collapseButton.TextColor3 = Color3.fromRGB(200,200,200)
collapseButton.Font = Enum.Font.Code
collapseButton.TextSize = 12
collapseButton.ZIndex = 102
collapseButton.Parent = titleBar
addBorder(collapseButton)

local titleDivider = Instance.new("Frame")
titleDivider.Size = UDim2.new(1, -2, 0, 1)
titleDivider.Position = UDim2.new(0, 1, 0, 21)
titleDivider.BackgroundColor3 = Color3.fromRGB(50,50,50)
titleDivider.BorderSizePixel = 0
titleDivider.ZIndex = 200
titleDivider.Parent = mainFrame

local contentFrame = Instance.new("Frame")
contentFrame.Size = UDim2.new(1, -2, 1, -23)
contentFrame.Position = UDim2.new(0, 1, 0, 22)
contentFrame.BackgroundTransparency = 1
contentFrame.ZIndex = 101
contentFrame.Parent = mainFrame

local toggleBtn = Instance.new("TextButton")
toggleBtn.Size = UDim2.new(0, 145, 0, 24)
toggleBtn.Position = UDim2.new(0.5, -72, 0, 3)
toggleBtn.BackgroundColor3 = Color3.fromRGB(30,30,30)
toggleBtn.Text = "TOGGLE"
toggleBtn.TextColor3 = Color3.fromRGB(200,200,200)
toggleBtn.Font = Enum.Font.Code
toggleBtn.TextSize = 11
toggleBtn.BorderSizePixel = 0
toggleBtn.ZIndex = 150
toggleBtn.Parent = contentFrame
addBorder(toggleBtn)

local tpBtn = Instance.new("TextButton")
tpBtn.Size = UDim2.new(0, 145, 0, 24)
tpBtn.Position = UDim2.new(0.5, -72, 0, 30)
tpBtn.BackgroundColor3 = Color3.fromRGB(30,30,30)
tpBtn.Text = "TP TO CAM"
tpBtn.TextColor3 = Color3.fromRGB(200,200,200)
tpBtn.Font = Enum.Font.Code
tpBtn.TextSize = 11
tpBtn.BorderSizePixel = 0
tpBtn.ZIndex = 150
tpBtn.Parent = contentFrame
addBorder(tpBtn)

toggleBtn.MouseButton1Click:Connect(toggleFreecam)
tpBtn.MouseButton1Click:Connect(teleportToCamera)

local isDragging = false
local dragStartPos = nil
local frameStartPos = nil

titleBar.InputBegan:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
        isDragging = true
        dragStartPos = input.Position
        frameStartPos = mainFrame.Position
    end
end)
titleBar.InputEnded:Connect(function() isDragging = false end)

UserInputService.InputChanged:Connect(function(input)
    if isDragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
        local delta = input.Position - dragStartPos
        mainFrame.Position = UDim2.new(frameStartPos.X.Scale, frameStartPos.X.Offset + delta.X, frameStartPos.Y.Scale, frameStartPos.Y.Offset + delta.Y)
    end
end)
UserInputService.InputEnded:Connect(function(input)
    if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then isDragging = false end
end)

local menuCollapsed = false
collapseButton.MouseButton1Click:Connect(function()
    menuCollapsed = not menuCollapsed
    if menuCollapsed then
        mainFrame:TweenSize(UDim2.new(0, 160, 0, 22), "Out", "Quad", 0.2, true)
        collapseButton.Text = "+"
        contentFrame.Visible = false
    else
        mainFrame:TweenSize(UDim2.new(0, 160, 0, 85), "Out", "Quad", 0.2, true)
        collapseButton.Text = "-"
        contentFrame.Visible = true
    end
end)

LocalPlayer.CharacterAdded:Connect(function(newChar)
    Character = newChar
    Humanoid = newChar:WaitForChild("Humanoid")
    if freecamEnabled then
        disableFreecam()
        toggleBtn.Text = "TOGGLE"
        toggleBtn.BackgroundColor3 = Color3.fromRGB(30,30,30)
    end
end)

script.Destroying:Connect(function()
    disableFreecam()
    if screenGui then screenGui:Destroy() end
end)

Features & Information

Freecam
#No key

Community Comments (1)

micmasmicmasAug 12, 2026

i can't turn my camera to look behind me?

More Scripts for Universal Scripts