Swe UI
Key RequiredUniversal

Swe UI

Universal ScriptKuttibagoKuttibago 215 views 1.1K executesUpdated Aug 23, 2026
Unrated
00
Lua Script•1980 lines (63856 chars)
-- Player Tools (LocalScript) - Clientside only
-- Placera som en LocalScript i StarterPlayer > StarterPlayerScripts (eller kör via en executor)
-- Sektioner i bokstavsordning: CFrame Speed, Click Teleport, ESP, Fly, Freecam,
-- Head Scale, Infinite Jump, Noclip, Settings, Shiftlock, Spectate, WalkSpeed. UI:t har en
-- vänstersidebar med kategorier: Movement, Visual, Players (samt en separat Settings-vy via
-- kugghjulet), plus en Hub-knapp i titelraden som stänger av/blockerar allt.

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

local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local camera = workspace.CurrentCamera

-- ===== Delat tillstånd (minimal mängd, bara det som korsrefereras mellan sektioner) =====
local hubEnabled = true
local noclipActive = false
local shiftlockActive = false
local walkSpeed = 16
local accentColor = Color3.fromRGB(0, 170, 255)
local freecamHintLabel = nil

local stopFly
local stopNoclip
local stopShiftlock
local stopSpectate

-- Färgnyanser som räknas fram från accentfärgen, så HELA UI:t kan färgas om.
local function shadeFromAccent(value)
	local h, s = accentColor:ToHSV()
	return Color3.fromHSV(h, math.clamp(s * 0.45, 0, 0.55), value)
end

local function getPanelColor() return shadeFromAccent(0.11) end
local function getSidebarColor() return shadeFromAccent(0.075) end
local function getTitleColor() return shadeFromAccent(0.16) end
local function getButtonColor() return shadeFromAccent(0.21) end
local function getListColor() return shadeFromAccent(0.08) end

-- Raycastar men hoppar över delar som inte faktiskt kolliderar (CanCollide = false),
-- så vi bara stoppas av sånt du redan skulle stoppas av när du går normalt.
local function raycastIgnoringNonCollide(origin, direction, filterInstances)
	local remainingDistance = direction.Magnitude
	if remainingDistance <= 0 then return nil end
	local dir = direction.Unit
	local currentOrigin = origin

	for _ = 1, 6 do
		local params = RaycastParams.new()
		params.FilterType = Enum.RaycastFilterType.Exclude
		params.FilterDescendantsInstances = filterInstances
		params.RespectCanCollide = true

		local result = workspace:Raycast(currentOrigin, dir * remainingDistance, params)
		if not result then
			return nil
		end
		if result.Instance.CanCollide then
			return result
		end

		local stepped = (result.Position - currentOrigin).Magnitude + 0.05
		currentOrigin = currentOrigin + dir * stepped
		remainingDistance = remainingDistance - stepped
		if remainingDistance <= 0 then
			return nil
		end
	end

	return nil
end

-- ================= CFRAME SPEED =================
-- Rör dig genom att direkt sätta CFrame varje frame (som Fly/Noclip), istället för att
-- höja WalkSpeed. Det betyder ingen inbyggd Roblox-acceleration/inbromsning - du är på
-- topfart direkt och stannar tvärt när du släpper tangenterna, ingen glidning alls.

local cframeSpeedActive = false
local cframeSpeedButton
local cframeSpeed = 50
local cframeSpeedConnection = nil
local cframeSpeedPosition = nil
local stopCFrameSpeed

local function updateCFrameSpeed(deltaTime)
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoid or not humanoidRootPart then return end

	-- Om du sitter i ett säte är HumanoidRootPart svetsad till sätet - att då tvinga
	-- CFrame varje frame fightar våldsamt mot den svetsen (det var det som fick dig
	-- att skjutas uppåt och gjorde det svårt att stänga av). Stäng av automatiskt.
	if humanoid.SeatPart or humanoid:GetState() == Enum.HumanoidStateType.Seated then
		stopCFrameSpeed()
		return
	end

	if not cframeSpeedPosition then
		cframeSpeedPosition = humanoidRootPart.Position
	end

	local camCFrame = camera.CFrame
	local flatLook = Vector3.new(camCFrame.LookVector.X, 0, camCFrame.LookVector.Z)
	local flatRight = Vector3.new(camCFrame.RightVector.X, 0, camCFrame.RightVector.Z)
	if flatLook.Magnitude > 0.001 then flatLook = flatLook.Unit end
	if flatRight.Magnitude > 0.001 then flatRight = flatRight.Unit end

	local moveVector = Vector3.new(0, 0, 0)
	if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveVector = moveVector + flatLook end
	if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveVector = moveVector - flatLook end
	if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveVector = moveVector - flatRight end
	if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveVector = moveVector + flatRight end

	-- Ingen rörelse den här framen = ingen förflyttning alls, inget momentum att fasa ut
	if moveVector.Magnitude == 0 then
		return
	end
	moveVector = moveVector.Unit * cframeSpeed

	local horizontalDelta = moveVector * deltaTime
	local distance = horizontalDelta.Magnitude

	if distance > 0.0001 then
		local direction = horizontalDelta.Unit
		local hit = raycastIgnoringNonCollide(cframeSpeedPosition, direction * (distance + 2), { character })
		if hit then
			local safeDistance = math.max((hit.Position - cframeSpeedPosition).Magnitude - 2, 0)
			horizontalDelta = direction * math.min(safeDistance, distance)
		end
	end

	local newHorizontalPos = cframeSpeedPosition + horizontalDelta

	-- Håll dig ovanpå marken (glider över trappor/kanter) via en nedåtriktad raycast.
	-- Avståndet räknas ut från KARAKTÄRENS faktiska HipHeight, inte en gissad konstant
	-- (det var därför benen sjönk genom marken - en fast siffra passade inte alla avatarer).
	local groundOffset = humanoid.HipHeight + humanoidRootPart.Size.Y / 2
	local groundHit = raycastIgnoringNonCollide(newHorizontalPos + Vector3.new(0, 5, 0), Vector3.new(0, -25, 0), { character })
	local targetY
	if groundHit then
		targetY = groundHit.Position.Y + groundOffset
	else
		targetY = cframeSpeedPosition.Y - 40 * deltaTime
	end

	cframeSpeedPosition = Vector3.new(newHorizontalPos.X, targetY, newHorizontalPos.Z)

	local facing = Vector3.new(moveVector.X, 0, moveVector.Z)
	if facing.Magnitude < 0.001 then
		facing = Vector3.new(humanoidRootPart.CFrame.LookVector.X, 0, humanoidRootPart.CFrame.LookVector.Z)
	end

	humanoidRootPart.CFrame = CFrame.new(cframeSpeedPosition, cframeSpeedPosition + facing)
	humanoidRootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
end

function stopCFrameSpeed()
	if not cframeSpeedActive then return end
	cframeSpeedActive = false
	if cframeSpeedConnection then
		cframeSpeedConnection:Disconnect()
		cframeSpeedConnection = nil
	end
	cframeSpeedPosition = nil

	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.AutoRotate = true
		humanoid.WalkSpeed = walkSpeed
	end

	if cframeSpeedButton then
		cframeSpeedButton.Text = "CFrame Speed: OFF"
		cframeSpeedButton.BackgroundColor3 = getButtonColor()
	end
end

local function startCFrameSpeed()
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if not character or not humanoid then return end
	if humanoid.SeatPart or humanoid:GetState() == Enum.HumanoidStateType.Seated then return end

	stopFly()
	stopShiftlock()

	cframeSpeedActive = true
	-- Ingen PlatformStand - den låter karaktären sluta hålla sin vanliga stå-pose, vilket
	-- fick benen att hamna fel jämfört med vad HipHeight-formeln förutsätter. WalkSpeed=0
	-- räcker för att förhindra att spelets egna WASD-styrning fightar mot vår rörelse.
	humanoid.AutoRotate = false
	humanoid.WalkSpeed = 0
	cframeSpeedConnection = RunService.Heartbeat:Connect(updateCFrameSpeed)

	if cframeSpeedButton then
		cframeSpeedButton.Text = "CFrame Speed: ON"
		cframeSpeedButton.BackgroundColor3 = accentColor
	end
end

local function toggleCFrameSpeed()
	if not hubEnabled then return end
	if cframeSpeedActive then stopCFrameSpeed() else startCFrameSpeed() end
end

-- ================= CLICK TELEPORT =================

local clickTeleportActive = false
local clickTeleportButton

