-- Educational UI Concept for Reset-Safe State Persistence local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local LocalPlayer = Players.LocalPlayer -- Create a ScreenGui local ScreenGui = Instance.new("ScreenGui") ScreenGui.Name = "PersistentFlightGui" -- CRUCIAL: Stops Roblox from deleting this UI when you die ScreenGui.ResetOnSpawn = false ScreenGui.Parent = LocalPlayer:WaitForChild("PlayerGui") -- Main Container Frame local MainFrame = Instance.new("Frame") MainFrame.Size = UDim2.new(0, 250, 0, 200) MainFrame.Position = UDim2.new(0.4, 0, 0.4, 0) MainFrame.BackgroundColor3 = Color3.fromRGB(40, 40, 40) MainFrame.Active = true MainFrame.Parent = ScreenGui -- ========================================== -- MOBILE FINGER & MOUSE DRAGGING ENGINE -- ========================================== local dragging = false local dragInput, dragStart, startPos local function update(input) local delta = input.Position - dragStart MainFrame.Position = UDim2.new( startPos.X.Scale, startPos.X.Offset + delta.X, startPos.Y.Scale, startPos.Y.Offset + delta.Y ) end MainFrame.InputBegan:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.Touch then dragging = true dragStart = input.Position startPos = MainFrame.Position input.Changed:Connect(function() if input.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) MainFrame.InputChanged:Connect(function(input) if input.UserInputType == Enum.UserInputType.MouseMovement or input.UserInputType == Enum.UserInputType.Touch then dragInput = input end end) UserInputService.InputChanged:Connect(function(input) if input == dragInput and dragging then update(input) end end) -- ========================================== -- Minimize / Maximize Toggle Button local MinBtn = Instance.new("TextButton") MinBtn.Size = UDim2.new(0, 30, 0, 25) MinBtn.Position = UDim2.new(1, -35, 0, 5) MinBtn.Text = "-" MinBtn.BackgroundColor3 = Color3.fromRGB(80, 30, 30) MinBtn.TextColor3 = Color3.fromRGB(255, 255, 255) MinBtn.Parent = MainFrame -- Flight Toggle Button local FlightButton = Instance.new("TextButton") FlightButton.Size = UDim2.new(0, 195, 0, 30) FlightButton.Position = UDim2.new(0, 10, 0, 5) FlightButton.Text = "FLY (ENABLE)" FlightButton.BackgroundColor3 = Color3.fromRGB(0, 100, 180) FlightButton.TextColor3 = Color3.fromRGB(255, 255, 255) FlightButton.Parent = MainFrame -- Directional Controls Frame local ControlFrame = Instance.new("Frame") ControlFrame.Size = UDim2.new(0, 230, 0, 150) ControlFrame.Position = UDim2.new(0, 10, 0, 45) ControlFrame.BackgroundTransparency = 1 ControlFrame.Visible = false ControlFrame.Parent = MainFrame -- Helper function to build uniform directional buttons local function createButton(name, pos, text) local btn = Instance.new("TextButton") btn.Name = name btn.Size = UDim2.new(0, 50, 0, 40) btn.Position = pos btn.Text = text btn.BackgroundColor3 = Color3.fromRGB(70, 70, 70) btn.TextColor3 = Color3.fromRGB(255, 255, 255) btn.Parent = ControlFrame return btn end -- Layout direction elements local UpBtn = createButton("UpBtn", UDim2.new(0, 90, 0, 5), "Up") local LeftBtn = createButton("LeftBtn", UDim2.new(0, 30, 0, 50), "Left") local RightBtn = createButton("RightBtn", UDim2.new(0, 150, 0, 50), "Right") local DownBtn = createButton("DownBtn", UDim2.new(0, 90, 0, 95), "Down") -- Global States & Physics Trackers local flightActive = false local isMinimized = false local movementVelocity = nil local rotationGyro = nil local MOVEMENT_SPEED = 2 -- References to the active character (changes when you die) local currentCharacter = nil local currentHumanoid = nil local currentRootPart = nil -- Core function to enable or disable physics setups local function updatePhysicsState() if not currentCharacter or not currentHumanoid or not currentRootPart then return end -- Clean up any lingering objects from a previous character life if movementVelocity then movementVelocity:Destroy() movementVelocity = nil end if rotationGyro then rotationGyro:Destroy() rotationGyro = nil end if flightActive then FlightButton.Text = "DISABLE" FlightButton.BackgroundColor3 = Color3.fromRGB(180, 50, 50) if not isMinimized then ControlFrame.Visible = true end currentHumanoid.WalkSpeed = MOVEMENT_SPEED -- Orient character flat immediately local flatTargetCFrame = currentRootPart.CFrame * CFrame.Angles(math.rad(90), 0, 0) currentRootPart.CFrame = flatTargetCFrame -- Apply locking forces rotationGyro = Instance.new("BodyGyro") rotationGyro.MaxTorque = Vector3.new(4e5, 4e5, 4e5) rotationGyro.D = 100 rotationGyro.P = 10000 rotationGyro.CFrame = flatTargetCFrame rotationGyro.Parent = currentRootPart movementVelocity = Instance.new("BodyVelocity") movementVelocity.MaxForce = Vector3.new(1e6, 1e6, 1e6) movementVelocity.Velocity = Vector3.new(0, 0, 0) movementVelocity.Parent = currentRootPart else FlightButton.Text = "FLY (ENABLE)" FlightButton.BackgroundColor3 = Color3.fromRGB(0, 100, 180) ControlFrame.Visible = false currentHumanoid.WalkSpeed = 16 currentRootPart.CFrame = CFrame.new(currentRootPart.Position) end end -- Hook up Character Re-binding loops (Fires every time you respawn) local function onCharacterAdded(newCharacter) currentCharacter = newCharacter currentHumanoid = newCharacter:WaitForChild("Humanoid") currentRootPart = newCharacter:WaitForChild("HumanoidRootPart") -- Instantly enforce the flight/flat physics if it was left ON when you died updatePhysicsState() end -- Connect to existing character, and listen for future spawns if LocalPlayer.Character then onCharacterAdded(LocalPlayer.Character) end LocalPlayer.CharacterAdded:Connect(onCharacterAdded) -- Minimize/Maximize UI Logic MinBtn.MouseButton1Click:Connect(function() isMinimized = not isMinimized if isMinimized then MainFrame.Size = UDim2.new(0, 250, 0, 40) ControlFrame.Visible = false MinBtn.Text = "+" else MainFrame.Size = UDim2.new(0, 250, 0, 200) if flightActive then ControlFrame.Visible = true end MinBtn.Text = "-" end end) -- Manual UI Toggle Button Press Listener FlightButton.MouseButton1Click:Connect(function() flightActive = not flightActive updatePhysicsState() end) -- Velocity Controller Direction mapping local function applyPhysicsVelocity(directionVector) if not flightActive or not movementVelocity then return end movementVelocity.Velocity = directionVector * MOVEMENT_SPEED end -- Button click/tap bindings UpBtn.MouseButton1Down:Connect(function() applyPhysicsVelocity(Vector3.new(0, 1, 0)) end) UpBtn.MouseButton1Up:Connect(function() applyPhysicsVelocity(Vector3.new(0, 0, 0)) end) DownBtn.MouseButton1Down:Connect(function() applyPhysicsVelocity(Vector3.new(0, -1, 0)) end) DownBtn.MouseButton1Up:Connect(function() applyPhysicsVelocity(Vector3.new(0, 0, 0)) end) LeftBtn.MouseButton1Down:Connect(function() applyPhysicsVelocity(Vector3.new(-1, 0, 0)) end) LeftBtn.MouseButton1Up:Connect(function() applyPhysicsVelocity(Vector3.new(0, 0, 0)) end) RightBtn.MouseButton1Down:Connect(function() applyPhysicsVelocity(Vector3.new(1, 0, 0)) end) RightBtn.MouseButton1Up:Connect(function() applyPhysicsVelocity(Vector3.new(0, 0, 0)) end)