RSR script
Key RequiredUniversal

RSR script

Universal ScriptRSRstudioRSRstudio 921 views 7.4K executesUpdated Oct 3, 2026
5.0/ 5(2 votes)
20100% Positive
Lua Script•2124 lines (63914 chars)
--========================================================
-- RSR STUDIO - SHOOTER PANEL ENHANCED
-- ONE LOCAL SCRIPT
-- Existing tabs preserved: PVP / MOVEMENT / SETTINGS
-- Added: BETTER FPS + INFORMATION + INVISIBLE (LOCAL)
--========================================================

-- SERVICES
local Players = game:GetService("Players")
local UIS = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local Lighting = game:GetService("Lighting")
local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera

--========================================================
-- SETTINGS
--========================================================

local Settings = {
    OpenKey = Enum.KeyCode.K,

    -- PVP
    AimAssist = false,
    AimKey = Enum.UserInputType.MouseButton2,
    AimKeyName = "RIGHT MOUSE",
    ESP = false,
    Tracers = false,
    FOVEnabled = true,
    FOV = 120,
    AimSmoothness = 0.15,
    Hitbox = 0,

    -- MOVEMENT
    SpeedEnabled = false,
    Speed = 16,
    FlyEnabled = false,
    FlySpeed = 50,
    SpinEnabled = false,
    SpinSpeed = 5,

    -- CAMERA / FIRST PERSON
    CameraFOV = 120,
    ArmsEnabled = false,
    ArmDistance = 0,

    -- VISUALS
    RainEnabled = true,
    MirrorEnabled = true,
    NeonAnimations = true,

    -- BETTER FPS
    BetterFPSEnabled = false,

    -- INVISIBILITY
    Invisible = false,

    -- COLORS
    ESPColor = Color3.fromRGB(255, 70, 70),
    TracerColor = Color3.fromRGB(255, 255, 255),
    FOVColor = Color3.fromRGB(255, 255, 255),

    GuiOpen = true,
    SoundsEnabled = true,
}

-- Roblox's native Camera.FieldOfView cannot exceed 120 degrees.
local NATIVE_FOV_MAX = 120

--========================================================
-- UI SOUNDS + PRESS ANIMATION
-- Change the Id values below to any sound you like,
-- e.g. "rbxassetid://123456789"
--========================================================

local SoundService = game:GetService("SoundService")

local SoundIDs = {
    Click = {Id = "rbxasset://sounds/button.wav", Volume = 0.6},
    Toggle = {Id = "rbxasset://sounds/switch.wav", Volume = 0.6},
}

local function PlaySound(Name)
    if not Settings.SoundsEnabled then
        return
    end

    local Data = SoundIDs[Name]
    if not Data then
        return
    end

    local Sound = Instance.new("Sound")
    Sound.SoundId = Data.Id
    Sound.Volume = Data.Volume
    Sound.Parent = SoundService
    Sound:Play()

    task.delay(3, function()
        if Sound then
            Sound:Destroy()
        end
    end)
end