local function onClickTeleportInput(input, gameProcessed)
	if gameProcessed then return end
	if not clickTeleportActive then return end
	if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end

	local character = player.Character
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoidRootPart then return end

	local mouseLocation = UserInputService:GetMouseLocation()
	local viewportRay = camera:ViewportPointToRay(mouseLocation.X, mouseLocation.Y)

	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Exclude
	params.FilterDescendantsInstances = { character }

	local result = workspace:Raycast(viewportRay.Origin, viewportRay.Direction * 3000, params)
	if result then
		local currentRotation = humanoidRootPart.CFrame - humanoidRootPart.CFrame.Position
		humanoidRootPart.CFrame = CFrame.new(result.Position + Vector3.new(0, 3, 0)) * currentRotation
		humanoidRootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
	end
end

UserInputService.InputBegan:Connect(onClickTeleportInput)

local function toggleClickTeleport()
	if not hubEnabled then return end
	clickTeleportActive = not clickTeleportActive
	if clickTeleportButton then
		clickTeleportButton.Text = clickTeleportActive and "Click Teleport: ON" or "Click Teleport: OFF"
		clickTeleportButton.BackgroundColor3 = clickTeleportActive and accentColor or getButtonColor()
	end
end

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

local espActive = false
local espButton

local espHighlights = setmetatable({}, { __mode = "k" })
local espBillboards = setmetatable({}, { __mode = "k" })
local espConnections = setmetatable({}, { __mode = "k" })

local function getESPColor(plr)
	if plr and plr.Team then
		return plr.Team.TeamColor.Color
	end
	return Color3.fromRGB(255, 60, 60)
end

local function getPlayerRoleText(plr)
	local leaderstats = plr and plr:FindFirstChild("leaderstats")
	if leaderstats then
		local role = leaderstats:FindFirstChild("Role")
		if role then
			return tostring(role.Value)
		end
	end
	return nil
end

local function addESPHighlight(character)
	if character == player.Character then return end
	if espHighlights[character] then return end

	local plr = Players:GetPlayerFromCharacter(character)
	local color = getESPColor(plr)

	local highlight = Instance.new("Highlight")
	highlight.Name = "ESPHighlight"
	highlight.FillColor = color
	highlight.OutlineColor = color
	highlight.FillTransparency = 0.5
	highlight.OutlineTransparency = 0
	highlight.DepthMode = Enum.HighlightDepthMode.AlwaysOnTop
	highlight.Parent = character
	espHighlights[character] = highlight

	local connections = {}
	espConnections[character] = connections

	local head = character:FindFirstChild("Head")
	if head and plr then
		local billboard = Instance.new("BillboardGui")
		billboard.Name = "ESPInfo"
		billboard.Size = UDim2.new(0, 170, 0, 50)
		billboard.StudsOffset = Vector3.new(0, 1.3, 0)
		billboard.AlwaysOnTop = true
		billboard.Parent = head
		espBillboards[character] = billboard

		local nameLabel = Instance.new("TextLabel")
		nameLabel.Size = UDim2.new(1, 0, 0, 18)
		nameLabel.BackgroundTransparency = 1
		nameLabel.Font = Enum.Font.GothamBold
		nameLabel.TextSize = 14
		nameLabel.TextColor3 = color
		nameLabel.TextStrokeTransparency = 0.3
		nameLabel.Text = plr.Name
		nameLabel.Parent = billboard

		local roleLabel = Instance.new("TextLabel")
		roleLabel.Size = UDim2.new(1, 0, 0, 14)
		roleLabel.Position = UDim2.new(0, 0, 0, 18)
		roleLabel.BackgroundTransparency = 1
		roleLabel.Font = Enum.Font.Gotham
		roleLabel.TextSize = 12
		roleLabel.TextColor3 = Color3.fromRGB(220, 220, 225)
		roleLabel.TextStrokeTransparency = 0.3
		roleLabel.Text = getPlayerRoleText(plr) or ""
		roleLabel.Parent = billboard

		local healthLabel = Instance.new("TextLabel")
		healthLabel.Size = UDim2.new(1, 0, 0, 14)
		healthLabel.Position = UDim2.new(0, 0, 0, 34)
		healthLabel.BackgroundTransparency = 1
		healthLabel.Font = Enum.Font.Gotham
		healthLabel.TextSize = 12
		healthLabel.TextColor3 = Color3.fromRGB(120, 255, 120)
		healthLabel.TextStrokeTransparency = 0.3
		healthLabel.Parent = billboard

		local humanoid = character:FindFirstChildOfClass("Humanoid")
		local function updateHealth()
			if humanoid and humanoid.MaxHealth > 0 then
				local pct = math.clamp(humanoid.Health / humanoid.MaxHealth, 0, 1)
				healthLabel.Text = string.format("%d/%d HP", math.floor(humanoid.Health), math.floor(humanoid.MaxHealth))
				healthLabel.TextColor3 = Color3.fromRGB(math.floor(255 * (1 - pct)), math.floor(255 * pct), 60)
			end
		end
		if humanoid then
			updateHealth()
			table.insert(connections, humanoid.HealthChanged:Connect(updateHealth))
		end

		local function updateTeamColor()
			local newColor = getESPColor(plr)
			highlight.FillColor = newColor
			highlight.OutlineColor = newColor
			nameLabel.TextColor3 = newColor
		end
		table.insert(connections, plr:GetPropertyChangedSignal("Team"):Connect(updateTeamColor))

		local leaderstats = plr:FindFirstChild("leaderstats")
		if leaderstats then
			local role = leaderstats:FindFirstChild("Role")
			if role then
				table.insert(connections, role:GetPropertyChangedSignal("Value"):Connect(function()
					roleLabel.Text = tostring(role.Value)
				end))
			end
		end
	end
end

local function removeESPHighlight(character)
	local highlight = espHighlights[character]
	if highlight then
		highlight:Destroy()
		espHighlights[character] = nil
	end
	local billboard = espBillboards[character]
	if billboard then
		billboard:Destroy()
		espBillboards[character] = nil
	end
	local connections = espConnections[character]
	if connections then
		for _, conn in connections do
			conn:Disconnect()
		end
		espConnections[character] = nil
	end
end

local function onCharacterAddedESP(character)
	if espActive then
		addESPHighlight(character)
	end
end

local function onPlayerAddedESP(plr)
	plr.CharacterAdded:Connect(onCharacterAddedESP)
	if plr.Character and espActive then
		addESPHighlight(plr.Character)
	end
end

for _, plr in Players:GetPlayers() do
	onPlayerAddedESP(plr)
end
Players.PlayerAdded:Connect(onPlayerAddedESP)

local function toggleESP()
	if not hubEnabled then return end
	espActive = not espActive
	if espActive then
		for _, plr in Players:GetPlayers() do
			if plr.Character then
				addESPHighlight(plr.Character)
			end
		end
		if espButton then
			espButton.Text = "ESP: ON"
			espButton.BackgroundColor3 = accentColor
		end
	else
		for character in espHighlights do
			removeESPHighlight(character)
		end
		if espButton then
			espButton.Text = "ESP: OFF"
			espButton.BackgroundColor3 = getButtonColor()
		end
	end
end

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

local flying = false
local flySpeed = 50
local flyConnection = nil
local flyOriginalPhysicalProps = nil
local flyPosition = nil
local flyButton

local function enableCameraFollow()
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.AutoRotate = false
	end
end

local function disableCameraFollow()
	UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.AutoRotate = true
	end
end

local function updateFlight(deltaTime)
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoid or not humanoidRootPart then return end

	-- Samma skydd som CFrame Speed: om du sitter i ett säte är HumanoidRootPart
	-- svetsad till det, och att tvinga CFrame varje frame fightar våldsamt mot svetsen.
	if humanoid.SeatPart or humanoid:GetState() == Enum.HumanoidStateType.Seated then
		stopFly()
		return
	end

	if not flyPosition then
		flyPosition = humanoidRootPart.Position
	end

	local moveVector = Vector3.new(0, 0, 0)
	local camCFrame = camera.CFrame

	if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveVector = moveVector + camCFrame.LookVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveVector = moveVector - camCFrame.LookVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveVector = moveVector - camCFrame.RightVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveVector = moveVector + camCFrame.RightVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.Space) then moveVector = moveVector + Vector3.new(0, 1, 0) end
	if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then moveVector = moveVector - Vector3.new(0, 1, 0) end

	if moveVector.Magnitude > 0 then
		moveVector = moveVector.Unit * flySpeed
	end

	local delta = moveVector * deltaTime
	local distance = delta.Magnitude

	if distance > 0.0001 then
		local direction = delta.Unit
		local hit = raycastIgnoringNonCollide(flyPosition, direction * (distance + 1.5), { character })
		if hit then
			local safeDistance = math.max((hit.Position - flyPosition).Magnitude - 1.5, 0)
			delta = direction * math.min(safeDistance, distance)
		end
	end

	flyPosition = flyPosition + delta

	-- Minsta avstånd till marken, oavsett hur brant du lutar kroppen (t.ex. när du
	-- tittar rakt ner) - annars kunde torson doppa ner i/genom marken när man flyger
	-- lågt, eftersom bara rörelseriktningen kollisionskontrollerades innan, inte hur
	-- nära marken roten faktiskt är rakt under dig.
	local groundBelow = raycastIgnoringNonCollide(flyPosition, Vector3.new(0, -10, 0), { character })
	if groundBelow then
		local minClearance = 3.5
		local clearance = flyPosition.Y - groundBelow.Position.Y
		if clearance < minClearance then
			flyPosition = Vector3.new(flyPosition.X, groundBelow.Position.Y + minClearance, flyPosition.Z)
		end
	end

	local lookVector = camCFrame.LookVector
	humanoidRootPart.CFrame = CFrame.new(flyPosition, flyPosition + lookVector)
	humanoidRootPart.AssemblyLinearVelocity = Vector3.new(0, 0, 0)
