local Players = game:GetService("Players") local UIS = game:GetService("UserInputService") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local flying = false local speed = 65 -- movement state local move = { forward = false, back = false, left = false, right = false, up = false, down = false } -- references that will be (re)created per character local hrp, hum local bv, bg local function cleanupBodyMovers() if bv and bv.Parent then bv:Destroy() end if bg and bg.Parent then bg:Destroy() end bv = nil bg = nil end local function createBodyMovers(parent) cleanupBodyMovers() bv = Instance.new("BodyVelocity") bv.MaxForce = Vector3.new(0,0,0) bv.Velocity = Vector3.new(0,0,0) bv.P = 1250 bv.Parent = parent bg = Instance.new("BodyGyro") bg.MaxTorque = Vector3.new(0,0,0) bg.P = 9000 bg.CFrame = workspace.CurrentCamera.CFrame bg.Parent = parent end local function onCharacterAdded(character) -- wait for required parts hrp = character:FindFirstChild("HumanoidRootPart") or character:WaitForChild("HumanoidRootPart", 5) hum = character:FindFirstChildOfClass("Humanoid") or character:WaitForChild("Humanoid", 5) if not hrp or not hum then warn("Flight script: couldn't find HumanoidRootPart or Humanoid on character.") return end createBodyMovers(hrp) flying = false hum.PlatformStand = false print("Flight script: character ready.") end -- attach to current character or wait if player.Character and player.Character.Parent then onCharacterAdded(player.Character) end player.CharacterAdded:Connect(onCharacterAdded) -- input handling UIS.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end local kc = input.KeyCode if kc == Enum.KeyCode.E then if not hrp or not hum then warn("Flight script: character not ready yet.") return end flying = not flying if flying then hum.PlatformStand = true if bv then bv.MaxForce = Vector3.new(5e5,5e5,5e5) end if bg then bg.MaxTorque = Vector3.new(5e5,5e5,5e5) end print("Flight enabled") else hum.PlatformStand = false if bv then bv.MaxForce = Vector3.new(0,0,0); bv.Velocity = Vector3.new(0,0,0) end if bg then bg.MaxTorque = Vector3.new(0,0,0) end print("Flight disabled") end end -- movement keys if kc == Enum.KeyCode.W then move.forward = true end if kc == Enum.KeyCode.S then move.back = true end if kc == Enum.KeyCode.A then move.left = true end if kc == Enum.KeyCode.D then move.right = true end if kc == Enum.KeyCode.Space then move.up = true end if kc == Enum.KeyCode.LeftControl then move.down = true end end) UIS.InputEnded:Connect(function(input) local kc = input.KeyCode if kc == Enum.KeyCode.W then move.forward = false end if kc == Enum.KeyCode.S then move.back = false end if kc == Enum.KeyCode.A then move.left = false end if kc == Enum.KeyCode.D then move.right = false end if kc == Enum.KeyCode.Space then move.up = false end if kc == Enum.KeyCode.LeftControl then move.down = false end end) -- main update loop RunService.RenderStepped:Connect(function() if not flying then return end if not hrp or not bv or not bg then return end local cam = workspace.CurrentCamera local dir = Vector3.new(0,0,0) if move.forward then dir = dir + cam.CFrame.LookVector end if move.back then dir = dir - cam.CFrame.LookVector end if move.left then dir = dir - cam.CFrame.RightVector end if move.right then dir = dir + cam.CFrame.RightVector end if move.up then dir = dir + Vector3.new(0,1,0) end if move.down then dir = dir - Vector3.new(0,1,0) end if dir.Magnitude > 0 then dir = dir.Unit * speed else dir = Vector3.new(0,0,0) end -- apply velocity and align orientation with camera bv.Velocity = dir bg.CFrame = cam.CFrame end) -- cleanup on teleport / leave player.OnTeleport:Connect(function(state) cleanupBodyMovers() end)