--[[ Modern Flight Controller (Roblox Studio) SINGLE SELF-CONTAINED LOCALSCRIPT Place this LocalScript in: StarterPlayer > StarterPlayerScripts Controls: - Toggle flight: F (changeable from the UI) - Move: WASD - Up: Space - Down: LeftControl Notes: - This is intended for a game you own or are developing. - BindableEvents are created under PlayerScripts/FlightBindings: ToggleRequested FlightStateChanged SpeedChanged ]] local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local TweenService = game:GetService("TweenService") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") local playerScripts = player:WaitForChild("PlayerScripts") --// Configuration local DEFAULT_SPEED = 65 local MIN_SPEED = 20 local MAX_SPEED = 180 local DEFAULT_TOGGLE_KEY = Enum.KeyCode.F local speed = DEFAULT_SPEED local toggleKey = DEFAULT_TOGGLE_KEY local flying = false local listeningForKey = false local destroyed = false local character: Model? local humanoid: Humanoid? local rootPart: BasePart? local flightAttachment: Attachment? local linearVelocity: LinearVelocity? local alignOrientation: AlignOrientation? --// Bindable interface local bindingsFolder = playerScripts:FindFirstChild("FlightBindings") if not bindingsFolder then bindingsFolder = Instance.new("Folder") bindingsFolder.Name = "FlightBindings" bindingsFolder.Parent = playerScripts end local function getOrCreateBindable(name: string): BindableEvent local existing = bindingsFolder:FindFirstChild(name) if existing and existing:IsA("BindableEvent") then return existing end if existing then existing:Destroy() end local event = Instance.new("BindableEvent") event.Name = name event.Parent = bindingsFolder return event end local toggleRequested = getOrCreateBindable("ToggleRequested") local flightStateChanged = getOrCreateBindable("FlightStateChanged") local speedChanged = getOrCreateBindable("SpeedChanged") --// UI helpers local function create(className: string, properties: {[string]: any}, parent: Instance?): Instance local instance = Instance.new(className) for property, value in properties do instance[property] = value end if parent then instance.Parent = parent end return instance end local screenGui = create("ScreenGui", { Name = "ModernFlightUI", ResetOnSpawn = false, IgnoreGuiInset = true, ZIndexBehavior = Enum.ZIndexBehavior.Sibling, }, playerGui) :: ScreenGui local shadow = create("ImageLabel", { Name = "Shadow", AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.55), Size = UDim2.fromOffset(350, 250), BackgroundTransparency = 1, Image = "rbxassetid://1316045217", ImageColor3 = Color3.fromRGB(0, 0, 0), ImageTransparency = 0.35, ScaleType = Enum.ScaleType.Slice, SliceCenter = Rect.new(10, 10, 118, 118), }, screenGui) :: ImageLabel local panel = create("Frame", { Name = "Panel", AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale(0.5, 0.5), Size = UDim2.fromOffset(330, 230), BackgroundColor3 = Color3.fromRGB(18, 20, 27), BorderSizePixel = 0, }, screenGui) :: Frame create("UICorner", { CornerRadius = UDim.new(0, 16), }, panel) create("UIStroke", { Color = Color3.fromRGB(58, 62, 78), Transparency = 0.35, Thickness = 1, }, panel) local openButton = create("TextButton", { Name = "OpenFlightUI", AnchorPoint = Vector2.new(0, 0.5), Position = UDim2.new(0, 14, 0.5, 0), Size = UDim2.fromOffset(54, 54), BackgroundColor3 = Color3.fromRGB(103, 92, 245), BorderSizePixel = 0, AutoButtonColor = false, Font = Enum.Font.GothamBold, Text = "FLY", TextColor3 = Color3.fromRGB(248, 248, 252), TextSize = 12, Visible = false, }, screenGui) :: TextButton create("UICorner", { CornerRadius = UDim.new(1, 0), }, openButton) create("UIStroke", { Color = Color3.fromRGB(164, 157, 255), Transparency = 0.25, Thickness = 1, }, openButton) local topBar = create("Frame", { Name = "TopBar", Size = UDim2.new(1, 0, 0, 54), BackgroundTransparency = 1, Active = true, }, panel) :: Frame local title = create("TextLabel", { Name = "Title", Position = UDim2.fromOffset(18, 9), Size = UDim2.new(1, -70, 0, 24), BackgroundTransparency = 1, Font = Enum.Font.GothamBold, Text = "FLIGHT CONTROLLER", TextColor3 = Color3.fromRGB(242, 244, 250), TextSize = 16, TextXAlignment = Enum.TextXAlignment.Left, }, topBar) :: TextLabel local subtitle = create("TextLabel", { Name = "Subtitle", Position = UDim2.fromOffset(18, 31), Size = UDim2.new(1, -70, 0, 16), BackgroundTransparency = 1, Font = Enum.Font.Gotham, Text = "WASD · Space · Left Ctrl", TextColor3 = Color3.fromRGB(138, 143, 159), TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, }, topBar) :: TextLabel local closeButton = create("TextButton", { Name = "Close", AnchorPoint = Vector2.new(1, 0.5), Position = UDim2.new(1, -14, 0.5, 0), Size = UDim2.fromOffset(30, 30), BackgroundColor3 = Color3.fromRGB(31, 34, 44), BorderSizePixel = 0, AutoButtonColor = false, Font = Enum.Font.GothamBold, Text = "×", TextColor3 = Color3.fromRGB(190, 194, 207), TextSize = 19, }, topBar) :: TextButton create("UICorner", { CornerRadius = UDim.new(0, 9), }, closeButton) local divider = create("Frame", { Position = UDim2.fromOffset(16, 54), Size = UDim2.new(1, -32, 0, 1), BackgroundColor3 = Color3.fromRGB(48, 51, 64), BorderSizePixel = 0, }, panel) local statusLabel = create("TextLabel", { Position = UDim2.fromOffset(18, 68), Size = UDim2.fromOffset(110, 18), BackgroundTransparency = 1, Font = Enum.Font.GothamMedium, Text = "FLIGHT STATUS", TextColor3 = Color3.fromRGB(139, 144, 160), TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, }, panel) :: TextLabel local toggleButton = create("TextButton", { Name = "ToggleFlight", Position = UDim2.fromOffset(18, 91), Size = UDim2.new(1, -36, 0, 44), BackgroundColor3 = Color3.fromRGB(44, 47, 60), BorderSizePixel = 0, AutoButtonColor = false, Font = Enum.Font.GothamBold, Text = "ENABLE FLIGHT", TextColor3 = Color3.fromRGB(235, 237, 244), TextSize = 13, }, panel) :: TextButton create("UICorner", { CornerRadius = UDim.new(0, 11), }, toggleButton) local speedText = create("TextLabel", { Position = UDim2.fromOffset(18, 148), Size = UDim2.fromOffset(160, 18), BackgroundTransparency = 1, Font = Enum.Font.GothamMedium, Text = ("SPEED %d"):format(speed), TextColor3 = Color3.fromRGB(188, 192, 204), TextSize = 11, TextXAlignment = Enum.TextXAlignment.Left, }, panel) :: TextLabel local sliderTrack = create("Frame", { Position = UDim2.fromOffset(18, 175), Size = UDim2.new(1, -134, 0, 6), BackgroundColor3 = Color3.fromRGB(48, 51, 64), BorderSizePixel = 0, Active = true, }, panel) :: Frame create("UICorner", { CornerRadius = UDim.new(1, 0), }, sliderTrack) local sliderFill = create("Frame", { Size = UDim2.fromScale((speed - MIN_SPEED) / (MAX_SPEED - MIN_SPEED), 1), BackgroundColor3 = Color3.fromRGB(115, 105, 255), BorderSizePixel = 0, }, sliderTrack) :: Frame create("UICorner", { CornerRadius = UDim.new(1, 0), }, sliderFill) local sliderKnob = create("Frame", { AnchorPoint = Vector2.new(0.5, 0.5), Position = UDim2.fromScale((speed - MIN_SPEED) / (MAX_SPEED - MIN_SPEED), 0.5), Size = UDim2.fromOffset(16, 16), BackgroundColor3 = Color3.fromRGB(238, 239, 246), BorderSizePixel = 0, }, sliderTrack) :: Frame create("UICorner", { CornerRadius = UDim.new(1, 0), }, sliderKnob) create("UIStroke", { Color = Color3.fromRGB(112, 103, 255), Thickness = 2, }, sliderKnob) local keybindButton = create("TextButton", { Name = "Keybind", AnchorPoint = Vector2.new(1, 0), Position = UDim2.new(1, -18, 0, 148), Size = UDim2.fromOffset(96, 38), BackgroundColor3 = Color3.fromRGB(31, 34, 44), BorderSizePixel = 0, AutoButtonColor = false, Font = Enum.Font.GothamBold, Text = "KEY: F", TextColor3 = Color3.fromRGB(208, 211, 222), TextSize = 11, }, panel) :: TextButton create("UICorner", { CornerRadius = UDim.new(0, 10), }, keybindButton) local footer = create("TextLabel", { AnchorPoint = Vector2.new(0.5, 1), Position = UDim2.new(0.5, 0, 1, -12), Size = UDim2.new(1, -36, 0, 18), BackgroundTransparency = 1, Font = Enum.Font.Gotham, Text = "Click the key button, then press a new keyboard key.", TextColor3 = Color3.fromRGB(104, 109, 124), TextSize = 10, }, panel) :: TextLabel --// Dragging do local dragging = false local dragStart = Vector2.zero local panelStart = panel.Position topBar.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position panelStart = panel.Position end end) UserInputService.InputChanged:Connect(function(input) if not dragging then return end if input.UserInputType ~= Enum.UserInputType.MouseMovement and input.UserInputType ~= Enum.UserInputType.Touch then return end local delta = input.Position - dragStart panel.Position = UDim2.new( panelStart.X.Scale, panelStart.X.Offset + delta.X, panelStart.Y.Scale, panelStart.Y.Offset + delta.Y ) shadow.Position = panel.Position + UDim2.fromOffset(0, 18) end) UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = false end end) end --// Character and flight local function removeFlightObjects() if alignOrientation then alignOrientation:Destroy() alignOrientation = nil end if linearVelocity then linearVelocity:Destroy() linearVelocity = nil end if flightAttachment then flightAttachment:Destroy() flightAttachment = nil end end local function updateUI() if flying then toggleButton.Text = "DISABLE FLIGHT" TweenService:Create( toggleButton, TweenInfo.new(0.18, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {BackgroundColor3 = Color3.fromRGB(103, 92, 245)} ):Play() else toggleButton.Text = "ENABLE FLIGHT" TweenService:Create( toggleButton, TweenInfo.new(0.18, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {BackgroundColor3 = Color3.fromRGB(44, 47, 60)} ):Play() end end local function setCharacter(newCharacter: Model) character = newCharacter humanoid = newCharacter:WaitForChild("Humanoid") :: Humanoid rootPart = newCharacter:WaitForChild("HumanoidRootPart") :: BasePart flying = false removeFlightObjects() updateUI() end local function enableFlight() if flying or not character or not humanoid or not rootPart then return end if humanoid.Health <= 0 or humanoid.Sit then return end removeFlightObjects() flightAttachment = Instance.new("Attachment") flightAttachment.Name = "FlightAttachment" flightAttachment.Parent = rootPart linearVelocity = Instance.new("LinearVelocity") linearVelocity.Name = "FlightLinearVelocity" linearVelocity.Attachment0 = flightAttachment linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World linearVelocity.MaxForce = math.huge linearVelocity.VectorVelocity = Vector3.zero linearVelocity.Parent = rootPart alignOrientation = Instance.new("AlignOrientation") alignOrientation.Name = "FlightAlignOrientation" alignOrientation.Attachment0 = flightAttachment alignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment alignOrientation.MaxTorque = math.huge alignOrientation.Responsiveness = 25 alignOrientation.RigidityEnabled = false alignOrientation.Parent = rootPart humanoid.AutoRotate = false humanoid:ChangeState(Enum.HumanoidStateType.Physics) flying = true updateUI() flightStateChanged:Fire(true) end local function disableFlight() if not flying then return end flying = false removeFlightObjects() if humanoid then humanoid.AutoRotate = true if humanoid.Health > 0 then humanoid:ChangeState(Enum.HumanoidStateType.GettingUp) end end updateUI() flightStateChanged:Fire(false) end local function setFlying(enabled: boolean) if enabled then enableFlight() else disableFlight() end end local function toggleFlight() setFlying(not flying) end local function calculateDirection(camera: Camera): Vector3 local direction = Vector3.zero local cameraCFrame = camera.CFrame local forward = Vector3.new(cameraCFrame.LookVector.X, 0, cameraCFrame.LookVector.Z) local right = Vector3.new(cameraCFrame.RightVector.X, 0, cameraCFrame.RightVector.Z) if forward.Magnitude > 0 then forward = forward.Unit end if right.Magnitude > 0 then right = right.Unit end if UserInputService:IsKeyDown(Enum.KeyCode.W) then direction += forward end if UserInputService:IsKeyDown(Enum.KeyCode.S) then direction -= forward end if UserInputService:IsKeyDown(Enum.KeyCode.D) then direction += right end if UserInputService:IsKeyDown(Enum.KeyCode.A) then direction -= right end if UserInputService:IsKeyDown(Enum.KeyCode.Space) then direction += Vector3.yAxis end if UserInputService:IsKeyDown(Enum.KeyCode.LeftControl) then direction -= Vector3.yAxis end if direction.Magnitude > 1 then direction = direction.Unit end return direction end RunService.RenderStepped:Connect(function() if not flying or not humanoid or not rootPart or not linearVelocity or not alignOrientation then return end if humanoid.Health <= 0 then disableFlight() return end local camera = workspace.CurrentCamera if not camera then return end local direction = calculateDirection(camera) linearVelocity.VectorVelocity = direction * speed local flatLook = Vector3.new(camera.CFrame.LookVector.X, 0, camera.CFrame.LookVector.Z) if flatLook.Magnitude > 0.001 then alignOrientation.CFrame = CFrame.lookAt(rootPart.Position, rootPart.Position + flatLook.Unit) end end) --// Slider do local sliding = false local function applySliderPosition(screenX: number) local relative = math.clamp( (screenX - sliderTrack.AbsolutePosition.X) / sliderTrack.AbsoluteSize.X, 0, 1 ) speed = math.floor(MIN_SPEED + ((MAX_SPEED - MIN_SPEED) * relative) + 0.5) speedText.Text = ("SPEED %d"):format(speed) sliderFill.Size = UDim2.fromScale(relative, 1) sliderKnob.Position = UDim2.fromScale(relative, 0.5) speedChanged:Fire(speed) end sliderTrack.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then sliding = true applySliderPosition(input.Position.X) end end) UserInputService.InputChanged:Connect(function(input) if not sliding then return end if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then applySliderPosition(input.Position.X) end end) UserInputService.InputEnded:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then sliding = false end end) end --// Button effects local function bindHover(button: TextButton, normalColor: Color3, hoverColor: Color3) button.MouseEnter:Connect(function() TweenService:Create( button, TweenInfo.new(0.12), {BackgroundColor3 = hoverColor} ):Play() end) button.MouseLeave:Connect(function() if button == toggleButton and flying then return end TweenService:Create( button, TweenInfo.new(0.12), {BackgroundColor3 = normalColor} ):Play() end) end bindHover(closeButton, Color3.fromRGB(31, 34, 44), Color3.fromRGB(58, 42, 50)) bindHover(keybindButton, Color3.fromRGB(31, 34, 44), Color3.fromRGB(43, 46, 59)) toggleButton.MouseButton1Click:Connect(toggleFlight) closeButton.MouseButton1Click:Connect(function() panel.Visible = false shadow.Visible = false openButton.Visible = true end) openButton.MouseButton1Click:Connect(function() openButton.Visible = false panel.Visible = true shadow.Visible = true end) bindHover(openButton, Color3.fromRGB(103, 92, 245), Color3.fromRGB(124, 114, 255)) keybindButton.MouseButton1Click:Connect(function() listeningForKey = true keybindButton.Text = "PRESS KEY..." end) UserInputService.InputBegan:Connect(function(input, gameProcessed) if input.UserInputType ~= Enum.UserInputType.Keyboard then return end if listeningForKey then if input.KeyCode == Enum.KeyCode.Escape then listeningForKey = false keybindButton.Text = "KEY: " .. toggleKey.Name return end if input.KeyCode ~= Enum.KeyCode.Unknown then toggleKey = input.KeyCode listeningForKey = false keybindButton.Text = "KEY: " .. toggleKey.Name end return end if gameProcessed or UserInputService:GetFocusedTextBox() then return end if input.KeyCode == toggleKey then toggleFlight() end end) toggleRequested.Event:Connect(function(requestedState) if typeof(requestedState) == "boolean" then setFlying(requestedState) else toggleFlight() end end) --// Respawn and cleanup if player.Character then task.spawn(setCharacter, player.Character) end player.CharacterAdded:Connect(setCharacter) screenGui.Destroying:Connect(function() if destroyed then return end destroyed = true disableFlight() end) updateUI()