end

function stopFly()
	flying = false
	flyPosition = nil
	if flyConnection then
		flyConnection:Disconnect()
		flyConnection = nil
	end
	local character = player.Character
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if humanoidRootPart and flyOriginalPhysicalProps ~= nil then
		humanoidRootPart.CustomPhysicalProperties = flyOriginalPhysicalProps
		flyOriginalPhysicalProps = nil
	end
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.PlatformStand = false
	end
	disableCameraFollow()
	if flyButton then
		flyButton.Text = "Fly: OFF"
		flyButton.BackgroundColor3 = getButtonColor()
	end
end

local function startFly()
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoid or not humanoidRootPart then return end
	if humanoid.SeatPart or humanoid:GetState() == Enum.HumanoidStateType.Seated then return end

	if noclipActive then stopNoclip() end
	if shiftlockActive then stopShiftlock() end
	if cframeSpeedActive then stopCFrameSpeed() end

	flying = true
	flyOriginalPhysicalProps = humanoidRootPart.CustomPhysicalProperties
	humanoidRootPart.CustomPhysicalProperties = PhysicalProperties.new(1, 0.3, 0)
	humanoid.PlatformStand = true
	enableCameraFollow()
	flyConnection = RunService.RenderStepped:Connect(updateFlight)

	if flyButton then
		flyButton.Text = "Fly: ON"
		flyButton.BackgroundColor3 = accentColor
	end
end

local function toggleFly()
	if not hubEnabled then return end
	if flying then stopFly() else startFly() end
end

-- ================= FREECAM =================

local freecamActive = false
local freecamConnection = nil
local freecamButton
local freecamYaw = 0
local freecamPitch = 0
local freecamSpeed = 60

local function updateFreecam(deltaTime)
	local rotation = CFrame.Angles(0, freecamYaw, 0) * CFrame.Angles(freecamPitch, 0, 0)
	local moveVector = Vector3.new(0, 0, 0)

	if UserInputService:IsKeyDown(Enum.KeyCode.W) then moveVector = moveVector + rotation.LookVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.S) then moveVector = moveVector - rotation.LookVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.A) then moveVector = moveVector - rotation.RightVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.D) then moveVector = moveVector + rotation.RightVector end
	if UserInputService:IsKeyDown(Enum.KeyCode.Space) then moveVector = moveVector + Vector3.new(0, 1, 0) end
	if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then moveVector = moveVector - Vector3.new(0, 1, 0) end

	if moveVector.Magnitude > 0 then
		moveVector = moveVector.Unit * freecamSpeed
	end

	camera.CFrame = CFrame.new(camera.CFrame.Position + moveVector * deltaTime) * rotation
end

UserInputService.InputChanged:Connect(function(input)
	if freecamActive and input.UserInputType == Enum.UserInputType.MouseMovement then
		freecamYaw = freecamYaw - input.Delta.X * 0.003
		freecamPitch = math.clamp(freecamPitch - input.Delta.Y * 0.003, -math.rad(89), math.rad(89))
	end
end)

local function stopFreecam()
	freecamActive = false
	if freecamConnection then
		freecamConnection:Disconnect()
		freecamConnection = nil
	end
	UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	camera.CameraType = Enum.CameraType.Custom
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		camera.CameraSubject = humanoid
	end
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if humanoidRootPart then
		humanoidRootPart.Anchored = false
	end
	if freecamButton then
		freecamButton.Text = "Freecam: OFF"
		freecamButton.BackgroundColor3 = getButtonColor()
	end
end

local function startFreecam()
	stopSpectate()
	if shiftlockActive then stopShiftlock() end

	local look = camera.CFrame.LookVector
	freecamYaw = math.atan2(-look.X, -look.Z)
	freecamPitch = math.asin(math.clamp(look.Y, -1, 1))

	freecamActive = true
	camera.CameraType = Enum.CameraType.Scriptable
	UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	freecamConnection = RunService.RenderStepped:Connect(updateFreecam)

	local character = player.Character
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if humanoidRootPart then
		humanoidRootPart.Anchored = true
	end

	if freecamButton then
		freecamButton.Text = "Freecam: ON"
		freecamButton.BackgroundColor3 = accentColor
	end
end

local function toggleFreecam()
	if not hubEnabled then return end
	if freecamActive then stopFreecam() else startFreecam() end
end

-- ================= HEAD SCALE =================

local MIN_SCALE = 1
local MAX_SCALE = 8
local INITIAL_SCALE = 1
local currentScale = INITIAL_SCALE

local originalHeadSizes = setmetatable({}, { __mode = "k" })
local originalMeshScales = setmetatable({}, { __mode = "k" })
local originalHeadJointC1 = setmetatable({}, { __mode = "k" })

local function findHeadJoint(character, head)
	for _, descendant in character:GetDescendants() do
		if descendant:IsA("Motor6D") and descendant.Part1 == head then
			return descendant
		end
	end
	return nil
end

local function setHeadScale(character, scale)
	local head = character:FindFirstChild("Head")
	if not head or not head:IsA("BasePart") then return end

	if not originalHeadSizes[character] then
		originalHeadSizes[character] = head.Size
	end
	head.Size = originalHeadSizes[character] * scale

	local mesh = head:FindFirstChildOfClass("SpecialMesh")
	if mesh then
		if not originalMeshScales[character] then
			originalMeshScales[character] = mesh.Scale
		end
		local baseMeshScale = originalMeshScales[character]
		mesh.Scale = Vector3.new(baseMeshScale.X * scale, baseMeshScale.Y * scale, baseMeshScale.Z * scale)
	end

	local joint = findHeadJoint(character, head)
	if joint then
		if not originalHeadJointC1[character] then
			originalHeadJointC1[character] = joint.C1
		end
		local baseC1 = originalHeadJointC1[character]
		local rotationOnly = baseC1 - baseC1.Position
		joint.C1 = CFrame.new(baseC1.Position * scale) * rotationOnly
	end
end

local function applyHeadScaleToAll(scale)
	currentScale = scale
	for _, plr in Players:GetPlayers() do
		if plr.Character then
			setHeadScale(plr.Character, scale)
		end
	end
end

local function onCharacterAddedHead(character)
	character:WaitForChild("Head", 5)
	setHeadScale(character, currentScale)
end

local function onPlayerAddedHead(plr)
	plr.CharacterAdded:Connect(onCharacterAddedHead)
	if plr.Character then
		onCharacterAddedHead(plr.Character)
	end
end

for _, plr in Players:GetPlayers() do
	onPlayerAddedHead(plr)
end
Players.PlayerAdded:Connect(onPlayerAddedHead)

-- ================= INFINITE JUMP =================

local infJumpActive = false
local infJumpButton

local function onJumpRequest()
	if not infJumpActive then return end
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
	end
end

UserInputService.JumpRequest:Connect(onJumpRequest)

local function toggleInfJump()
	if not hubEnabled then return end
	infJumpActive = not infJumpActive
	if infJumpButton then
		infJumpButton.Text = infJumpActive and "Infinite Jump: ON" or "Infinite Jump: OFF"
		infJumpButton.BackgroundColor3 = infJumpActive and accentColor or getButtonColor()
	end
end

-- ================= NOCLIP =================
-- Bara kollisionen stängs av - vanlig gång, gravitation och hopp fortsätter fungera precis
-- som vanligt, du "flyger" inte, du går/faller rakt igenom saker.

local noclipConnection = nil
local noclipButton