-- Button shrinks when pressed, springs back on release, plays a click sound.
local function AddPressAnimation(Button, SoundName)
    local Scale = Button:FindFirstChildOfClass("UIScale") or Instance.new("UIScale")
    Scale.Scale = 1
    Scale.Parent = Button

    Button.MouseButton1Down:Connect(function()
        TweenService:Create(
            Scale,
            TweenInfo.new(0.07, Enum.EasingStyle.Quad, Enum.EasingDirection.Out),
            {Scale = 0.94}
        ):Play()
    end)

    local function Release()
        TweenService:Create(
            Scale,
            TweenInfo.new(0.25, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
            {Scale = 1}
        ):Play()
    end

    Button.MouseButton1Up:Connect(Release)
    Button.MouseLeave:Connect(Release)

    Button.MouseButton1Click:Connect(function()
        PlaySound(SoundName or "Click")
    end)
end

--========================================================
-- GUI ROOT
--========================================================

local Gui = Instance.new("ScreenGui")
Gui.Name = "RSR_Studio_Shooter"
Gui.ResetOnSpawn = false
Gui.IgnoreGuiInset = true
Gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
Gui.Parent = LocalPlayer:WaitForChild("PlayerGui")

--========================================================
-- MAIN WINDOW
--========================================================

local Main = Instance.new("Frame")
Main.Name = "Main"
Main.Size = UDim2.new(0, 800, 0, 540)
Main.Position = UDim2.new(0.5, -400, 0.5, -270)
Main.BackgroundColor3 = Color3.fromRGB(7, 9, 14)
Main.BorderSizePixel = 0
Main.ClipsDescendants = true
Main.ZIndex = 5
Main.Parent = Gui

local MainCorner = Instance.new("UICorner")
MainCorner.CornerRadius = UDim.new(0, 26)
MainCorner.Parent = Main

local MainStroke = Instance.new("UIStroke")
MainStroke.Color = Color3.fromRGB(95, 105, 145)
MainStroke.Thickness = 1.5
MainStroke.Transparency = 0.1
MainStroke.Parent = Main

local MainGradient = Instance.new("UIGradient")
MainGradient.Rotation = 35
MainGradient.Color = ColorSequence.new({
    ColorSequenceKeypoint.new(0, Color3.fromRGB(8, 11, 20)),
    ColorSequenceKeypoint.new(0.5, Color3.fromRGB(11, 13, 21)),
    ColorSequenceKeypoint.new(1, Color3.fromRGB(5, 8, 13)),
})
MainGradient.Parent = Main

local MainScale = Instance.new("UIScale")
MainScale.Scale = 1
MainScale.Parent = Main

--========================================================
-- NEON BRAND / REFLECTION
--========================================================

local Reflection = Instance.new("Frame")
Reflection.Name = "ReflectionSweep"
Reflection.Size = UDim2.new(0, 180, 1.6, 0)
Reflection.Position = UDim2.new(-0.2, 0, -0.3, 0)
Reflection.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
Reflection.BackgroundTransparency = 0.94
Reflection.BorderSizePixel = 0
Reflection.Rotation = 18
Reflection.ZIndex = 8
Reflection.Parent = Main

local ReflectionGradient = Instance.new("UIGradient")
ReflectionGradient.Transparency = NumberSequence.new({
    NumberSequenceKeypoint.new(0, 1),
    NumberSequenceKeypoint.new(0.45, 0.85),
    NumberSequenceKeypoint.new(0.5, 0.2),
    NumberSequenceKeypoint.new(0.55, 0.85),
    NumberSequenceKeypoint.new(1, 1),
})
ReflectionGradient.Parent = Reflection

local GlassGlow = Instance.new("Frame")
GlassGlow.Name = "GlassGlow"
GlassGlow.Size = UDim2.new(1, -12, 1, -12)
GlassGlow.Position = UDim2.new(0, 6, 0, 6)
GlassGlow.BackgroundTransparency = 1
GlassGlow.BorderSizePixel = 0
GlassGlow.ZIndex = 7
GlassGlow.Parent = Main

local GlassStroke = Instance.new("UIStroke")
GlassStroke.Color = Color3.fromRGB(90, 210, 255)
GlassStroke.Thickness = 1
GlassStroke.Transparency = 0.72
GlassStroke.Parent = GlassGlow

local GlassCorner = Instance.new("UICorner")
GlassCorner.CornerRadius = UDim.new(0, 17)
GlassCorner.Parent = GlassGlow

--========================================================
-- EXTRA NEON / RTX-STYLE GUI FX
--========================================================

local NeonGlows = {}
for i, data in ipairs({
    {size = 2, transparency = 0.52},
    {size = 4, transparency = 0.70},
    {size = 7, transparency = 0.84},
    {size = 11, transparency = 0.92},
    {size = 16, transparency = 0.965},
}) do
    local Glow = Main:Clone()
    Glow.Name = "NeonGlow_" .. i
    Glow.BackgroundTransparency = 1
    Glow.BorderSizePixel = 0
    Glow.ClipsDescendants = true
    Glow.Position = UDim2.new(0, -data.size, 0, -data.size)
    Glow.Size = UDim2.new(1, data.size * 2, 1, data.size * 2)
    Glow.ZIndex = 3

    for _, child in ipairs(Glow:GetChildren()) do
        child:Destroy()
    end

    local Stroke = Instance.new("UIStroke")
    Stroke.Thickness = data.size
    Stroke.Transparency = data.transparency
    Stroke.Color = Color3.fromRGB(55, 245, 255)
    Stroke.Parent = Glow

    local Corner = Instance.new("UICorner")
    Corner.CornerRadius = UDim.new(0, 26 + data.size)
    Corner.Parent = Glow
    Glow.Parent = Main
    table.insert(NeonGlows, Stroke)
end

local RTXLabel = Instance.new("TextLabel")
RTXLabel.Name = "RTXStyle"
RTXLabel.Size = UDim2.new(0, 90, 0, 22)
RTXLabel.Position = UDim2.new(1, -105, 0, 20)
RTXLabel.BackgroundTransparency = 1
RTXLabel.Text = "RTX STYLE"
RTXLabel.TextSize = 10
RTXLabel.Font = Enum.Font.GothamBlack
RTXLabel.TextColor3 = Color3.fromRGB(80, 255, 245)
RTXLabel.TextStrokeTransparency = 0.35
RTXLabel.TextStrokeColor3 = Color3.fromRGB(20, 130, 255)
RTXLabel.ZIndex = 16
RTXLabel.Parent = Main

local NeonTitle = Instance.new("TextLabel")
NeonTitle.Name = "NeonRSRTitle"
NeonTitle.Size = UDim2.new(0, 500, 0, 40)
NeonTitle.Position = UDim2.new(0.5, -250, 0, 3)
NeonTitle.BackgroundTransparency = 1
NeonTitle.Text = "RSR SCRIPT STUDIO"
NeonTitle.TextSize = 28
NeonTitle.Font = Enum.Font.GothamBlack
NeonTitle.TextXAlignment = Enum.TextXAlignment.Center
NeonTitle.TextColor3 = Color3.fromRGB(110, 255, 248)
NeonTitle.TextStrokeTransparency = 0.04
NeonTitle.TextStrokeColor3 = Color3.fromRGB(0, 125, 255)
NeonTitle.ZIndex = 17
NeonTitle.Parent = Main

local NeonTitleGlow = NeonTitle:Clone()
NeonTitleGlow.Name = "NeonRSRTitleGlow"
NeonTitleGlow.TextTransparency = 0.65
NeonTitleGlow.ZIndex = 16
NeonTitleGlow.Parent = Main

-- Neon bushes / vines in every corner.
local BushLayer = Instance.new("Frame")
BushLayer.Name = "RTXCornerBushes"
BushLayer.Size = UDim2.fromScale(1, 1)
BushLayer.BackgroundTransparency = 1
BushLayer.ZIndex = 13
BushLayer.Parent = Main

local Bushes = {}
local function CreateBushCorner(xScale, yScale, flipX, flipY)
    local Holder = Instance.new("Frame")
    Holder.Size = UDim2.fromOffset(145, 115)
    Holder.Position = UDim2.new(xScale, flipX and -116 or -4, yScale, flipY and -91 or -4)
    Holder.BackgroundTransparency = 1
    Holder.ZIndex = 13
    Holder.Parent = BushLayer

    local BaseGlow = Instance.new("Frame")
    BaseGlow.Size = UDim2.fromOffset(118, 82)
    BaseGlow.Position = UDim2.new(0, flipX and 20 or 6, 0, flipY and 27 or 6)
    BaseGlow.BackgroundColor3 = Color3.fromRGB(30, 255, 220)
    BaseGlow.BackgroundTransparency = 0.91
    BaseGlow.BorderSizePixel = 0
    BaseGlow.ZIndex = 13
    BaseGlow.Parent = Holder
    local bc = Instance.new("UICorner")
    bc.CornerRadius = UDim.new(1, 0)
    bc.Parent = BaseGlow

    for i = 1, 40 do
        local Leaf = Instance.new("Frame")
        local px = (i % 5) * 18 + math.random(-5, 5)
        local py = math.floor((i - 1) / 5) * 20 + math.random(-5, 5)
        Leaf.Size = UDim2.fromOffset(math.random(16, 38), math.random(12, 30))
        Leaf.Position = UDim2.new(0, flipX and (88-px) or px, 0, flipY and (70-py) or py)
        Leaf.Rotation = math.random(-55, 55)
        Leaf.BackgroundColor3 = Color3.fromRGB(10 + math.random(0, 35), 110 + math.random(0, 120), 70 + math.random(0, 150))
        Leaf.BackgroundTransparency = math.random(28, 55) / 100
        Leaf.BorderSizePixel = 0
        Leaf.ZIndex = 14
        Leaf.Parent = Holder
        local lc = Instance.new("UICorner")
        lc.CornerRadius = UDim.new(1, 0)
        lc.Parent = Leaf
        local ls = Instance.new("UIStroke")
        ls.Thickness = math.random(1, 2)
        ls.Transparency = 0.32
        ls.Color = Color3.fromRGB(70, 255, 230)
        ls.Parent = Leaf
        table.insert(Bushes, {part = Leaf, base = Leaf.Rotation, phase = math.random() * math.pi * 2})
    end
end

CreateBushCorner(0, 0, false, false)
CreateBushCorner(1, 0, true, false)
CreateBushCorner(0, 1, false, true)
CreateBushCorner(1, 1, true, true)

local CornerRays = {}
for corner = 1, 4 do
    for ray = 1, 6 do
        local Beam = Instance.new("Frame")
        Beam.Name = "RTX_CornerRay_" .. corner .. "_" .. ray
        Beam.Size = UDim2.fromOffset(math.random(30, 75), math.random(1, 3))
        Beam.BackgroundColor3 = Color3.fromRGB(70, 255, 240)
        Beam.BackgroundTransparency = 0.68
        Beam.BorderSizePixel = 0
        Beam.ZIndex = 12
        Beam.AnchorPoint = Vector2.new(0.5, 0.5)
        Beam.Rotation = ((corner == 2 or corner == 4) and -1 or 1) * math.random(18, 48)
        local x = (corner == 2 or corner == 4) and 1 or 0
        local y = (corner >= 3) and 1 or 0
        Beam.Position = UDim2.new(x, x == 1 and -28 or 28, y, y == 1 and -28 or 28)
        Beam.Parent = BushLayer
        local c = Instance.new("UICorner")
        c.CornerRadius = UDim.new(1, 0)
        c.Parent = Beam
        table.insert(CornerRays, {part = Beam, phase = math.random() * math.pi * 2})
    end
end

-- Small reflective strips for a glass / ray-traced look.
for i = 1, 8 do
    local Strip = Instance.new("Frame")
    Strip.Name = "RTXReflectiveStrip" .. i
    Strip.Size = UDim2.new(0, 70 + i * 10, 0, 1)
    Strip.Position = UDim2.new(0, 20 + (i - 1) * 15, 1, -18 - (i - 1) * 4)
    Strip.BackgroundColor3 = Color3.fromRGB(90, 245, 255)
    Strip.BackgroundTransparency = 0.6
    Strip.BorderSizePixel = 0
    Strip.Rotation = -5
    Strip.ZIndex = 14
    Strip.Parent = Main
end

--========================================================
-- RAIN OVERLAY
--========================================================

local Rain = Instance.new("Frame")
Rain.Name = "Rain"
Rain.Size = UDim2.fromScale(1, 1)
Rain.BackgroundTransparency = 1
Rain.ClipsDescendants = true
Rain.ZIndex = 4
Rain.Parent = Main

local function CreateRainDrop()
    if not Settings.RainEnabled or not Rain.Parent then
        return
    end

    local Drop = Instance.new("Frame")
    Drop.Name = "Drop"

    local height = math.random(18, 48)
    local width = math.random(1, 2)

    Drop.Size = UDim2.new(0, width, 0, height)
    Drop.Position = UDim2.new(math.random(-10, 110) / 100, 0, -0.1, 0)
    Drop.BackgroundColor3 = Color3.fromRGB(90, 175, 255)
    Drop.BackgroundTransparency = math.random(35, 72) / 100
    Drop.BorderSizePixel = 0
    Drop.Rotation = math.random(-8, 8)
    Drop.ZIndex = 4
    Drop.Parent = Rain

    local DropCorner = Instance.new("UICorner")
    DropCorner.CornerRadius = UDim.new(1, 0)
    DropCorner.Parent = Drop

    local duration = math.random(55, 120) / 100
    local xShift = math.random(-25, 25) / 1000

    TweenService:Create(
        Drop,
        TweenInfo.new(duration, Enum.EasingStyle.Linear),
        {
            Position = UDim2.new(
                Drop.Position.X.Scale + xShift,
                0,
                1.2,
                0
            ),
            BackgroundTransparency = 0.94,
        }
    ):Play()

    task.delay(duration, function()
        if Drop then
            Drop:Destroy()
        end
    end)
end

task.spawn(function()
    while Gui.Parent do
        if Settings.RainEnabled then
            for _ = 1, 2 do
                CreateRainDrop()
            end
        end
        task.wait(0.045)
    end
end)

--========================================================
-- DECORATIVE BACKGROUND / CURVATURE
--========================================================

local AccentTop = Instance.new("Frame")
AccentTop.Size = UDim2.new(1, -40, 0, 2)
AccentTop.Position = UDim2.new(0, 20, 0, 70)
AccentTop.BorderSizePixel = 0
AccentTop.ZIndex = 14
AccentTop.Parent = Main

local AccentGradient = Instance.new("UIGradient")
AccentGradient.Color = ColorSequence.new({
    ColorSequenceKeypoint.new(0, Color3.fromRGB(0, 255, 230)),
    ColorSequenceKeypoint.new(0.5, Color3.fromRGB(95, 140, 255)),
    ColorSequenceKeypoint.new(1, Color3.fromRGB(255, 70, 210)),
})
AccentGradient.Parent = AccentTop

local AccentCorner = Instance.new("UICorner")
AccentCorner.CornerRadius = UDim.new(1, 0)
AccentCorner.Parent = AccentTop

--========================================================
-- SUBTITLE
--========================================================

local SubTitle = Instance.new("TextLabel")
SubTitle.Size = UDim2.new(0, 450, 0, 25)
SubTitle.Position = UDim2.new(0, 27, 0, 52)
SubTitle.BackgroundTransparency = 1
SubTitle.Text = "DEVELOPER CONTROL PANEL"
SubTitle.TextColor3 = Color3.fromRGB(110, 120, 140)
SubTitle.TextSize = 11
SubTitle.Font = Enum.Font.GothamBold
SubTitle.TextXAlignment = Enum.TextXAlignment.Left
SubTitle.ZIndex = 14
SubTitle.Parent = Main

--========================================================
-- SIDEBAR / CONTENT
--========================================================

local Sidebar = Instance.new("Frame")
Sidebar.Size = UDim2.new(0, 185, 1, -105)
Sidebar.Position = UDim2.new(0, 15, 0, 92)
Sidebar.BackgroundColor3 = Color3.fromRGB(12, 15, 22)
Sidebar.BackgroundTransparency = 0.08
Sidebar.BorderSizePixel = 0
Sidebar.ZIndex = 10
Sidebar.Parent = Main

local SidebarCorner = Instance.new("UICorner")
SidebarCorner.CornerRadius = UDim.new(0, 14)
SidebarCorner.Parent = Sidebar

local SidebarStroke = Instance.new("UIStroke")
SidebarStroke.Color = Color3.fromRGB(60, 75, 105)
SidebarStroke.Transparency = 0.4
SidebarStroke.Parent = Sidebar

local Content = Instance.new("Frame")
Content.Size = UDim2.new(1, -220, 1, -105)
Content.Position = UDim2.new(0, 205, 0, 92)
Content.BackgroundTransparency = 1
Content.ZIndex = 10
Content.Parent = Main

--========================================================
-- TABS (ORIGINAL TABS KEPT)
--========================================================

local Tabs = {}
local Pages = {}

local function CreateTab(Name, Text, Order)
    local Button = Instance.new("TextButton")
    Button.Name = Name
    Button.Size = UDim2.new(1, -20, 0, 45)
    Button.Position = UDim2.new(0, 10, 0, 10 + (Order - 1) * 55)
    Button.BackgroundColor3 = Color3.fromRGB(20, 24, 34)
    Button.BackgroundTransparency = 0.4
    Button.BorderSizePixel = 0
    Button.Text = Text
    Button.TextColor3 = Color3.fromRGB(160, 165, 180)
    Button.TextSize = 13
    Button.Font = Enum.Font.GothamBold
    Button.ZIndex = 12
    Button.AutoButtonColor = false
    Button.Parent = Sidebar

    local Corner = Instance.new("UICorner")
    Corner.CornerRadius = UDim.new(0, 10)
    Corner.Parent = Button

    local Stroke = Instance.new("UIStroke")
    Stroke.Color = Color3.fromRGB(70, 85, 120)
    Stroke.Transparency = 0.75
    Stroke.Parent = Button

    Tabs[Name] = Button
    AddPressAnimation(Button, "Click")

    Button.MouseEnter:Connect(function()
        if Button.BackgroundColor3 ~= Color3.fromRGB(55, 65, 90) then
            TweenService:Create(
                Button,
                TweenInfo.new(0.15, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
                {BackgroundColor3 = Color3.fromRGB(33, 39, 55)}
            ):Play()
        end
    end)

    Button.MouseLeave:Connect(function()
        if Button.BackgroundColor3 ~= Color3.fromRGB(55, 65, 90) then
            TweenService:Create(
                Button,
                TweenInfo.new(0.15, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
                {BackgroundColor3 = Color3.fromRGB(20, 24, 34)}
            ):Play()
        end
    end)

    return Button
end

local function CreatePage(Name)
    local Page = Instance.new("ScrollingFrame")
    Page.Name = Name
    Page.Size = UDim2.fromScale(1, 1)
    Page.BackgroundTransparency = 1
    Page.BorderSizePixel = 0
    Page.ScrollBarThickness = 3
    Page.ScrollBarImageColor3 = Color3.fromRGB(80, 90, 120)
    Page.CanvasSize = UDim2.new(0, 0, 0, 1000)
    Page.AutomaticCanvasSize = Enum.AutomaticSize.Y
    Page.ScrollingDirection = Enum.ScrollingDirection.Y
    Page.Visible = false
    Page.ZIndex = 11
    Page.Parent = Content

    Pages[Name] = Page
    return Page
end

-- Existing tabs
CreateTab("PVP", "PVP", 1)
CreateTab("MOVEMENT", "MOVEMENT", 2)
CreateTab("SETTINGS", "SETTINGS", 3)
-- New tab
CreateTab("BETTERFPS", "BETTER FPS", 4)
CreateTab("INFO", "INFORMATION", 5)

local PVP = CreatePage("PVP")
local Movement = CreatePage("MOVEMENT")
local SettingsPage = CreatePage("SETTINGS")
local BetterFPS = CreatePage("BETTERFPS")
local InfoPage = CreatePage("INFO")

local function SwitchPage(Name)
    for PageName, Page in pairs(Pages) do
        local Show = PageName == Name
        if Show and not Page.Visible then
            Page.Position = UDim2.new(0, 0, 0, 18)
            Page.Visible = true
            TweenService:Create(
                Page,
                TweenInfo.new(0.28, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
                {Position = UDim2.new(0, 0, 0, 0)}
            ):Play()
        else
            Page.Visible = Show
        end
    end

    for TabName, Button in pairs(Tabs) do
        local Selected = TabName == Name
        TweenService:Create(
            Button,
            TweenInfo.new(0.16, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
            {
                BackgroundColor3 = Selected
                    and Color3.fromRGB(55, 65, 90)
                    or Color3.fromRGB(20, 24, 34),
                TextColor3 = Selected
                    and Color3.fromRGB(255, 255, 255)
                    or Color3.fromRGB(160, 165, 180),
            }
        ):Play()
    end
end

for Name, Button in pairs(Tabs) do
    Button.MouseButton1Click:Connect(function()
        SwitchPage(Name)
    end)
end

SwitchPage("PVP")

--========================================================
-- UI HELPERS
--========================================================

local function CreateSection(Page, Text, Y)
    local Label = Instance.new("TextLabel")
    Label.Size = UDim2.new(1, -20, 0, 30)
    Label.Position = UDim2.new(0, 10, 0, Y)
    Label.BackgroundTransparency = 1
    Label.Text = Text
    Label.TextColor3 = Color3.fromRGB(110, 150, 255)
    Label.TextSize = 12
    Label.Font = Enum.Font.GothamBold
    Label.TextXAlignment = Enum.TextXAlignment.Left
    Label.ZIndex = 12
    Label.Parent = Page
    return Label
end

local function CreateToggle(Page, Text, Y, Default, Callback)
    local Button = Instance.new("TextButton")
    Button.Size = UDim2.new(1, -20, 0, 42)
    Button.Position = UDim2.new(0, 10, 0, Y)
    Button.BackgroundColor3 = Color3.fromRGB(18, 22, 31)
    Button.BorderSizePixel = 0
    Button.Text = ""
    Button.ZIndex = 12
    Button.AutoButtonColor = false
    Button.Parent = Page

    local Corner = Instance.new("UICorner")
    Corner.CornerRadius = UDim.new(0, 10)
    Corner.Parent = Button

    local Stroke = Instance.new("UIStroke")
    Stroke.Color = Color3.fromRGB(62, 73, 97)
    Stroke.Transparency = 0.68
    Stroke.Parent = Button

    local Label = Instance.new("TextLabel")
    Label.Size = UDim2.new(1, -65, 1, 0)
    Label.Position = UDim2.new(0, 15, 0, 0)
    Label.BackgroundTransparency = 1
    Label.Text = Text
    Label.TextColor3 = Color3.fromRGB(220, 223, 230)
    Label.TextSize = 13
    Label.Font = Enum.Font.GothamMedium
    Label.TextXAlignment = Enum.TextXAlignment.Left
    Label.ZIndex = 13
    Label.Parent = Button

    local Status = Instance.new("TextLabel")
    Status.Size = UDim2.new(0, 45, 1, 0)
    Status.Position = UDim2.new(1, -55, 0, 0)
    Status.BackgroundTransparency = 1
    Status.TextSize = 11
    Status.Font = Enum.Font.GothamBold
    Status.ZIndex = 13
    Status.Parent = Button

    local State = Default

    local StatusScale = Instance.new("UIScale")
    StatusScale.Parent = Status

    local function Update(Animate)
        Status.Text = State and "ON" or "OFF"
        Status.TextColor3 = State
            and Color3.fromRGB(80, 255, 150)
            or Color3.fromRGB(120, 125, 135)

        local TargetColor = State
            and Color3.fromRGB(25, 38, 38)
            or Color3.fromRGB(18, 22, 31)

        if Animate then
            TweenService:Create(
                Button,
                TweenInfo.new(0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
                {BackgroundColor3 = TargetColor}
            ):Play()

            StatusScale.Scale = 1.6
            TweenService:Create(
                StatusScale,
                TweenInfo.new(0.35, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
                {Scale = 1}
            ):Play()
        else
            Button.BackgroundColor3 = TargetColor
        end
    end

    AddPressAnimation(Button, "Toggle")

    Button.MouseEnter:Connect(function()
        TweenService:Create(
            Button,
            TweenInfo.new(0.12, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
            {Size = UDim2.new(1, -16, 0, 44)}
        ):Play()
    end)

    Button.MouseLeave:Connect(function()
        TweenService:Create(
            Button,
            TweenInfo.new(0.12, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
            {Size = UDim2.new(1, -20, 0, 42)}
        ):Play()
    end)

    Button.MouseButton1Click:Connect(function()
        State = not State
        Update(true)
        Callback(State)
    end)

    Update()
    return Button
end

local function CreateSlider(Page, Text, Y, Min, Max, Default, Callback)
    local Holder = Instance.new("Frame")
    Holder.Size = UDim2.new(1, -20, 0, 65)
    Holder.Position = UDim2.new(0, 10, 0, Y)
    Holder.BackgroundColor3 = Color3.fromRGB(18, 22, 31)
    Holder.BorderSizePixel = 0
    Holder.ZIndex = 12
    Holder.Parent = Page

    local Corner = Instance.new("UICorner")
    Corner.CornerRadius = UDim.new(0, 10)
    Corner.Parent = Holder

    local Stroke = Instance.new("UIStroke")
    Stroke.Color = Color3.fromRGB(62, 73, 97)
    Stroke.Transparency = 0.68
    Stroke.Parent = Holder

    local Label = Instance.new("TextLabel")
    Label.Size = UDim2.new(0.7, 0, 0, 28)
    Label.Position = UDim2.new(0, 15, 0, 3)
    Label.BackgroundTransparency = 1
    Label.Text = Text
    Label.TextColor3 = Color3.fromRGB(220, 223, 230)
    Label.TextSize = 12
    Label.Font = Enum.Font.GothamMedium
    Label.TextXAlignment = Enum.TextXAlignment.Left
    Label.ZIndex = 13
    Label.Parent = Holder

    local Value = Instance.new("TextLabel")
    Value.Size = UDim2.new(0, 80, 0, 28)
    Value.Position = UDim2.new(1, -95, 0, 3)
    Value.BackgroundTransparency = 1
    Value.TextColor3 = Color3.fromRGB(110, 150, 255)
    Value.TextSize = 12
    Value.Font = Enum.Font.GothamBold
    Value.ZIndex = 13
    Value.Parent = Holder

    local Bar = Instance.new("Frame")
    Bar.Size = UDim2.new(1, -30, 0, 5)
    Bar.Position = UDim2.new(0, 15, 0, 46)
    Bar.BackgroundColor3 = Color3.fromRGB(45, 50, 65)
    Bar.BorderSizePixel = 0
    Bar.ZIndex = 13
    Bar.Parent = Holder

    local BarCorner = Instance.new("UICorner")
    BarCorner.CornerRadius = UDim.new(1, 0)
    BarCorner.Parent = Bar

    local Fill = Instance.new("Frame")
    local InitialPercent = math.clamp((Default - Min) / math.max(Max - Min, 0.0001), 0, 1)
    Fill.Size = UDim2.new(InitialPercent, 0, 1, 0)
    Fill.BackgroundColor3 = Color3.fromRGB(90, 130, 255)
    Fill.BorderSizePixel = 0
    Fill.ZIndex = 14
    Fill.Parent = Bar

    local FillCorner = Instance.new("UICorner")
    FillCorner.CornerRadius = UDim.new(1, 0)
    FillCorner.Parent = Fill

    local Knob = Instance.new("Frame")
    Knob.AnchorPoint = Vector2.new(0.5, 0.5)
    Knob.Size = UDim2.fromOffset(10, 10)
    Knob.Position = UDim2.new(InitialPercent, 0, 0.5, 0)
    Knob.BackgroundColor3 = Color3.fromRGB(205, 225, 255)
    Knob.BorderSizePixel = 0
    Knob.ZIndex = 15
    Knob.Parent = Bar

    local KnobCorner = Instance.new("UICorner")
    KnobCorner.CornerRadius = UDim.new(1, 0)
    KnobCorner.Parent = Knob

    local Dragging = false
    local LastNumber = Default

    local function FormatNumber(Number)
        if Max - Min >= 10 then
            return math.floor(Number + 0.5)
        end
        return math.floor(Number * 100 + 0.5) / 100
    end

    local function SetValue(X)
        local Percent = math.clamp(
            (X - Bar.AbsolutePosition.X) / math.max(Bar.AbsoluteSize.X, 1),
            0,
            1
        )

        local Number = FormatNumber(Min + (Max - Min) * Percent)
        LastNumber = Number
        local FinalPercent = math.clamp((Number - Min) / math.max(Max - Min, 0.0001), 0, 1)

        Fill.Size = UDim2.new(FinalPercent, 0, 1, 0)
        Knob.Position = UDim2.new(FinalPercent, 0, 0.5, 0)
        Value.Text = tostring(Number)
        Callback(Number)
    end

    Bar.InputBegan:Connect(function(Input)
        if Input.UserInputType == Enum.UserInputType.MouseButton1 then
            Dragging = true
            PlaySound("Click")
            TweenService:Create(
                Knob,
                TweenInfo.new(0.15, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
                {Size = UDim2.fromOffset(16, 16)}
            ):Play()
            SetValue(Input.Position.X)
        end
    end)

    UIS.InputChanged:Connect(function(Input)
        if Dragging and Input.UserInputType == Enum.UserInputType.MouseMovement then
            SetValue(Input.Position.X)
        end
    end)

    UIS.InputEnded:Connect(function(Input)
        if Input.UserInputType == Enum.UserInputType.MouseButton1 then
            if Dragging then
                TweenService:Create(
                    Knob,
                    TweenInfo.new(0.2, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
                    {Size = UDim2.fromOffset(10, 10)}
                ):Play()
            end
            Dragging = false
        end
    end)

    Value.Text = tostring(LastNumber)
    Callback(LastNumber)
    return Holder
end

local function CreateInfo(Page, Text, Y, Height)
    local Info = Instance.new("TextLabel")
    Info.Size = UDim2.new(1, -20, 0, Height)
    Info.Position = UDim2.new(0, 10, 0, Y)
    Info.BackgroundColor3 = Color3.fromRGB(18, 22, 31)
    Info.BorderSizePixel = 0
    Info.Text = Text
    Info.TextColor3 = Color3.fromRGB(190, 195, 210)
    Info.TextSize = 12
    Info.Font = Enum.Font.GothamMedium
    Info.TextWrapped = true
    Info.TextXAlignment = Enum.TextXAlignment.Left
    Info.TextYAlignment = Enum.TextYAlignment.Center
    Info.ZIndex = 12
    Info.Parent = Page

    local Corner = Instance.new("UICorner")
    Corner.CornerRadius = UDim.new(0, 12)
    Corner.Parent = Info

    local Stroke = Instance.new("UIStroke")
    Stroke.Color = Color3.fromRGB(62, 73, 97)
    Stroke.Transparency = 0.7
    Stroke.Parent = Info

    return Info
end

--========================================================
-- PVP
--========================================================

CreateSection(PVP, "COMBAT", 10)

CreateToggle(PVP, "Aim Assist", 45, false, function(Value)
    Settings.AimAssist = Value
end)

local AimKeyButton = Instance.new("TextButton")
AimKeyButton.Size = UDim2.new(1, -20, 0, 42)
AimKeyButton.Position = UDim2.new(0, 10, 0, 95)
AimKeyButton.BackgroundColor3 = Color3.fromRGB(18, 22, 31)
AimKeyButton.BorderSizePixel = 0
AimKeyButton.Text = "AIM KEY     RIGHT MOUSE"
AimKeyButton.TextColor3 = Color3.fromRGB(220, 223, 230)
AimKeyButton.TextSize = 13
AimKeyButton.Font = Enum.Font.GothamMedium
AimKeyButton.ZIndex = 12
AimKeyButton.AutoButtonColor = false
AimKeyButton.Parent = PVP

local AimKeyCorner = Instance.new("UICorner")
AimKeyCorner.CornerRadius = UDim.new(0, 10)
AimKeyCorner.Parent = AimKeyButton
AddPressAnimation(AimKeyButton, "Click")

AimKeyButton.MouseButton1Click:Connect(function()
    if Settings.AimKey == Enum.UserInputType.MouseButton2 then
        Settings.AimKey = Enum.UserInputType.MouseButton1
        Settings.AimKeyName = "LEFT MOUSE"
    else
        Settings.AimKey = Enum.UserInputType.MouseButton2
        Settings.AimKeyName = "RIGHT MOUSE"
    end
    AimKeyButton.Text = "AIM KEY     " .. Settings.AimKeyName
end)

CreateToggle(PVP, "ESP Players", 145, false, function(Value)
    Settings.ESP = Value
end)

CreateToggle(PVP, "Tracers", 195, false, function(Value)
    Settings.Tracers = Value
end)

CreateToggle(PVP, "FOV Circle", 245, true, function(Value)
    Settings.FOVEnabled = Value
end)

CreateSection(PVP, "AIM / HEAD HITBOX", 315)

CreateSlider(PVP, "FOV", 350, 30, 500, 120, function(Value)
    Settings.FOV = Value
end)

CreateSlider(PVP, "HEAD HITBOX", 425, 0, 10, 0, function(Value)
    Settings.Hitbox = Value
end)

CreateSlider(PVP, "AIM SMOOTHNESS", 500, 0.01, 1, 0.15, function(Value)
    Settings.AimSmoothness = Value
end)

--========================================================
-- MOVEMENT
--========================================================

CreateSection(Movement, "MOVEMENT", 10)

CreateToggle(Movement, "Speed", 45, false, function(Value)
    Settings.SpeedEnabled = Value
end)

CreateSlider(Movement, "Run Speed", 95, 16, 1000, 16, function(Value)
    Settings.Speed = Value
end)

CreateToggle(Movement, "Fly", 175, false, function(Value)
    Settings.FlyEnabled = Value
end)

CreateSlider(Movement, "Fly Speed", 225, 10, 1000, 50, function(Value)
    Settings.FlySpeed = Value
end)

CreateToggle(Movement, "INVISIBLE", 305, false, function(Value)
    Settings.Invisible = Value
end)


CreateToggle(Movement, "Spin", 360, false, function(Value)
    Settings.SpinEnabled = Value
end)

CreateSlider(Movement, "Spin Speed", 410, 1, 30, 5, function(Value)
    Settings.SpinSpeed = Value
end)

--========================================================
-- SETTINGS
--========================================================

CreateSection(SettingsPage, "RSR STUDIO", 10)

CreateInfo(SettingsPage,
    "RSR STUDIO SHOOTER\n\n" ..
    "K  =  OPEN / CLOSE\n" ..
    "Aim Assist works while holding your selected mouse button.\n" ..
    "Head Hitbox changes the local visual size of the head.\n" ..
    "ESP remains active after players respawn while the toggle is ON.",
    45,
    130
)

CreateSection(SettingsPage, "CAMERA", 185)

local CameraFOVInfo = CreateInfo(
    SettingsPage,
    "Native Roblox camera FOV supports up to 120°. The slider below is 80–240° as requested; values above 120° are capped by the engine.",
    215,
    60
)

CreateSlider(SettingsPage, "CAMERA FOV (80-240)", 285, 80, 240, 120, function(Value)
    Settings.CameraFOV = Value
    local Actual = math.clamp(Value, 80, NATIVE_FOV_MAX)
    if Camera then
        Camera.FieldOfView = Actual
    end
    CameraFOVInfo.Text = string.format(
        "Selected FOV: %d°\nActual Roblox FOV: %d° (engine max 120°)",
        Value,
        Actual
    )
end)

CreateToggle(SettingsPage, "FIRST PERSON ARMS", 365, false, function(Value)
    Settings.ArmsEnabled = Value
end)

CreateSlider(SettingsPage, "ARM DISTANCE", 415, 0, 3, 0, function(Value)
    Settings.ArmDistance = Value
end)

CreateToggle(SettingsPage, "GUI RAIN", 495, true, function(Value)
    Settings.RainEnabled = Value
end)

CreateToggle(SettingsPage, "MIRROR REFLECTION", 545, true, function(Value)
    Settings.MirrorEnabled = Value
end)

CreateToggle(SettingsPage, "NEON ANIMATIONS", 595, true, function(Value)
    Settings.NeonAnimations = Value
end)

CreateSection(SettingsPage, "COLORS", 655)

local Colors = {
    Color3.fromRGB(255, 70, 70),
    Color3.fromRGB(255, 170, 60),
    Color3.fromRGB(255, 240, 70),
    Color3.fromRGB(80, 255, 130),
    Color3.fromRGB(70, 180, 255),
    Color3.fromRGB(160, 90, 255),
    Color3.fromRGB(255, 80, 200),
}

local ColorIndex = 1

local ColorButton = Instance.new("TextButton")
ColorButton.Size = UDim2.new(1, -20, 0, 45)
ColorButton.Position = UDim2.new(0, 10, 0, 690)
ColorButton.BackgroundColor3 = Color3.fromRGB(18, 22, 31)
ColorButton.BorderSizePixel = 0
ColorButton.Text = "CHANGE ESP / TRACER COLOR"
ColorButton.TextColor3 = Colors[1]
ColorButton.TextSize = 13
ColorButton.Font = Enum.Font.GothamBold
ColorButton.ZIndex = 12
ColorButton.AutoButtonColor = false
ColorButton.Parent = SettingsPage

local ColorCorner = Instance.new("UICorner")
ColorCorner.CornerRadius = UDim.new(0, 10)
ColorCorner.Parent = ColorButton
AddPressAnimation(ColorButton, "Click")

ColorButton.MouseButton1Click:Connect(function()
    ColorIndex += 1
    if ColorIndex > #Colors then
        ColorIndex = 1
    end

    Settings.ESPColor = Colors[ColorIndex]
    Settings.TracerColor = Colors[ColorIndex]
    ColorButton.TextColor3 = Colors[ColorIndex]
end)

CreateToggle(SettingsPage, "UI SOUNDS", 750, true, function(Value)
    Settings.SoundsEnabled = Value
end)

--========================================================
-- INFORMATION
--========================================================

CreateSection(InfoPage, "RSR SCRIPT STUDIO", 10)

local AboutCard = CreateInfo(
    InfoPage,
    "✦ RSR SCRIPT STUDIO ✦\n\n" ..
    "Created for Roblox projects and custom control panels.\n" ..
    "I make scripts, GUI systems, visual effects and gameplay tools.\n\n" ..
    "ROBLOX: Cukier_Zzz\n" ..
    "ROBLOX ACCOUNT: Cukier_Zzz\nFollow Cukier_Zzz on Roblox for new scripts and projects.",
    45,
    185
)

CreateInfo(
    InfoPage,
    "⌨  PANEL KEY\n\nK = OPEN / CLOSE\nThe panel opens and closes with the K key.",
    245,
    105
)

CreateInfo(
    InfoPage,
    "⚡ VISUAL SYSTEMS\n\nNeon interface, animated reflections, rain, RTX-style corner bushes and smooth UI motion are client-side visual effects.",
    365,
    105
)

CreateInfo(
    InfoPage,
    "◈ INVISIBLE\n\nThis all-in-one LocalScript hides your character locally on your own screen. A LocalScript alone cannot force other players' clients to render your character as invisible because replication is controlled by the server.",
    485,
    115
)

--========================================================
-- BETTER FPS
--========================================================

CreateSection(BetterFPS, "BETTER FPS", 10)

CreateToggle(BetterFPS, "Better FPS", 45, false, function(Value)
    Settings.BetterFPSEnabled = Value
end)

CreateInfo(BetterFPS,
    "When enabled, this locally removes or disables many visual effects that can cost FPS: Decals, Textures, particles, trails, beams, smoke, fire, sparkles and selected post-processing. It is designed for lower-end or busy maps.",
    95,
    105
)

CreateInfo(BetterFPS,
    "Classic texture mode: texture/decal transparency is stored and restored when Better FPS is switched OFF. New descendants are also optimized while the mode is ON.",
    210,
    85
)

CreateInfo(BetterFPS,
    "The existing PVP / MOVEMENT / SETTINGS tabs are unchanged. BETTER FPS is an added tab.",
    305,
    65
)

--========================================================
-- NEON ANIMATION LOOP
--========================================================

local NeonTime = 0
RunService.RenderStepped:Connect(function(dt)
    NeonTime += dt
    if not Settings.NeonAnimations then
        return
    end

    local hue = (NeonTime * 0.055) % 1
    local neonColor = Color3.fromHSV(hue, 0.78, 1)

    RTXLabel.TextColor3 = neonColor
    NeonTitle.TextColor3 = neonColor
    NeonTitle.TextStrokeColor3 = Color3.fromHSV((hue + 0.08) % 1, 0.9, 1)
    NeonTitleGlow.TextColor3 = Color3.fromHSV((hue + 0.03) % 1, 0.85, 1)
    NeonTitleGlow.TextStrokeColor3 = neonColor
    NeonTitleGlow.TextTransparency = 0.55 + 0.16 * (0.5 + 0.5 * math.sin(NeonTime * 2.4))
    MainStroke.Color = neonColor
    AccentTop.BackgroundColor3 = neonColor

    for i, Stroke in ipairs(NeonGlows) do
        Stroke.Color = Color3.fromHSV((hue + i * 0.045) % 1, 0.8, 1)
    end

    Reflection.Position = UDim2.new((math.sin(NeonTime * 0.65) * 0.55) + 0.25, 0, -0.3, 0)

    for _, item in ipairs(CornerRays) do
        if item.part.Parent then
            item.part.BackgroundColor3 = neonColor
            item.part.BackgroundTransparency = 0.54 + 0.25 * (0.5 + 0.5 * math.sin(NeonTime * 2.8 + item.phase))
        end
    end

    for _, info in ipairs(Bushes) do
        if info.part.Parent then
            info.part.Rotation = info.base + math.sin(NeonTime * 1.4 + info.phase) * 7
        end
    end
end)

--========================================================
-- FOV CIRCLE
--========================================================

local FOVCircle = Instance.new("Frame")
FOVCircle.Name = "FOVCircle"
FOVCircle.AnchorPoint = Vector2.new(0.5, 0.5)
FOVCircle.Position = UDim2.fromScale(0.5, 0.5)
FOVCircle.Size = UDim2.fromOffset(Settings.FOV * 2, Settings.FOV * 2)
FOVCircle.BackgroundTransparency = 1
FOVCircle.BorderSizePixel = 0
FOVCircle.ZIndex = 100
FOVCircle.Parent = Gui

local FOVCorner = Instance.new("UICorner")
FOVCorner.CornerRadius = UDim.new(1, 0)
FOVCorner.Parent = FOVCircle

local FOVStroke = Instance.new("UIStroke")
FOVStroke.Thickness = 1.5
FOVStroke.Transparency = 0.15
FOVStroke.Parent = FOVCircle

local FOVGlow = Instance.new("UIStroke")
FOVGlow.Thickness = 4
FOVGlow.Transparency = 0.85
FOVGlow.Parent = FOVCircle

--========================================================
-- ESP
--========================================================

local ESPObjects = {}

local function RemoveESP(Player)
    local Object = ESPObjects[Player]
    if Object then
        if Object.Highlight and Object.Highlight.Parent then
            Object.Highlight:Destroy()
        end
        if Object.Billboard and Object.Billboard.Parent then
            Object.Billboard:Destroy()
        end
    end
    ESPObjects[Player] = nil
end

local function CreateESP(Player)
    if Player == LocalPlayer then
        return
    end

    local Character = Player.Character
    if not Character then
        return
    end

    RemoveESP(Player)

    local Highlight = Instance.new("Highlight")
    Highlight.Name = "RSR_ESP"
    Highlight.FillTransparency = 0.72
    Highlight.OutlineTransparency = 0
    Highlight.FillColor = Settings.ESPColor
    Highlight.OutlineColor = Settings.ESPColor
    Highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
    Highlight.Adornee = Character
    Highlight.Parent = Character

    local Head = Character:FindFirstChild("Head")
    local Billboard

    if Head then
        Billboard = Instance.new("BillboardGui")
        Billboard.Name = "RSR_ESP_Name"
        Billboard.Adornee = Head
        Billboard.Size = UDim2.new(0, 150, 0, 35)
        Billboard.StudsOffset = Vector3.new(0, 2.5, 0)
        Billboard.AlwaysOnTop = true
        Billboard.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
        Billboard.Parent = Head

        local NameLabel = Instance.new("TextLabel")
        NameLabel.Size = UDim2.fromScale(1, 1)
        NameLabel.BackgroundTransparency = 1
        NameLabel.Text = Player.DisplayName
        NameLabel.TextColor3 = Settings.ESPColor
        NameLabel.TextStrokeTransparency = 0.3
        NameLabel.TextStrokeColor3 = Color3.fromRGB(0, 0, 0)
        NameLabel.TextSize = 13
        NameLabel.Font = Enum.Font.GothamBold
        NameLabel.Parent = Billboard
    end

    ESPObjects[Player] = {
        Highlight = Highlight,
        Billboard = Billboard,
    }
end

local function ApplyESPToAll()
    if not Settings.ESP then
        return
    end

    for _, Player in ipairs(Players:GetPlayers()) do
        if Player ~= LocalPlayer and Player.Character then
            CreateESP(Player)
        end
    end
end

for _, Player in ipairs(Players:GetPlayers()) do
    if Player ~= LocalPlayer then
        Player.CharacterAdded:Connect(function()
            task.wait(0.25)
            if Settings.ESP then
                CreateESP(Player)
            end
        end)
    end
end

Players.PlayerAdded:Connect(function(Player)
    Player.CharacterAdded:Connect(function()
        task.wait(0.25)
        if Settings.ESP then
            CreateESP(Player)
        end
    end)
end)

Players.PlayerRemoving:Connect(function(Player)
    RemoveESP(Player)
end)

--========================================================
-- TRACERS
--========================================================

local TracerFolder = Instance.new("Folder")
TracerFolder.Name = "RSR_Tracers"
TracerFolder.Parent = Gui

local Tracers = {}

local function CreateTracer(Player)
    if Player == LocalPlayer then
        return nil
    end

    local Line = Instance.new("Frame")
    Line.Name = Player.Name
    Line.AnchorPoint = Vector2.new(0.5, 0.5)
    Line.BackgroundColor3 = Settings.TracerColor
    Line.BorderSizePixel = 0
    Line.Visible = false
    Line.ZIndex = 90
    Line.Parent = TracerFolder

    local Corner = Instance.new("UICorner")
    Corner.CornerRadius = UDim.new(1, 0)
    Corner.Parent = Line

    return Line
end

for _, Player in ipairs(Players:GetPlayers()) do
    Tracers[Player] = CreateTracer(Player)
end

Players.PlayerAdded:Connect(function(Player)
    Tracers[Player] = CreateTracer(Player)
end)

Players.PlayerRemoving:Connect(function(Player)
    if Tracers[Player] then
        Tracers[Player]:Destroy()
    end
    Tracers[Player] = nil
end)

--========================================================
-- AIM TARGET
--========================================================

local function GetClosestTarget()
    local Closest = nil
    local ClosestDistance = math.huge

    local Center = Vector2.new(
        Camera.ViewportSize.X / 2,
        Camera.ViewportSize.Y / 2
    )

    for _, Player in ipairs(Players:GetPlayers()) do
        if Player ~= LocalPlayer then
            local Character = Player.Character
            local Head = Character and Character:FindFirstChild("Head")
            local Humanoid = Character and Character:FindFirstChildOfClass("Humanoid")

            if Head and Humanoid and Humanoid.Health > 0 then
                local Position, Visible = Camera:WorldToViewportPoint(Head.Position)

                if Visible and Position.Z > 0 then
                    local ScreenPosition = Vector2.new(Position.X, Position.Y)
                    local Distance = (ScreenPosition - Center).Magnitude

                    if Distance <= Settings.FOV and Distance < ClosestDistance then
                        ClosestDistance = Distance
                        Closest = Head
                    end
                end
            end
        end
    end

    return Closest
end

--========================================================
-- FLY
--========================================================

local FlyVelocity
local FlyConnection

local function StartFly()
    if FlyConnection then
        FlyConnection:Disconnect()
        FlyConnection = nil
    end

    local Character = LocalPlayer.Character
    if not Character then
        return
    end

    local Root = Character:FindFirstChild("HumanoidRootPart")
    if not Root then
        return
    end

    if FlyVelocity then
        FlyVelocity:Destroy()
    end

    FlyVelocity = Instance.new("BodyVelocity")
    FlyVelocity.Name = "RSR_FlyVelocity"
    FlyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
    FlyVelocity.Velocity = Vector3.zero
    FlyVelocity.Parent = Root

    FlyConnection = RunService.RenderStepped:Connect(function()
        if not Settings.FlyEnabled or not Root.Parent then
            return
        end

        local Direction = Vector3.zero

        if UIS:IsKeyDown(Enum.KeyCode.W) then
            Direction += Camera.CFrame.LookVector
        end
        if UIS:IsKeyDown(Enum.KeyCode.S) then
            Direction -= Camera.CFrame.LookVector
        end
        if UIS:IsKeyDown(Enum.KeyCode.A) then
            Direction -= Camera.CFrame.RightVector
        end
        if UIS:IsKeyDown(Enum.KeyCode.D) then
            Direction += Camera.CFrame.RightVector
        end
        if UIS:IsKeyDown(Enum.KeyCode.Space) then
            Direction += Vector3.new(0, 1, 0)
        end
        if UIS:IsKeyDown(Enum.KeyCode.LeftControl) then
            Direction -= Vector3.new(0, 1, 0)
        end

        if Direction.Magnitude > 0 then
            Direction = Direction.Unit
        end

        FlyVelocity.Velocity = Direction * Settings.FlySpeed
    end)
end

local function StopFly()
    if FlyConnection then
        FlyConnection:Disconnect()
        FlyConnection = nil
    end

    if FlyVelocity then
        FlyVelocity:Destroy()
        FlyVelocity = nil
    end
end

--========================================================
-- HEAD HITBOX (LOCAL VISUAL)
--========================================================

local OriginalHeadSizes = {}

local function UpdateHeadHitbox(Player)
    if Player == LocalPlayer then
        return
    end

    local Character = Player.Character
    if not Character then
        return
    end

    local Head = Character:FindFirstChild("Head")
    if not Head or not Head:IsA("BasePart") then
        return
    end

    if not OriginalHeadSizes[Player] then
        OriginalHeadSizes[Player] = Head.Size
    end

    local OriginalSize = OriginalHeadSizes[Player]

    if Settings.Hitbox <= 0 then
        Head.Size = OriginalSize
        return
    end

    local Scale = 1 + (Settings.Hitbox * 0.35)
    Head.Size = Vector3.new(
        OriginalSize.X * Scale,
        OriginalSize.Y * Scale,
        OriginalSize.Z * Scale
    )
end

Players.PlayerRemoving:Connect(function(Player)
    OriginalHeadSizes[Player] = nil
end)

--========================================================
-- FIRST PERSON ARM DISTANCE
--========================================================

local ArmJointCache = {}

local function GetArmJoints(Character)
    local Joints = {}

    local UpperTorso = Character:FindFirstChild("UpperTorso")
    if UpperTorso then
        local Left = UpperTorso:FindFirstChild("LeftShoulder")
        local Right = UpperTorso:FindFirstChild("RightShoulder")
        if Left and Left:IsA("Motor6D") then
            table.insert(Joints, Left)
        end
        if Right and Right:IsA("Motor6D") then
            table.insert(Joints, Right)
        end
    end

    local Torso = Character:FindFirstChild("Torso")
    if Torso then
        local Left = Torso:FindFirstChild("Left Shoulder")
        local Right = Torso:FindFirstChild("Right Shoulder")
        if Left and Left:IsA("Motor6D") then
            table.insert(Joints, Left)
        end
        if Right and Right:IsA("Motor6D") then
            table.insert(Joints, Right)
        end
    end

    return Joints
end

local function IsFirstPerson()
    if not Camera then
        return false
    end

    local Character = LocalPlayer.Character
    local Head = Character and Character:FindFirstChild("Head")
    if not Head then
        return false
    end

    return (Camera.CFrame.Position - Head.Position).Magnitude < 1.1
end

local function UpdateArmDistance()
    local Character = LocalPlayer.Character
    if not Character then
        return
    end

    local Joints = ArmJointCache[Character]
    if not Joints then
        Joints = GetArmJoints(Character)
        ArmJointCache[Character] = Joints
    end

    local Active = Settings.ArmsEnabled and IsFirstPerson()

    for _, Joint in ipairs(Joints) do
        if Joint.Parent then
            if not Joint:GetAttribute("RSR_OriginalCached") then
                Joint:SetAttribute("RSR_OriginalCached", true)
                Joint:SetAttribute("RSR_OriginalC0", tostring(Joint.C0))
            end

            -- Use a local Transform for a safer visual offset during first-person.
            if Active then
                local direction = Joint.Name:lower():find("left") and -1 or 1
                Joint.Transform = CFrame.new(direction * Settings.ArmDistance * 0.18, 0, -Settings.ArmDistance * 0.08)
            else
                Joint.Transform = CFrame.identity
            end
        end
    end
end

--========================================================
-- INVISIBILITY
--========================================================

local InvisibleOriginals = {}

local function RememberInvisible(instance, property)
    InvisibleOriginals[instance] = InvisibleOriginals[instance] or {}
    if InvisibleOriginals[instance][property] == nil then
        local ok, value = pcall(function() return instance[property] end)
        if ok then
            InvisibleOriginals[instance][property] = value
        end
    end
end

local function ApplyInvisibleToCharacter(character)
    if not character then return end

    for _, descendant in ipairs(character:GetDescendants()) do
        if descendant:IsA("BasePart") then
            RememberInvisible(descendant, "LocalTransparencyModifier")
            pcall(function() descendant.LocalTransparencyModifier = 1 end)
        elseif descendant:IsA("Decal") or descendant:IsA("Texture") then
            RememberInvisible(descendant, "Transparency")
            pcall(function() descendant.Transparency = 1 end)
        end
    end
end

local function RemoveInvisibleFromCharacter(character)
    for instance, properties in pairs(InvisibleOriginals) do
        if instance and instance.Parent then
            for property, value in pairs(properties) do
                pcall(function() instance[property] = value end)
            end
        end
    end
    InvisibleOriginals = {}
end

local function UpdateInvisibility()
    local character = LocalPlayer.Character
    if Settings.Invisible then
        ApplyInvisibleToCharacter(character)
    else
        RemoveInvisibleFromCharacter(character)
    end
end

--========================================================
-- BETTER FPS OPTIMIZER
--========================================================

local FPSOriginals = {}
local FPSDescendantConnection
local FPSLightingOriginals = {
    GlobalShadows = Lighting.GlobalShadows,
}

local function RememberProperty(Instance, Property)
    FPSOriginals[Instance] = FPSOriginals[Instance] or {}
    if FPSOriginals[Instance][Property] == nil then
        local ok, value = pcall(function()
            return Instance[Property]
        end)
        if ok then
            FPSOriginals[Instance][Property] = value
        end
    end
end

local function OptimizeInstance(Instance)
    if not Settings.BetterFPSEnabled then
        return
    end

    if Instance:IsA("Decal") or Instance:IsA("Texture") then
        RememberProperty(Instance, "Transparency")
        pcall(function()
            Instance.Transparency = 1
        end)
    elseif Instance:IsA("ParticleEmitter") or Instance:IsA("Trail") or Instance:IsA("Beam")
        or Instance:IsA("Smoke") or Instance:IsA("Fire") or Instance:IsA("Sparkles") then
        RememberProperty(Instance, "Enabled")
        pcall(function()
            Instance.Enabled = false
        end)
    elseif Instance:IsA("BloomEffect") or Instance:IsA("SunRaysEffect")
        or Instance:IsA("ColorCorrectionEffect") or Instance:IsA("DepthOfFieldEffect")
        or Instance:IsA("BlurEffect") then
        RememberProperty(Instance, "Enabled")
        pcall(function()
            Instance.Enabled = false
        end)
    end
end

local function EnableBetterFPS()
    Settings.BetterFPSEnabled = true
    FPSLightingOriginals.GlobalShadows = Lighting.GlobalShadows
    Lighting.GlobalShadows = false

    for _, Descendant in ipairs(workspace:GetDescendants()) do
        OptimizeInstance(Descendant)
    end

    for _, Descendant in ipairs(Lighting:GetDescendants()) do
        OptimizeInstance(Descendant)
    end

    if FPSDescendantConnection then
        FPSDescendantConnection:Disconnect()
    end

    FPSDescendantConnection = workspace.DescendantAdded:Connect(function(Instance)
        task.defer(function()
            OptimizeInstance(Instance)
        end)
    end)
end

local function DisableBetterFPS()
    Settings.BetterFPSEnabled = false

    if FPSDescendantConnection then
        FPSDescendantConnection:Disconnect()
        FPSDescendantConnection = nil
    end

    for Instance, Properties in pairs(FPSOriginals) do
        if Instance and Instance.Parent then
            for Property, Value in pairs(Properties) do
                pcall(function()
                    Instance[Property] = Value
                end)
            end
        end
    end

    FPSOriginals = {}
    Lighting.GlobalShadows = FPSLightingOriginals.GlobalShadows
end

-- Watch the setting in case the UI callback is edited later.
local PreviousBetterFPS = Settings.BetterFPSEnabled
local PreviousInvisible = Settings.Invisible

RunService.Heartbeat:Connect(function()
    if Settings.Invisible ~= PreviousInvisible then
        PreviousInvisible = Settings.Invisible
        UpdateInvisibility()
    elseif Settings.Invisible then
        ApplyInvisibleToCharacter(LocalPlayer.Character)
    end
end)

RunService.Heartbeat:Connect(function()
    if Settings.BetterFPSEnabled ~= PreviousBetterFPS then
        PreviousBetterFPS = Settings.BetterFPSEnabled
        if Settings.BetterFPSEnabled then
            EnableBetterFPS()
        else
            DisableBetterFPS()
        end
    end
end)

--========================================================
-- MAIN LOOP
--========================================================

RunService.RenderStepped:Connect(function()
    Camera = workspace.CurrentCamera or Camera

    -- FOV circle
    FOVCircle.Visible = Settings.FOVEnabled
    if Settings.FOVEnabled then
        FOVCircle.Size = UDim2.fromOffset(Settings.FOV * 2, Settings.FOV * 2)
        FOVStroke.Color = Settings.FOVColor
        FOVGlow.Color = Settings.FOVColor
    end

    -- Neon / mirror animation
    if Settings.NeonAnimations then
        local Pulse = (math.sin(os.clock() * 3) + 1) / 2
        GlassStroke.Transparency = 0.58 + Pulse * 0.2
    else
        GlassStroke.Transparency = 0.72
    end

    Reflection.Visible = Settings.MirrorEnabled
    if Settings.MirrorEnabled and Settings.NeonAnimations then
        local sweep = (os.clock() % 2.8) / 2.8
        Reflection.Position = UDim2.new(-0.35 + sweep * 1.55, 0, -0.25, 0)
    end

    -- ESP: stays active after respawns while ON
    for _, Player in ipairs(Players:GetPlayers()) do
        if Player ~= LocalPlayer then
            if Settings.ESP then
                if not ESPObjects[Player] then
                    CreateESP(Player)
                else
                    local Object = ESPObjects[Player]

                    if Object.Highlight and Object.Highlight.Parent then
                        Object.Highlight.FillColor = Settings.ESPColor
                        Object.Highlight.OutlineColor = Settings.ESPColor
                    end

                    if Object.Billboard and Object.Billboard.Parent then
                        local Label = Object.Billboard:FindFirstChildOfClass("TextLabel")
                        if Label then
                            Label.TextColor3 = Settings.ESPColor
                        end
                    end
                end
            else
                if ESPObjects[Player] then
                    RemoveESP(Player)
                end
            end
        end
    end

    -- Tracers
    for Player, Line in pairs(Tracers) do
        if Line and Line.Parent then
            if not Settings.Tracers then
                Line.Visible = false
            else
                local Character = Player.Character
                local Root = Character and Character:FindFirstChild("HumanoidRootPart")

                if Root then
                    local Position, Visible = Camera:WorldToViewportPoint(Root.Position)
                    if Visible then
                        local Start = Vector2.new(
                            Camera.ViewportSize.X / 2,
                            Camera.ViewportSize.Y
                        )
                        local Finish = Vector2.new(Position.X, Position.Y)
                        local Difference = Finish - Start
                        local Length = Difference.Magnitude

                        Line.Position = UDim2.fromOffset(
                            (Start.X + Finish.X) / 2,
                            (Start.Y + Finish.Y) / 2
                        )
                        Line.Size = UDim2.fromOffset(Length, 2)
                        Line.Rotation = math.deg(math.atan2(Difference.Y, Difference.X))
                        Line.BackgroundColor3 = Settings.TracerColor
                        Line.Visible = true
                    else
                        Line.Visible = false
                    end
                else
                    Line.Visible = false
                end
            end
        end
    end

    -- Speed
    local Character = LocalPlayer.Character
    local Humanoid = Character and Character:FindFirstChildOfClass("Humanoid")

    if Humanoid then
        if Settings.SpeedEnabled then
            Humanoid.WalkSpeed = Settings.Speed
        else
            Humanoid.WalkSpeed = 16
        end
    end

    -- Spin
    if Settings.SpinEnabled and Character then
        local Root = Character:FindFirstChild("HumanoidRootPart")
        if Root then
            Root.CFrame = Root.CFrame * CFrame.Angles(0, math.rad(Settings.SpinSpeed), 0)
        end
    end

    -- Aim assist
    if Settings.AimAssist then
        local AimPressed = UIS:IsMouseButtonPressed(Settings.AimKey)
        if AimPressed then
            local Target = GetClosestTarget()
            if Target then
                local CameraPosition = Camera.CFrame.Position
                local TargetCFrame = CFrame.lookAt(CameraPosition, Target.Position)
                Camera.CFrame = Camera.CFrame:Lerp(TargetCFrame, Settings.AimSmoothness)
            end
        end
    end

    -- Local head visual
    for _, Player in ipairs(Players:GetPlayers()) do
        if Player ~= LocalPlayer then
            UpdateHeadHitbox(Player)
        end
    end

    -- First-person arms
    UpdateArmDistance()
end)

--========================================================
-- FLY STATE
--========================================================

RunService.Heartbeat:Connect(function()
    if Settings.FlyEnabled then
        if not FlyVelocity then
            StartFly()
        end
    else
        if FlyVelocity then
            StopFly()
        end
    end
end)

--========================================================
-- CAMERA FOV ENFORCEMENT
--========================================================

RunService:BindToRenderStep("RSR_CameraFOV", Enum.RenderPriority.Camera.Value + 1, function()
    if not Camera then
        return
    end

    local ActualFOV = math.clamp(Settings.CameraFOV, 80, NATIVE_FOV_MAX)
    if math.abs(Camera.FieldOfView - ActualFOV) > 0.05 then
        Camera.FieldOfView = ActualFOV
    end
end)

--========================================================
-- K = OPEN / CLOSE
--========================================================

UIS.InputBegan:Connect(function(Input, GameProcessed)
    if GameProcessed then
        return
    end

    if Input.KeyCode == Settings.OpenKey then
        Settings.GuiOpen = not Settings.GuiOpen
        PlaySound("Click")

        if Settings.GuiOpen then
            Main.Visible = true
            Main.Position = UDim2.new(0.5, -400, 0.5, -235)
            MainScale.Scale = 0.9
            TweenService:Create(
                MainScale,
                TweenInfo.new(0.35, Enum.EasingStyle.Back, Enum.EasingDirection.Out),
                {Scale = 1}
            ):Play()

            TweenService:Create(
                Main,
                TweenInfo.new(0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.Out),
                {
                    Position = UDim2.new(0.5, -400, 0.5, -270),
                }
            ):Play()
        else
            TweenService:Create(
                Main,
                TweenInfo.new(0.2, Enum.EasingStyle.Quint, Enum.EasingDirection.In),
                {
                    Position = UDim2.new(0.5, -400, 0.5, -235),
                }
            ):Play()

            TweenService:Create(
                MainScale,
                TweenInfo.new(0.2, Enum.EasingStyle.Quint, Enum.EasingDirection.In),
                {Scale = 0.9}
            ):Play()

            task.delay(0.2, function()
                if not Settings.GuiOpen then
                    Main.Visible = false
                end
            end)
        end
    end
end)

--========================================================
-- RESPAWN
--========================================================

LocalPlayer.CharacterAdded:Connect(function(Character)
    ArmJointCache[Character] = nil

    task.wait(0.6)

    if Settings.FlyEnabled then
        StartFly()
    end

    if Settings.ESP then
        ApplyESPToAll()
    end

    if Settings.Invisible then
        task.wait(0.15)
        UpdateInvisibility()
    end
end)

--========================================================
-- INITIAL STATE
--========================================================

if Settings.CameraFOV then
    Camera.FieldOfView = math.clamp(Settings.CameraFOV, 80, NATIVE_FOV_MAX)
end

Main.Visible = true

print("RSR STUDIO SHOOTER PANEL ENHANCED LOADED")
print("Press K to open / close")

Features & Information

-aimbot -speedhack -spin -fly -fov -better FPS -ESP and more
#universal script

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts