local Players = game:GetService("Players") local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local camera = workspace.CurrentCamera local FLY_SPEED = 70 local BOOST_POWER = 180 local BOOST_UPWARD = 8 local BOOST_TURN_SPEED = 14 local VEHICLE_DETECT_DISTANCE = 30 local flying = false local noclip = false local vehicleSeat = nil local vehicleModel = nil local bodyVelocity = nil local bodyGyro = nil local oldCameraType = nil local oldCameraSubject = nil local savedCollision = {} local savedPlayerCollision = {} local noclipCharacters = {} local keys = { W = false, A = false, S = false, D = false } local function getHumanoid() local character = player.Character if not character then return nil end return character:FindFirstChildOfClass("Humanoid") end local function getPlayerSeat() local humanoid = getHumanoid() if not humanoid then return nil end local seatPart = humanoid.SeatPart if seatPart and (seatPart:IsA("VehicleSeat") or seatPart:IsA("Seat")) then return seatPart end return nil end local function getNearestVehicleSeat() local character = player.Character if not character then return nil end local playerRoot = character:FindFirstChild("HumanoidRootPart") if not playerRoot then return nil end local closestSeat = nil local closestDistance = VEHICLE_DETECT_DISTANCE for _, object in ipairs(workspace:GetDescendants()) do if object:IsA("VehicleSeat") then local distance = (object.Position - playerRoot.Position).Magnitude if distance <= closestDistance then closestDistance = distance closestSeat = object end end end return closestSeat end local function getVehicleSeat() local currentSeat = getPlayerSeat() if currentSeat then if currentSeat:IsA("VehicleSeat") then return currentSeat end local model = currentSeat:FindFirstAncestorOfClass("Model") if model then for _, object in ipairs(model:GetDescendants()) do if object:IsA("VehicleSeat") then return object end end end end return getNearestVehicleSeat() end local function getVehicleModel(seat) if not seat then return nil end return seat:FindFirstAncestorOfClass("Model") end local function getVehicleRoot(seat) if not seat then return nil end local model = seat:FindFirstAncestorOfClass("Model") if model and model.PrimaryPart then return model.PrimaryPart end return seat end local function isPlayerDriver(seat) if not seat then return false end local humanoid = getHumanoid() if not humanoid then return false end return seat:IsA("VehicleSeat") and seat.Occupant == humanoid end local function isPlayerStillInVehicle() local humanoid = getHumanoid() if not humanoid then return false end local seatPart = humanoid.SeatPart if not seatPart then return false end return vehicleModel and seatPart:IsDescendantOf(vehicleModel) or false end local function savePlayerCollision(character) if not character or savedPlayerCollision[character] then return end local collisionData = {} for _, object in ipairs(character:GetDescendants()) do if object:IsA("BasePart") then collisionData[object] = object.CanCollide end end savedPlayerCollision[character] = collisionData end local function setPlayerCollision(character, enabled) if not character then return end for _, object in ipairs(character:GetDescendants()) do if object:IsA("BasePart") then object.CanCollide = enabled end end end local function restorePlayerCollision(character) if not character then return end local saved = savedPlayerCollision[character] if not saved then return end for part, originalValue in pairs(saved) do if part and part.Parent then part.CanCollide = originalValue end end savedPlayerCollision[character] = nil noclipCharacters[character] = nil end local function getVehicleOccupants() local occupants = {} if not vehicleModel then return occupants end for _, object in ipairs(vehicleModel:GetDescendants()) do if object:IsA("Seat") or object:IsA("VehicleSeat") then local humanoid = object.Occupant if humanoid then local character = humanoid.Parent if character then occupants[character] = true end end end end return occupants end local function updateOccupantNoclip() if not noclip or not vehicleModel then return end local occupants = getVehicleOccupants() for character in pairs(occupants) do savePlayerCollision(character) setPlayerCollision(character, false) noclipCharacters[character] = true end for character in pairs(noclipCharacters) do if not occupants[character] then restorePlayerCollision(character) end end end local function saveVehicleCollision(model) savedCollision = {} if not model then return end for _, object in ipairs(model:GetDescendants()) do if object:IsA("BasePart") then savedCollision[object] = { CanCollide = object.CanCollide } end end end local function restoreVehicleCollision() for part, data in pairs(savedCollision) do if part and part.Parent then part.CanCollide = data.CanCollide end end savedCollision = {} end local function setNoclipCollision(enabled) if not vehicleModel then return end for _, object in ipairs(vehicleModel:GetDescendants()) do if object:IsA("BasePart") then object.CanCollide = not enabled end end if enabled then updateOccupantNoclip() else for character in pairs(noclipCharacters) do restorePlayerCollision(character) end noclipCharacters = {} end end local function enableNoclip() if not flying or not vehicleModel then return end noclip = true setNoclipCollision(true) end local function disableNoclip() noclip = false restoreVehicleCollision() for character in pairs(noclipCharacters) do restorePlayerCollision(character) end noclipCharacters = {} end local function restoreCamera() if oldCameraType then camera.CameraType = oldCameraType end if oldCameraSubject then camera.CameraSubject = oldCameraSubject end oldCameraType = nil oldCameraSubject = nil end local function stopFlying() flying = false disableNoclip() if bodyVelocity then bodyVelocity:Destroy() bodyVelocity = nil end if bodyGyro then bodyGyro:Destroy() bodyGyro = nil end restoreCamera() end local function startFlying() local seat = getVehicleSeat() if not seat then warn("V-Fly: No vehicle found.") return end local model = getVehicleModel(seat) if not model then warn("V-Fly: Vehicle model not found.") return end local root = getVehicleRoot(seat) if not root then return end vehicleSeat = seat vehicleModel = model noclip = false saveVehicleCollision(model) savePlayerCollision(player.Character) flying = true oldCameraType = camera.CameraType oldCameraSubject = camera.CameraSubject camera.CameraType = Enum.CameraType.Custom local character = player.Character if character then local humanoid = character:FindFirstChildOfClass("Humanoid") if humanoid then camera.CameraSubject = humanoid end end bodyVelocity = Instance.new("BodyVelocity") bodyVelocity.Name = "VFlyVelocity" bodyVelocity.MaxForce = Vector3.new(math.huge, math.huge, math.huge) bodyVelocity.P = 10000 bodyVelocity.Velocity = Vector3.zero bodyVelocity.Parent = root bodyGyro = Instance.new("BodyGyro") bodyGyro.Name = "VFlyGyro" bodyGyro.MaxTorque = Vector3.new(math.huge, math.huge, math.huge) bodyGyro.P = 10000 bodyGyro.D = 500 bodyGyro.CFrame = root.CFrame bodyGyro.Parent = root end local function toggleNoclip() if not flying then return end if noclip then disableNoclip() else enableNoclip() end end local function boostVehicle() local seat = vehicleSeat or getVehicleSeat() if not seat then warn("Boost: No vehicle found nearby.") return end local root = getVehicleRoot(seat) if not root then return end local model = getVehicleModel(seat) if model then vehicleSeat = seat vehicleModel = model if next(savedCollision) == nil then saveVehicleCollision(model) end end local assemblyRoot = root.AssemblyRootPart or root local driving = isPlayerDriver(seat) local cameraLook = camera.CFrame.LookVector local horizontalLook = Vector3.new(cameraLook.X, 0, cameraLook.Z) if horizontalLook.Magnitude < 0.01 then horizontalLook = assemblyRoot.CFrame.LookVector horizontalLook = Vector3.new(horizontalLook.X, 0, horizontalLook.Z) end if horizontalLook.Magnitude < 0.01 then return end horizontalLook = horizontalLook.Unit if not driving then local currentLook = assemblyRoot.CFrame.LookVector local currentHorizontal = Vector3.new(currentLook.X, 0, currentLook.Z) if currentHorizontal.Magnitude > 0.01 then currentHorizontal = currentHorizontal.Unit local currentAngle = math.atan2(currentHorizontal.X, currentHorizontal.Z) local targetAngle = math.atan2(horizontalLook.X, horizontalLook.Z) local angleDifference = math.atan2( math.sin(targetAngle - currentAngle), math.cos(targetAngle - currentAngle) ) local turnAmount = math.clamp( angleDifference, -BOOST_TURN_SPEED * 0.1, BOOST_TURN_SPEED * 0.1 ) local newAngle = currentAngle + turnAmount local newDirection = Vector3.new( math.sin(newAngle), 0, math.cos(newAngle) ) assemblyRoot.CFrame = CFrame.lookAt( assemblyRoot.Position, assemblyRoot.Position + newDirection ) end end local impulse = ( horizontalLook * BOOST_POWER + Vector3.new(0, BOOST_UPWARD, 0) ) * assemblyRoot.AssemblyMass assemblyRoot:ApplyImpulse(impulse) if flying and noclip then setNoclipCollision(true) end end UserInputService.InputBegan:Connect(function(input, gameProcessed) if gameProcessed then return end local key = input.KeyCode if key == Enum.KeyCode.F then if flying then stopFlying() vehicleSeat = nil vehicleModel = nil else startFlying() end return end if key == Enum.KeyCode.B then boostVehicle() return end if key == Enum.KeyCode.N then toggleNoclip() return end if key == Enum.KeyCode.W then keys.W = true elseif key == Enum.KeyCode.A then keys.A = true elseif key == Enum.KeyCode.S then keys.S = true elseif key == Enum.KeyCode.D then keys.D = true end end) UserInputService.InputEnded:Connect(function(input) local key = input.KeyCode if key == Enum.KeyCode.W then keys.W = false elseif key == Enum.KeyCode.A then keys.A = false elseif key == Enum.KeyCode.S then keys.S = false elseif key == Enum.KeyCode.D then keys.D = false end end) RunService.RenderStepped:Connect(function() if flying and not isPlayerStillInVehicle() then stopFlying() vehicleSeat = nil vehicleModel = nil return end if not flying then return end if not vehicleSeat or not vehicleSeat.Parent then stopFlying() vehicleSeat = nil vehicleModel = nil return end local root = getVehicleRoot(vehicleSeat) if not root then stopFlying() vehicleSeat = nil vehicleModel = nil return end if not bodyVelocity or not bodyGyro then stopFlying() vehicleSeat = nil vehicleModel = nil return end if noclip then setNoclipCollision(true) end local cameraCF = camera.CFrame local forward = cameraCF.LookVector local right = cameraCF.RightVector local movement = Vector3.zero if keys.W then movement += forward end if keys.S then movement -= forward end if keys.A then movement -= right end if keys.D then movement += right end if movement.Magnitude > 0 then bodyVelocity.Velocity = movement.Unit * FLY_SPEED else bodyVelocity.Velocity = Vector3.zero end local lookDirection = cameraCF.LookVector local horizontalLook = Vector3.new(lookDirection.X, 0, lookDirection.Z) if horizontalLook.Magnitude > 0.01 then horizontalLook = horizontalLook.Unit bodyGyro.CFrame = CFrame.lookAt(root.Position, root.Position + horizontalLook) end end) local function setupSeatMonitor(character) local humanoid = character:WaitForChild("Humanoid") humanoid:GetPropertyChangedSignal("SeatPart"):Connect(function() if not humanoid.SeatPart then if flying then stopFlying() end vehicleSeat = nil vehicleModel = nil return end if noclip and vehicleModel and humanoid.SeatPart:IsDescendantOf(vehicleModel) then savePlayerCollision(character) setPlayerCollision(character, false) noclipCharacters[character] = true end end) end player.CharacterAdded:Connect(function(character) if flying then stopFlying() end noclip = false for oldCharacter in pairs(savedPlayerCollision) do restorePlayerCollision(oldCharacter) end savedPlayerCollision = {} noclipCharacters = {} restoreVehicleCollision() vehicleSeat = nil vehicleModel = nil task.spawn(function() setupSeatMonitor(character) end) end) if player.Character then task.spawn(function() setupSeatMonitor(player.Character) end) end