local noclipOriginalCanCollide = setmetatable({}, { __mode = "k" })

local function setNoclipCollisions(character, enabled)
	for _, part in character:GetDescendants() do
		if part:IsA("BasePart") then
			if enabled then
				local original = noclipOriginalCanCollide[part]
				if original ~= nil then
					part.CanCollide = original
				end
			else
				if noclipOriginalCanCollide[part] == nil then
					noclipOriginalCanCollide[part] = part.CanCollide
				end
				part.CanCollide = false
			end
		end
	end
end

local function updateNoclip()
	local character = player.Character
	if not character then return end
	for _, part in character:GetDescendants() do
		if part:IsA("BasePart") and part.CanCollide then
			part.CanCollide = false
		end
	end
end

function stopNoclip()
	noclipActive = false
	if noclipConnection then
		noclipConnection:Disconnect()
		noclipConnection = nil
	end
	local character = player.Character
	if character then
		setNoclipCollisions(character, true)
	end
	if noclipButton then
		noclipButton.Text = "Noclip: OFF"
		noclipButton.BackgroundColor3 = getButtonColor()
	end
end

local function startNoclip()
	local character = player.Character
	if not character then return end

	if flying then stopFly() end

	noclipActive = true
	setNoclipCollisions(character, false)
	noclipConnection = RunService.Heartbeat:Connect(updateNoclip)

	if noclipButton then
		noclipButton.Text = "Noclip: ON"
		noclipButton.BackgroundColor3 = accentColor
	end
end

local function toggleNoclip()
	if not hubEnabled then return end
	if noclipActive then stopNoclip() else startNoclip() end
end

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

local keybinds = {
	CFrameSpeed = Enum.KeyCode.R,
	ClickTeleport = Enum.KeyCode.T,
	Fly = Enum.KeyCode.F,
	Noclip = Enum.KeyCode.C,
	Freecam = Enum.KeyCode.V,
	Shiftlock = Enum.KeyCode.LeftShift,
}

local presetColors = {
	Color3.fromRGB(0, 170, 255),
	Color3.fromRGB(255, 70, 70),
	Color3.fromRGB(70, 220, 130),
	Color3.fromRGB(190, 100, 255),
	Color3.fromRGB(255, 170, 40),
	Color3.fromRGB(255, 255, 255),
}

local themedElements = {} -- lista av { instance = ..., role = "accent"|"panel"|"sidebar"|"title"|"button"|"list" }
local rebindingAction = nil
local keybindButtons = {}

local function registerThemed(instance, role)
	table.insert(themedElements, { instance = instance, role = role })
	return instance
end

local function applyTheme()
	local panelColor = getPanelColor()
	local sidebarColor = getSidebarColor()
	local titleColor = getTitleColor()
	local buttonColor = getButtonColor()
	local listColor = getListColor()

	for _, entry in themedElements do
		local inst = entry.instance
		if inst and inst.Parent then
			if entry.role == "accent" then
				inst.BackgroundColor3 = accentColor
			elseif entry.role == "panel" then
				inst.BackgroundColor3 = panelColor
			elseif entry.role == "sidebar" then
				inst.BackgroundColor3 = sidebarColor
			elseif entry.role == "title" then
				inst.BackgroundColor3 = titleColor
			elseif entry.role == "button" then
				inst.BackgroundColor3 = buttonColor
			elseif entry.role == "list" then
				inst.BackgroundColor3 = listColor
			end
		end
	end
end

-- Togglingsknapparna byter färg mellan AV och PÅ, så de hanteras separat från temaloopen
-- ovan för att inte skriva över ett aktivt läges färg.
local function refreshToggleButtonColors()
	local buttonColor = getButtonColor()
	if cframeSpeedButton then cframeSpeedButton.BackgroundColor3 = cframeSpeedActive and accentColor or buttonColor end
	if clickTeleportButton then clickTeleportButton.BackgroundColor3 = clickTeleportActive and accentColor or buttonColor end
	if espButton then espButton.BackgroundColor3 = espActive and accentColor or buttonColor end
	if flyButton then flyButton.BackgroundColor3 = flying and accentColor or buttonColor end
	if freecamButton then freecamButton.BackgroundColor3 = freecamActive and accentColor or buttonColor end
	if infJumpButton then infJumpButton.BackgroundColor3 = infJumpActive and accentColor or buttonColor end
	if noclipButton then noclipButton.BackgroundColor3 = noclipActive and accentColor or buttonColor end
end

local function setAccentColor(newColor)
	accentColor = newColor
	applyTheme()
	refreshToggleButtonColors()
end

local function beginRebind(action, button)
	rebindingAction = action
	button.Text = "..."
end

UserInputService.InputBegan:Connect(function(input)
	if rebindingAction and input.UserInputType == Enum.UserInputType.Keyboard then
		if input.KeyCode == Enum.KeyCode.Escape then
			-- Escape gör tangenten obunden (ingen tangent alls) istället för att binda till Escape
			keybinds[rebindingAction] = nil
			local button = keybindButtons[rebindingAction]
			if button then
				button.Text = "Unbound"
			end
			if rebindingAction == "Freecam" and freecamHintLabel then
				freecamHintLabel.Text = "Mouse locks in freecam - no key bound, click the button to exit"
			end
			rebindingAction = nil
			return
		end

		keybinds[rebindingAction] = input.KeyCode
		local button = keybindButtons[rebindingAction]
		if button then
			button.Text = input.KeyCode.Name
		end
		if rebindingAction == "Freecam" and freecamHintLabel then
			freecamHintLabel.Text = "Mouse locks in freecam - press " .. input.KeyCode.Name .. " to exit"
		end
		rebindingAction = nil
	end
end)

UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end
	if rebindingAction then return end
	if input.KeyCode == keybinds.CFrameSpeed then
		toggleCFrameSpeed()
	elseif input.KeyCode == keybinds.ClickTeleport then
		toggleClickTeleport()
	elseif input.KeyCode == keybinds.Fly then
		toggleFly()
	elseif input.KeyCode == keybinds.Noclip then
		toggleNoclip()
	elseif input.KeyCode == keybinds.Freecam then
		toggleFreecam()
	end
end)

-- ================= SHIFTLOCK =================

local shiftlockConnection = nil
local shiftlockButton

local function updateShiftlock()
	local character = player.Character
	local humanoidRootPart = character and character:FindFirstChild("HumanoidRootPart")
	if not humanoidRootPart then return end

	local lookVector = camera.CFrame.LookVector
	local flatLook = Vector3.new(lookVector.X, 0, lookVector.Z)
	if flatLook.Magnitude > 0.001 then
		flatLook = flatLook.Unit
		humanoidRootPart.CFrame = CFrame.new(humanoidRootPart.Position, humanoidRootPart.Position + flatLook)
	end
end

function stopShiftlock()
	shiftlockActive = false
	if shiftlockConnection then
		shiftlockConnection:Disconnect()
		shiftlockConnection = nil
	end
	UserInputService.MouseBehavior = Enum.MouseBehavior.Default
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.AutoRotate = true
	end
	if shiftlockButton then
		shiftlockButton.Text = "Shiftlock: OFF"
		shiftlockButton.BackgroundColor3 = getButtonColor()
	end
end

local function startShiftlock()
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	if flying then stopFly() end
	if freecamActive then stopFreecam() end
	if cframeSpeedActive then stopCFrameSpeed() end

	shiftlockActive = true
	humanoid.AutoRotate = false
	UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
	shiftlockConnection = RunService.RenderStepped:Connect(updateShiftlock)

	if shiftlockButton then
		shiftlockButton.Text = "Shiftlock: ON"
		shiftlockButton.BackgroundColor3 = accentColor
	end
end

local function toggleShiftlock()
	if not hubEnabled then return end
	if shiftlockActive then stopShiftlock() else startShiftlock() end
end

-- Egen hanterare, utan gameProcessed-kollen: Shift "tas" ofta redan av spelets egna
-- standardkontroller (t.ex. inbyggd shiftlock eller sprint), vilket annars hindrade vår
-- knapptryckning från att någonsin nå fram. Accepterar båda Shift-tangenterna om
-- standardbindningen (vänster Shift) fortfarande gäller.
UserInputService.InputBegan:Connect(function(input)
	if rebindingAction then return end
	if input.KeyCode == keybinds.Shiftlock then
		toggleShiftlock()
	elseif keybinds.Shiftlock == Enum.KeyCode.LeftShift and input.KeyCode == Enum.KeyCode.RightShift then
		toggleShiftlock()
	end
end)

-- ================= SPECTATE =================

local spectateTarget = nil

