local Players = game:GetService("Players") local RunService = game:GetService("RunService") local TweenService = game:GetService("TweenService") local UserInputService = game:GetService("UserInputService") local player = Players.LocalPlayer local camera = workspace.CurrentCamera ------------------------------------------------ -- SETTINGS ------------------------------------------------ local speed = 70 ------------------------------------------------ -- CHARACTER ------------------------------------------------ local character = player.Character or player.CharacterAdded:Wait() local humanoid = character:WaitForChild("Humanoid") local root = character:WaitForChild("HumanoidRootPart") local animator = humanoid:WaitForChild("Animator") ------------------------------------------------ -- STATE ------------------------------------------------ local flying = false local upDown = 0 local bodyVelocity local bodyGyro local idleTrack, moveTrack ------------------------------------------------ -- GUI (NO JOYSTICK CHANGES - IMPORTANT) ------------------------------------------------ local gui = Instance.new("ScreenGui") gui.Name = "FlyGui" gui.ResetOnSpawn = false gui.Parent = player:WaitForChild("PlayerGui") local button = Instance.new("TextButton") button.Size = UDim2.new(0, 150, 0, 55) button.Position = UDim2.new(0, 20, 0.45, 0) button.BackgroundColor3 = Color3.fromRGB(120,120,120) button.TextColor3 = Color3.fromRGB(255,255,255) button.Text = "FLY" button.TextSize = 22 button.Parent = gui Instance.new("UICorner", button).CornerRadius = UDim.new(0,10) ------------------------------------------------ -- SPEED + UP/DOWN INPUT ------------------------------------------------ UserInputService.InputBegan:Connect(function(input, gp) if gp then return end if input.KeyCode == Enum.KeyCode.Equals then speed += 10 elseif input.KeyCode == Enum.KeyCode.Minus then speed = math.max(10, speed - 10) end -- UP / DOWN (PC ONLY) if input.KeyCode == Enum.KeyCode.Space then upDown = 1 elseif input.KeyCode == Enum.KeyCode.LeftShift then upDown = -1 end end) UserInputService.InputEnded:Connect(function(input) if input.KeyCode == Enum.KeyCode.Space or input.KeyCode == Enum.KeyCode.LeftShift then upDown = 0 end end) ------------------------------------------------ -- ANIMATIONS ------------------------------------------------ local function loadAnimations() local idleAnim = Instance.new("Animation") idleAnim.AnimationId = "rbxassetid://247742499" local moveAnim = Instance.new("Animation") moveAnim.AnimationId = "rbxassetid://119783214" idleTrack = animator:LoadAnimation(idleAnim) moveTrack = animator:LoadAnimation(moveAnim) end loadAnimations() ------------------------------------------------ -- FOV ------------------------------------------------ local function setFOV(val) TweenService:Create(camera, TweenInfo.new(0.25), { FieldOfView = val }):Play() end ------------------------------------------------ -- FLY PHYSICS ------------------------------------------------ local function startFly() bodyVelocity = Instance.new("BodyVelocity") bodyVelocity.MaxForce = Vector3.new(1e9,1e9,1e9) bodyVelocity.Parent = root bodyGyro = Instance.new("BodyGyro") bodyGyro.MaxTorque = Vector3.new(1e9,1e9,1e9) bodyGyro.CFrame = root.CFrame bodyGyro.Parent = root end local function stopFly() if bodyVelocity then bodyVelocity:Destroy() end if bodyGyro then bodyGyro:Destroy() end end ------------------------------------------------ -- MAIN LOOP (🔥 FIXED JOYSTICK + NO INVERSION + UP/DOWN FIX) ------------------------------------------------ RunService.RenderStepped:Connect(function() if not flying then return end local moveDir = humanoid.MoveDirection -- 🔥 FIX: ONLY USE FLAT CAMERA (prevents inversion completely) local camCF = camera.CFrame local forward = Vector3.new(camCF.LookVector.X, 0, camCF.LookVector.Z) if forward.Magnitude > 0 then forward = forward.Unit end local right = Vector3.new(camCF.RightVector.X, 0, camCF.RightVector.Z) if right.Magnitude > 0 then right = right.Unit end -- ✔ joystick stays PERFECT (no touching Roblox controls) local direction = (right * moveDir.X) + (forward * moveDir.Z) + Vector3.new(0, upDown, 0) -- smooth fly local finalVelocity = direction * speed if bodyVelocity then bodyVelocity.Velocity = finalVelocity end if bodyGyro then bodyGyro.CFrame = camera.CFrame end -- animations local moving = moveDir.Magnitude > 0 or upDown ~= 0 if moving then if idleTrack and idleTrack.IsPlaying then idleTrack:Stop() end if moveTrack and not moveTrack.IsPlaying then moveTrack:Play() end setFOV(90) else if moveTrack and moveTrack.IsPlaying then moveTrack:Stop() end if idleTrack and not idleTrack.IsPlaying then idleTrack:Play() end setFOV(70) end end) ------------------------------------------------ -- TOGGLE ------------------------------------------------ button.MouseButton1Click:Connect(function() flying = not flying if flying then startFly() else stopFly() if idleTrack then idleTrack:Stop() end if moveTrack then moveTrack:Stop() end setFOV(70) end end) ------------------------------------------------ -- RESPAWN FIX ------------------------------------------------ player.CharacterAdded:Connect(function(char) character = char humanoid = character:WaitForChild("Humanoid") root = character:WaitForChild("HumanoidRootPart") animator = character:WaitForChild("Animator") flying = false upDown = 0 stopFly() loadAnimations() setFOV(70) end)