function stopSpectate()
	spectateTarget = nil
	if freecamActive then return end
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	camera.CameraSubject = humanoid
	camera.CameraType = Enum.CameraType.Custom
end

local function startSpectate(targetPlayer)
	if targetPlayer == player then return end
	local character = targetPlayer.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if not humanoid then return end

	if freecamActive then stopFreecam() end

	spectateTarget = targetPlayer
	camera.CameraSubject = humanoid
	camera.CameraType = Enum.CameraType.Custom
end

-- ================= WALKSPEED =================

local function applyWalkSpeedToLocalCharacter()
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid then
		humanoid.WalkSpeed = walkSpeed
		-- UseJumpPower=true gör att JumpPower (en fast starthastighet) styr hoppet,
		-- och den FAKTISKA höjden beror då på gravitationen som vanlig fysik.
		-- Annars räknar Roblox automatiskt om kraften så du alltid når samma höjd
		-- oavsett gravitation, vilket var därför gravitationsreglaget inte kändes
		-- av när du hoppade.
		humanoid.UseJumpPower = true
	end
end

local function setWalkSpeed(value)
	walkSpeed = value
	applyWalkSpeedToLocalCharacter()
end

applyWalkSpeedToLocalCharacter()

-- Håller WalkSpeed vid det inställda värdet varje frame, ifall något annat (spelets
-- egna skript, respawn-timing, m.m.) skriver över det - annars kunde det kännas som
-- att reglaget bara funkade medan man höll i det.
RunService.Heartbeat:Connect(function()
	local character = player.Character
	local humanoid = character and character:FindFirstChildOfClass("Humanoid")
	if humanoid and humanoid.WalkSpeed ~= walkSpeed and not (flying or noclipActive or cframeSpeedActive) then
		humanoid.WalkSpeed = walkSpeed
	end
end)

player.CharacterAdded:Connect(function(character)
	stopFly()
	stopNoclip()
	stopFreecam()
	stopShiftlock()
	stopCFrameSpeed()
	character:WaitForChild("Humanoid", 5)
	applyWalkSpeedToLocalCharacter()
end)

-- ================= HUB ENABLE / DISABLE =================
-- Stänger av allt just nu aktivt OCH blockerar alla toggle-funktioner (via hubEnabled-
-- kollen i varje togglefunktion ovan) tills huben slås på igen. Inget går att aktivera
-- via vare sig knappar eller snabbkommandon medan den är avstängd.

local hubToggleButton

local function disableHub()
	hubEnabled = false

	stopFly()
	stopNoclip()
	stopFreecam()
	stopShiftlock()
	stopCFrameSpeed()
	stopSpectate()
	if espActive then
		espActive = false
		for character in espHighlights do
			removeESPHighlight(character)
		end
		if espButton then
			espButton.Text = "ESP: OFF"
			espButton.BackgroundColor3 = getButtonColor()
		end
	end
	if infJumpActive then
		infJumpActive = false
		if infJumpButton then
			infJumpButton.Text = "Infinite Jump: OFF"
			infJumpButton.BackgroundColor3 = getButtonColor()
		end
	end
	if clickTeleportActive then
		clickTeleportActive = false
		if clickTeleportButton then
			clickTeleportButton.Text = "Click Teleport: OFF"
			clickTeleportButton.BackgroundColor3 = getButtonColor()
		end
	end

	if hubToggleButton then
		hubToggleButton.Text = "Hub: OFF"
		hubToggleButton.BackgroundColor3 = Color3.fromRGB(200, 70, 70)
	end
end

local function enableHub()
	hubEnabled = true
	if hubToggleButton then
		hubToggleButton.Text = "Hub: ON"
		hubToggleButton.BackgroundColor3 = Color3.fromRGB(80, 200, 120)
	end
end

local function toggleHub()
	if hubEnabled then disableHub() else enableHub() end
end

-- ================= UI =================

local screenGui = Instance.new("ScreenGui")
screenGui.Name = "PlayerToolsUI"
screenGui.ResetOnSpawn = false
screenGui.Parent = playerGui

local EXPANDED_HEIGHT = 540
local FRAME_WIDTH = 480
local TITLEBAR_HEIGHT = 44
local SIDEBAR_WIDTH = 132

local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, FRAME_WIDTH, 0, EXPANDED_HEIGHT)
frame.Position = UDim2.new(0.5, -FRAME_WIDTH / 2, 0.05, 0)
frame.BackgroundColor3 = getPanelColor()
frame.BorderSizePixel = 0
frame.ClipsDescendants = true
frame.Parent = screenGui
registerThemed(frame, "panel")

local uiScale = Instance.new("UIScale")
uiScale.Scale = 1
uiScale.Parent = frame

local frameCorner = Instance.new("UICorner")
frameCorner.CornerRadius = UDim.new(0, 16)
frameCorner.Parent = frame

-- ===== Storleksändra genom att dra i nedre högra hörnet, som ett vanligt fönster =====
local resizeHandle = Instance.new("Frame")
resizeHandle.Size = UDim2.new(0, 20, 0, 20)
resizeHandle.AnchorPoint = Vector2.new(1, 1)
resizeHandle.Position = UDim2.new(1, -2, 1, -2)
resizeHandle.BackgroundTransparency = 1
resizeHandle.Active = true
resizeHandle.ZIndex = 10
resizeHandle.Parent = frame

-- Ritar ett litet diagonalt "grip"-mönster av prickar, som ett vanligt resize-handtag
local resizeDotPositions = {
	{ 14, 4 }, { 14, 9 }, { 9, 14 }, { 14, 14 }, { 4, 14 }, { 9, 9 },
}
for _, dotPos in resizeDotPositions do
	local dot = Instance.new("Frame")
	dot.Size = UDim2.new(0, 3, 0, 3)
	dot.Position = UDim2.new(0, dotPos[1], 0, dotPos[2])
	dot.BackgroundColor3 = Color3.fromRGB(190, 190, 196)
	dot.BackgroundTransparency = 0.2
	dot.BorderSizePixel = 0
	dot.Parent = resizeHandle

	local dotCorner = Instance.new("UICorner")
	dotCorner.CornerRadius = UDim.new(1, 0)
	dotCorner.Parent = dot
end

local resizing = false

resizeHandle.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		resizing = true
	end
end)

UserInputService.InputChanged:Connect(function(input)
	if resizing and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
		local topLeft = frame.AbsolutePosition
		local desiredWidth = input.Position.X - topLeft.X
		uiScale.Scale = math.clamp(desiredWidth / FRAME_WIDTH, 0.6, 1.6)
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		resizing = false
	end
end)

-- ===== Titelrad (dragbar) =====
local titleBar = Instance.new("Frame")
titleBar.Active = true
titleBar.Size = UDim2.new(1, 0, 0, TITLEBAR_HEIGHT)
titleBar.BackgroundColor3 = getTitleColor()
titleBar.BorderSizePixel = 0
titleBar.Parent = frame
registerThemed(titleBar, "title")

local titleBarCorner = Instance.new("UICorner")
titleBarCorner.CornerRadius = UDim.new(0, 16)
titleBarCorner.Parent = titleBar

local titleBarMask = Instance.new("Frame")
titleBarMask.Size = UDim2.new(1, 0, 0, 16)
titleBarMask.Position = UDim2.new(0, 0, 1, -16)
titleBarMask.BackgroundColor3 = getTitleColor()
titleBarMask.BorderSizePixel = 0
titleBarMask.ZIndex = 0
titleBarMask.Parent = titleBar
registerThemed(titleBarMask, "title")

local title = Instance.new("TextLabel")
title.Text = "Player Tools"
title.Font = Enum.Font.GothamBold
title.TextSize = 18
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.BackgroundTransparency = 1
title.Size = UDim2.new(1, -266, 1, 0)
title.Position = UDim2.new(0, 16, 0, 0)
title.TextXAlignment = Enum.TextXAlignment.Left
title.Parent = titleBar

local function createTitleBarButton(xOffsetFromRight, text)
	local button = Instance.new("TextButton")
	button.Text = text
	button.Font = Enum.Font.GothamBold
	button.TextSize = 15
	button.TextColor3 = Color3.fromRGB(255, 255, 255)
	button.BackgroundColor3 = getButtonColor()
	button.Size = UDim2.new(0, 28, 0, 28)
	button.Position = UDim2.new(1, xOffsetFromRight, 0.5, -14)
	button.Parent = titleBar

	local buttonCorner = Instance.new("UICorner")
	buttonCorner.CornerRadius = UDim.new(0, 8)
	buttonCorner.Parent = button

	registerThemed(button, "button")
	return button
end

local closeButton = createTitleBarButton(-36, "X")
local minimizeButton = createTitleBarButton(-74, "-")
local gearButton = createTitleBarButton(-112, "\226\154\153")

hubToggleButton = Instance.new("TextButton")
hubToggleButton.Text = "Hub: ON"
hubToggleButton.Font = Enum.Font.GothamBold
hubToggleButton.TextSize = 13
hubToggleButton.TextColor3 = Color3.fromRGB(255, 255, 255)
hubToggleButton.BackgroundColor3 = Color3.fromRGB(80, 200, 120)
hubToggleButton.Size = UDim2.new(0, 64, 0, 28)
hubToggleButton.Position = UDim2.new(1, -186, 0.5, -14)
hubToggleButton.Parent = titleBar

local hubToggleCorner = Instance.new("UICorner")
hubToggleCorner.CornerRadius = UDim.new(0, 8)
hubToggleCorner.Parent = hubToggleButton

hubToggleButton.MouseButton1Click:Connect(toggleHub)

local dragging = false
local dragStartMousePos = nil
local dragStartFramePos = nil

titleBar.InputBegan:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		dragging = true
		dragStartMousePos = input.Position
		dragStartFramePos = frame.Position
	end
end)

UserInputService.InputChanged:Connect(function(input)
	if dragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
		local delta = input.Position - dragStartMousePos
		frame.Position = UDim2.new(
			dragStartFramePos.X.Scale, dragStartFramePos.X.Offset + delta.X,
			dragStartFramePos.Y.Scale, dragStartFramePos.Y.Offset + delta.Y
		)
	end
end)

UserInputService.InputEnded:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
		dragging = false
	end
end)

-- ===== Sidebar + innehållsytor =====
local sidebar = Instance.new("Frame")
sidebar.Size = UDim2.new(0, SIDEBAR_WIDTH, 1, -TITLEBAR_HEIGHT)
sidebar.Position = UDim2.new(0, 0, 0, TITLEBAR_HEIGHT)
sidebar.BackgroundColor3 = getSidebarColor()
sidebar.BorderSizePixel = 0
sidebar.Parent = frame
registerThemed(sidebar, "sidebar")

local sidebarListLayout = Instance.new("UIListLayout")
sidebarListLayout.Padding = UDim.new(0, 4)
sidebarListLayout.SortOrder = Enum.SortOrder.LayoutOrder
sidebarListLayout.Parent = sidebar

local sidebarPadding = Instance.new("UIPadding")
sidebarPadding.PaddingTop = UDim.new(0, 12)
sidebarPadding.PaddingLeft = UDim.new(0, 8)
sidebarPadding.PaddingRight = UDim.new(0, 8)
sidebarPadding.Parent = sidebar

local divider = Instance.new("Frame")
divider.Size = UDim2.new(0, 1, 1, -TITLEBAR_HEIGHT)
divider.Position = UDim2.new(0, SIDEBAR_WIDTH, 0, TITLEBAR_HEIGHT)
divider.BackgroundColor3 = getButtonColor()
divider.BorderSizePixel = 0
divider.Parent = frame
registerThemed(divider, "button")

local function autoSizeCanvas(scrollingFrame, listLayout)
	local function update()
		scrollingFrame.CanvasSize = UDim2.new(0, 0, 0, listLayout.AbsoluteContentSize.Y + 20)
	end
	listLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(update)
	update()
end

local function createCategoryContent()
	local content = Instance.new("ScrollingFrame")
	content.Size = UDim2.new(1, -(SIDEBAR_WIDTH + 1), 1, -TITLEBAR_HEIGHT)
	content.Position = UDim2.new(0, SIDEBAR_WIDTH + 1, 0, TITLEBAR_HEIGHT)
	content.BackgroundTransparency = 1
	content.BorderSizePixel = 0
	content.ScrollBarThickness = 5
	content.ScrollBarImageColor3 = Color3.fromRGB(90, 90, 96)
	content.CanvasSize = UDim2.new(0, 0, 0, 0)
	content.Visible = false
	content.Parent = frame

	local listLayout = Instance.new("UIListLayout")
	listLayout.Padding = UDim.new(0, 14)
	listLayout.SortOrder = Enum.SortOrder.LayoutOrder
	listLayout.Parent = content
	autoSizeCanvas(content, listLayout)

	local padding = Instance.new("UIPadding")
	padding.PaddingLeft = UDim.new(0, 18)
	padding.PaddingRight = UDim.new(0, 18)
	padding.PaddingTop = UDim.new(0, 16)
	padding.PaddingBottom = UDim.new(0, 16)
	padding.Parent = content

	return content
end

local movementContent = createCategoryContent()
local visualContent = createCategoryContent()
local playersContent = createCategoryContent()

local settingsContent = Instance.new("ScrollingFrame")
settingsContent.Size = UDim2.new(1, 0, 1, -TITLEBAR_HEIGHT)
settingsContent.Position = UDim2.new(0, 0, 0, TITLEBAR_HEIGHT)
settingsContent.BackgroundTransparency = 1
settingsContent.BorderSizePixel = 0
settingsContent.ScrollBarThickness = 5
settingsContent.CanvasSize = UDim2.new(0, 0, 0, 0)
settingsContent.Visible = false
settingsContent.Parent = frame

local settingsListLayout = Instance.new("UIListLayout")
settingsListLayout.Padding = UDim.new(0, 12)
settingsListLayout.SortOrder = Enum.SortOrder.LayoutOrder
settingsListLayout.Parent = settingsContent
autoSizeCanvas(settingsContent, settingsListLayout)

local settingsPadding = Instance.new("UIPadding")
settingsPadding.PaddingLeft = UDim.new(0, 18)
settingsPadding.PaddingRight = UDim.new(0, 18)
settingsPadding.PaddingTop = UDim.new(0, 16)
settingsPadding.PaddingBottom = UDim.new(0, 16)
settingsPadding.Parent = settingsContent

-- ===== Minimera / kategorier / inställningsvy =====
local minimized = false
local showingSettings = false
local currentCategory = "Movement"
local categoryEntries = {}

local function selectCategory(name)
	currentCategory = name
	for catName, info in categoryEntries do
		local isSelected = catName == name
		info.indicator.Visible = isSelected
		info.button.TextColor3 = isSelected and Color3.fromRGB(255, 255, 255) or Color3.fromRGB(175, 175, 182)
		if not showingSettings then
			info.content.Visible = isSelected
		end
	end
end

local function setShowingSettings(state)
	showingSettings = state
	if minimized then return end
	sidebar.Visible = not state
	divider.Visible = not state
	settingsContent.Visible = state
	for catName, info in categoryEntries do
		info.content.Visible = (not state) and (catName == currentCategory)
	end
end

local minimizeTween = nil
local MINIMIZE_TWEEN_INFO = TweenInfo.new(0.28, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)

local function setMinimized(state)
	minimized = state

	if minimizeTween then
		minimizeTween:Cancel()
		minimizeTween = nil
	end

	if minimized then
		minimizeButton.Text = "+"
		resizeHandle.Visible = false
		minimizeTween = TweenService:Create(frame, MINIMIZE_TWEEN_INFO, {
			Size = UDim2.new(0, FRAME_WIDTH, 0, TITLEBAR_HEIGHT),
		})
		minimizeTween.Completed:Connect(function()
			if minimized then
				sidebar.Visible = false
				divider.Visible = false
				settingsContent.Visible = false
				for _, info in categoryEntries do info.content.Visible = false end
			end
		end)
		minimizeTween:Play()
	else
		sidebar.Visible = not showingSettings
		divider.Visible = not showingSettings
		settingsContent.Visible = showingSettings
		resizeHandle.Visible = true
		for catName, info in categoryEntries do
			info.content.Visible = (not showingSettings) and (catName == currentCategory)
		end
		minimizeButton.Text = "-"
		minimizeTween = TweenService:Create(frame, MINIMIZE_TWEEN_INFO, {
			Size = UDim2.new(0, FRAME_WIDTH, 0, EXPANDED_HEIGHT),
		})
		minimizeTween:Play()
	end
end

minimizeButton.MouseButton1Click:Connect(function()
	setMinimized(not minimized)
end)

gearButton.MouseButton1Click:Connect(function()
	setShowingSettings(not showingSettings)
end)

closeButton.MouseButton1Click:Connect(function()
	disableHub()
	screenGui:Destroy()
end)

-- ===== Återanvändbara byggare =====
local nextLayoutOrder = 0
local function getNextLayoutOrder()
	nextLayoutOrder = nextLayoutOrder + 10
	return nextLayoutOrder
end

local function createToggleButton(parent, text, onClick)
	local row = Instance.new("Frame")
	row.Size = UDim2.new(1, 0, 0, 36)
	row.BackgroundTransparency = 1
	row.LayoutOrder = getNextLayoutOrder()
	row.Parent = parent

	local button = Instance.new("TextButton")
	button.Text = text
	button.Font = Enum.Font.GothamBold
	button.TextSize = 15
	button.TextColor3 = Color3.fromRGB(255, 255, 255)
	button.BackgroundColor3 = getButtonColor()
	button.Size = UDim2.new(1, 0, 1, 0)
	button.Parent = row

	local buttonCorner = Instance.new("UICorner")
	buttonCorner.CornerRadius = UDim.new(0, 10)
	buttonCorner.Parent = button

	button.MouseButton1Click:Connect(onClick)
	return button
end

local function createHintLabel(parent, text)
	local hint = Instance.new("TextLabel")
	hint.Font = Enum.Font.Gotham
	hint.TextSize = 12
	hint.TextColor3 = Color3.fromRGB(150, 150, 158)
	hint.BackgroundTransparency = 1
	hint.Size = UDim2.new(1, 0, 0, 16)
	hint.LayoutOrder = getNextLayoutOrder()
	hint.TextXAlignment = Enum.TextXAlignment.Left
	hint.Text = text
	hint.Parent = parent
	return hint
end

local function createSliderRow(parent, labelPrefix, min, max, initial, suffix, onChange)
	local row = Instance.new("Frame")
	row.Size = UDim2.new(1, 0, 0, 46)
	row.BackgroundTransparency = 1
	row.LayoutOrder = getNextLayoutOrder()
	row.Parent = parent

	local label = Instance.new("TextLabel")
	label.Font = Enum.Font.Gotham
	label.TextSize = 14
	label.TextColor3 = Color3.fromRGB(205, 205, 210)
	label.BackgroundTransparency = 1
	label.Size = UDim2.new(1, 0, 0, 18)
	label.TextXAlignment = Enum.TextXAlignment.Left
	label.Parent = row

	local track = Instance.new("Frame")
	track.Active = true
	track.Size = UDim2.new(1, 0, 0, 8)
	track.Position = UDim2.new(0, 0, 0, 28)
	track.BackgroundColor3 = getButtonColor()
	track.BorderSizePixel = 0
	track.Parent = row
	registerThemed(track, "button")

	local trackCorner = Instance.new("UICorner")
	trackCorner.CornerRadius = UDim.new(1, 0)
	trackCorner.Parent = track

	local fill = Instance.new("Frame")
	fill.BackgroundColor3 = accentColor
	fill.BorderSizePixel = 0
	fill.Size = UDim2.new(0, 0, 1, 0)
	fill.Parent = track
	registerThemed(fill, "accent")

	local fillCorner = Instance.new("UICorner")
	fillCorner.CornerRadius = UDim.new(1, 0)
	fillCorner.Parent = fill

	local knob = Instance.new("Frame")
	knob.Active = true
	knob.Size = UDim2.new(0, 18, 0, 18)
	knob.AnchorPoint = Vector2.new(0.5, 0.5)
	knob.Position = UDim2.new(0, 0, 0.5, 0)
	knob.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
	knob.BorderSizePixel = 0
	knob.ZIndex = 2
	knob.Parent = track

	local knobCorner = Instance.new("UICorner")
	knobCorner.CornerRadius = UDim.new(1, 0)
	knobCorner.Parent = knob

	local sliderDragging = false

	local function setFromAlpha(alpha)
		alpha = math.clamp(alpha, 0, 1)
		knob.Position = UDim2.new(alpha, 0, 0.5, 0)
		fill.Size = UDim2.new(alpha, 0, 1, 0)
		local value = min + (max - min) * alpha
		label.Text = string.format("%s: %.1f%s", labelPrefix, value, suffix)
		onChange(value)
	end

	local function alphaFromInput(input)
		local trackPos = track.AbsolutePosition.X
		local trackSize = track.AbsoluteSize.X
		if trackSize <= 0 then return 0 end
		return (input.Position.X - trackPos) / trackSize
	end

	knob.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			sliderDragging = true
		end
	end)

	track.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			sliderDragging = true
			setFromAlpha(alphaFromInput(input))
		end
	end)

	UserInputService.InputChanged:Connect(function(input)
		if sliderDragging and (input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch) then
			setFromAlpha(alphaFromInput(input))
		end
	end)

	UserInputService.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then
			sliderDragging = false
		end
	end)

	local initialAlpha = (initial - min) / (max - min)
	setFromAlpha(initialAlpha)

	return row
end

local function createCategoryButton(name, content, layoutOrder)
	local button = Instance.new("TextButton")
	button.Text = name
	button.Font = Enum.Font.GothamBold
	button.TextSize = 14
	button.TextColor3 = Color3.fromRGB(175, 175, 182)
	button.BackgroundTransparency = 1
	button.Size = UDim2.new(1, 0, 0, 38)
	button.TextXAlignment = Enum.TextXAlignment.Left
	button.LayoutOrder = layoutOrder
	button.Parent = sidebar

	local buttonPadding = Instance.new("UIPadding")
	buttonPadding.PaddingLeft = UDim.new(0, 14)
	buttonPadding.Parent = button

	local indicator = Instance.new("Frame")
	indicator.Size = UDim2.new(0, 3, 0, 20)
	indicator.AnchorPoint = Vector2.new(0, 0.5)
	indicator.Position = UDim2.new(0, -8, 0.5, 0)
	indicator.BackgroundColor3 = accentColor
	indicator.BorderSizePixel = 0
	indicator.Visible = false
	indicator.Parent = button
	registerThemed(indicator, "accent")

	local indicatorCorner = Instance.new("UICorner")
	indicatorCorner.CornerRadius = UDim.new(1, 0)
	indicatorCorner.Parent = indicator

	categoryEntries[name] = { button = button, indicator = indicator, content = content }

	button.MouseButton1Click:Connect(function()
		selectCategory(name)
	end)

	return button
end

createCategoryButton("Movement", movementContent, 1)
createCategoryButton("Visual", visualContent, 2)
createCategoryButton("Players", playersContent, 3)

-- ===== Movement-kategorin, i bokstavsordning =====

createSliderRow(movementContent, "CFrame Speed", 10, 200, cframeSpeed, "", function(value)
	cframeSpeed = value
end)
cframeSpeedButton = createToggleButton(movementContent, "CFrame Speed: OFF", toggleCFrameSpeed)

clickTeleportButton = createToggleButton(movementContent, "Click Teleport: OFF", toggleClickTeleport)

createSliderRow(movementContent, "Fly Speed", 10, 200, flySpeed, "", function(value)
	flySpeed = value
end)
flyButton = createToggleButton(movementContent, "Fly: OFF", toggleFly)

freecamHintLabel = createHintLabel(movementContent, "Mouse locks in freecam - press " .. keybinds.Freecam.Name .. " to exit")
createSliderRow(movementContent, "Freecam Speed", 10, 200, freecamSpeed, "", function(value)
	freecamSpeed = value
end)
freecamButton = createToggleButton(movementContent, "Freecam: OFF", toggleFreecam)

createSliderRow(movementContent, "Gravity", 10, 300, workspace.Gravity, "", function(value)
	workspace.Gravity = value
end)

infJumpButton = createToggleButton(movementContent, "Infinite Jump: OFF", toggleInfJump)

noclipButton = createToggleButton(movementContent, "Noclip: OFF", toggleNoclip)

shiftlockButton = createToggleButton(movementContent, "Shiftlock: OFF", toggleShiftlock)

createSliderRow(movementContent, "WalkSpeed", 16, 200, walkSpeed, "", function(value)
	setWalkSpeed(value)
end)

-- ===== Visual-kategorin, i bokstavsordning =====

espButton = createToggleButton(visualContent, "ESP: OFF", toggleESP)

createSliderRow(visualContent, "Head Scale", MIN_SCALE, MAX_SCALE, INITIAL_SCALE, "x", function(value)
	applyHeadScaleToAll(value)
end)

-- ===== Players-kategorin =====

do
	local label = Instance.new("TextLabel")
	label.Text = "Spectate"
	label.Font = Enum.Font.Gotham
	label.TextSize = 14
	label.TextColor3 = Color3.fromRGB(205, 205, 210)
	label.BackgroundTransparency = 1
	label.Size = UDim2.new(1, -60, 0, 18)
	label.LayoutOrder = getNextLayoutOrder()
	label.TextXAlignment = Enum.TextXAlignment.Left
	label.Parent = playersContent

	local stopButton = Instance.new("TextButton")
	stopButton.Text = "Stop"
	stopButton.Font = Enum.Font.GothamBold
	stopButton.TextSize = 12
	stopButton.TextColor3 = Color3.fromRGB(255, 255, 255)
	stopButton.BackgroundColor3 = getButtonColor()
	stopButton.Size = UDim2.new(0, 56, 0, 20)
	stopButton.LayoutOrder = label.LayoutOrder
	stopButton.AnchorPoint = Vector2.new(1, 0)
	stopButton.Position = UDim2.new(1, 0, 0, 0)
	stopButton.Parent = playersContent

	local stopCorner = Instance.new("UICorner")
	stopCorner.CornerRadius = UDim.new(0, 6)
	stopCorner.Parent = stopButton
	registerThemed(stopButton, "button")

	stopButton.MouseButton1Click:Connect(function()
		stopSpectate()
	end)

	local listRow = Instance.new("Frame")
	listRow.Size = UDim2.new(1, 0, 0, 220)
	listRow.BackgroundTransparency = 1
	listRow.LayoutOrder = getNextLayoutOrder()
	listRow.Parent = playersContent

	local listFrame = Instance.new("ScrollingFrame")
	listFrame.Size = UDim2.new(1, 0, 1, 0)
	listFrame.BackgroundColor3 = getListColor()
	listFrame.BorderSizePixel = 0
	listFrame.ScrollBarThickness = 4
	listFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
	listFrame.Parent = listRow
	registerThemed(listFrame, "list")

	local listCorner = Instance.new("UICorner")
	listCorner.CornerRadius = UDim.new(0, 8)
	listCorner.Parent = listFrame

	local listLayout = Instance.new("UIListLayout")
	listLayout.Padding = UDim.new(0, 4)
	listLayout.SortOrder = Enum.SortOrder.LayoutOrder
	listLayout.Parent = listFrame
	autoSizeCanvas(listFrame, listLayout)

	local listPadding = Instance.new("UIPadding")
	listPadding.PaddingLeft = UDim.new(0, 6)
	listPadding.PaddingRight = UDim.new(0, 6)
	listPadding.PaddingTop = UDim.new(0, 6)
	listPadding.PaddingBottom = UDim.new(0, 6)
	listPadding.Parent = listFrame

	local playerButtons = {}

	local function addPlayerButton(plr)
		if plr == player then return end
		if playerButtons[plr] then return end

		local btn = Instance.new("TextButton")
		btn.Text = plr.Name
		btn.Font = Enum.Font.Gotham
		btn.TextSize = 14
		btn.TextColor3 = Color3.fromRGB(220, 220, 225)
		btn.BackgroundColor3 = getButtonColor()
		btn.Size = UDim2.new(1, 0, 0, 26)
		btn.Parent = listFrame
		registerThemed(btn, "button")

		local btnCorner = Instance.new("UICorner")
		btnCorner.CornerRadius = UDim.new(0, 6)
		btnCorner.Parent = btn

		btn.MouseButton1Click:Connect(function()
			startSpectate(plr)
		end)

		playerButtons[plr] = btn
	end

	local function removePlayerButton(plr)
		local btn = playerButtons[plr]
		if btn then
			btn:Destroy()
			playerButtons[plr] = nil
		end
	end

	for _, plr in Players:GetPlayers() do
		addPlayerButton(plr)
	end
	Players.PlayerAdded:Connect(addPlayerButton)
	Players.PlayerRemoving:Connect(removePlayerButton)
end

-- ===== Settings-vyn =====

do
	local backRow = Instance.new("Frame")
	backRow.Size = UDim2.new(1, 0, 0, 32)
	backRow.BackgroundTransparency = 1
	backRow.LayoutOrder = 1
	backRow.Parent = settingsContent

	local backButton = Instance.new("TextButton")
	backButton.Text = "< Back"
	backButton.Font = Enum.Font.GothamBold
	backButton.TextSize = 14
	backButton.TextColor3 = Color3.fromRGB(255, 255, 255)
	backButton.BackgroundColor3 = getButtonColor()
	backButton.Size = UDim2.new(0, 100, 1, 0)
	backButton.Parent = backRow
	registerThemed(backButton, "button")

	local backCorner = Instance.new("UICorner")
	backCorner.CornerRadius = UDim.new(0, 8)
	backCorner.Parent = backButton

	backButton.MouseButton1Click:Connect(function()
		setShowingSettings(false)
	end)

	local keybindsHeader = Instance.new("TextLabel")
	keybindsHeader.Text = "Keybinds"
	keybindsHeader.Font = Enum.Font.GothamBold
	keybindsHeader.TextSize = 15
	keybindsHeader.TextColor3 = Color3.fromRGB(255, 255, 255)
	keybindsHeader.BackgroundTransparency = 1
	keybindsHeader.Size = UDim2.new(1, 0, 0, 20)
	keybindsHeader.TextXAlignment = Enum.TextXAlignment.Left
	keybindsHeader.LayoutOrder = 2
	keybindsHeader.Parent = settingsContent

	local function createKeybindRow(order, label, action)
		local row = Instance.new("Frame")
		row.Size = UDim2.new(1, 0, 0, 32)
		row.BackgroundTransparency = 1
		row.LayoutOrder = order
		row.Parent = settingsContent

		local labelText = Instance.new("TextLabel")
		labelText.Text = label
		labelText.Font = Enum.Font.Gotham
		labelText.TextSize = 14
		labelText.TextColor3 = Color3.fromRGB(205, 205, 210)
		labelText.BackgroundTransparency = 1
		labelText.Size = UDim2.new(0.5, 0, 1, 0)
		labelText.TextXAlignment = Enum.TextXAlignment.Left
		labelText.Parent = row

		local keyButton = Instance.new("TextButton")
		keyButton.Text = keybinds[action].Name
		keyButton.Font = Enum.Font.GothamBold
		keyButton.TextSize = 13
		keyButton.TextColor3 = Color3.fromRGB(255, 255, 255)
		keyButton.BackgroundColor3 = getButtonColor()
		keyButton.Size = UDim2.new(0.5, -4, 0, 28)
		keyButton.Position = UDim2.new(0.5, 4, 0, 2)
		keyButton.Parent = row
		registerThemed(keyButton, "button")

		local keyButtonCorner = Instance.new("UICorner")
		keyButtonCorner.CornerRadius = UDim.new(0, 6)
		keyButtonCorner.Parent = keyButton

		keybindButtons[action] = keyButton

		keyButton.MouseButton1Click:Connect(function()
			beginRebind(action, keyButton)
		end)
	end

	createKeybindRow(3, "CFrame Speed", "CFrameSpeed")
	createKeybindRow(4, "Click Teleport", "ClickTeleport")
	createKeybindRow(5, "Fly", "Fly")
	createKeybindRow(6, "Noclip", "Noclip")
	createKeybindRow(7, "Freecam", "Freecam")
	createKeybindRow(8, "Shiftlock", "Shiftlock")

	local colorHeader = Instance.new("TextLabel")
	colorHeader.Text = "UI Color"
	colorHeader.Font = Enum.Font.GothamBold
	colorHeader.TextSize = 15
	colorHeader.TextColor3 = Color3.fromRGB(255, 255, 255)
	colorHeader.BackgroundTransparency = 1
	colorHeader.Size = UDim2.new(1, 0, 0, 20)
	colorHeader.TextXAlignment = Enum.TextXAlignment.Left
	colorHeader.LayoutOrder = 9
	colorHeader.Parent = settingsContent

	local swatchRow = Instance.new("Frame")
	swatchRow.Size = UDim2.new(1, 0, 0, 30)
	swatchRow.BackgroundTransparency = 1
	swatchRow.LayoutOrder = 10
	swatchRow.Parent = settingsContent

	local swatchSize = 28
	local spacing = 8
	for i, color in presetColors do
		local swatch = Instance.new("TextButton")
		swatch.Text = ""
		swatch.BackgroundColor3 = color
		swatch.Size = UDim2.new(0, swatchSize, 0, swatchSize)
		swatch.Position = UDim2.new(0, (i - 1) * (swatchSize + spacing), 0, 0)
		swatch.Parent = swatchRow

		local swatchCorner = Instance.new("UICorner")
		swatchCorner.CornerRadius = UDim.new(1, 0)
		swatchCorner.Parent = swatch

		swatch.MouseButton1Click:Connect(function()
			setAccentColor(color)
		end)
	end
end

selectCategory("Movement")

Features & Information

Fly, Freecam, Noclip, CFrame speed and much much more!
#UI#Free#Fly#Sweden

Community Comments (0)

No comments yet for this script.

More Scripts for Universal Scripts