--by Rylvns
--edited 5/9/26
--!optimize 2
--!native
local FLY_KEY = Enum.KeyCode.LeftShift;
local FLY_UP_KEY = Enum.KeyCode.Space;
local FLY_DOWN_KEY = Enum.KeyCode.LeftControl;
local FLY_SPEED = 50;
local MAX_FLY_SPEED = 400;
local SPEED_INCREMENT = 1;
local COLLISION_RADIUS = 60;
local UserInputService = game:GetService("UserInputService");
local RunService = game:GetService("RunService");
local Players = game:GetService("Players");
local Player = Players.LocalPlayer;
local Character = Player.Character or Player.CharacterAdded:Wait();
local Humanoid = Character:WaitForChild("Humanoid");
local RootPart = Character:WaitForChild("HumanoidRootPart");
local Flying = false;
local FlySpeed = FLY_SPEED;
local OriginalGravity = workspace.Gravity;
local ChangedParts = {};
local OverlapParams = OverlapParams.new();
OverlapParams.FilterType = Enum.RaycastFilterType.Exclude;
OverlapParams.FilterDescendantsInstances = {Character};
local function RestoreAllCollisions()
for Part in pairs(ChangedParts) do
if not Part then continue end;
if not Part.Parent then continue end;
Part.CanCollide = true;
end;
ChangedParts = {};
end;
local function StopFlying()
Flying = false;
FlySpeed = FLY_SPEED;
if RootPart and RootPart.Parent then
RootPart.AssemblyLinearVelocity = Vector3.zero;
end;
workspace.Gravity = OriginalGravity;
RestoreAllCollisions();
end;
Player.CharacterAdded:Connect(function(NewCharacter)
if Flying then StopFlying() end;
Character = NewCharacter;
Humanoid = Character:WaitForChild("Humanoid");
RootPart = Character:WaitForChild("HumanoidRootPart");
OverlapParams.FilterDescendantsInstances = {Character};
end);
RunService.RenderStepped:Connect(function()
if not Flying or not RootPart or not RootPart.Parent then return end;
local MoveDirection = Vector3.zero;
local CameraCFrame = workspace.CurrentCamera.CFrame;
MoveDirection += UserInputService:IsKeyDown(Enum.KeyCode.W) and CameraCFrame.LookVector or Vector3.zero;
MoveDirection -= UserInputService:IsKeyDown(Enum.KeyCode.S) and CameraCFrame.LookVector or Vector3.zero;
MoveDirection -= UserInputService:IsKeyDown(Enum.KeyCode.A) and CameraCFrame.RightVector or Vector3.zero;
MoveDirection += UserInputService:IsKeyDown(Enum.KeyCode.D) and CameraCFrame.RightVector or Vector3.zero;
MoveDirection += UserInputService:IsKeyDown(FLY_UP_KEY) and Vector3.yAxis or Vector3.zero;
MoveDirection -= UserInputService:IsKeyDown(FLY_DOWN_KEY) and Vector3.yAxis or Vector3.zero;
if MoveDirection.Magnitude > 0 then
FlySpeed = math.min(FlySpeed+SPEED_INCREMENT, MAX_FLY_SPEED);
MoveDirection = MoveDirection.Unit*FlySpeed;
RootPart.AssemblyLinearVelocity = MoveDirection*0.5;
else
RootPart.AssemblyLinearVelocity = Vector3.zero;
end;
local NearbySet = {};
for _, Part in ipairs(workspace:GetPartBoundsInRadius(RootPart.Position, COLLISION_RADIUS, OverlapParams)) do
NearbySet[Part] = true;
if not Part.CanCollide then continue end;
if ChangedParts[Part] then continue end;
ChangedParts[Part] = true;
Part.CanCollide = false;
end;
for Part in pairs(ChangedParts) do
if NearbySet[Part] then continue end;
if Part and Part.Parent then
Part.CanCollide = true;
end;
ChangedParts[Part] = nil;
end;
end);
UserInputService.InputBegan:Connect(function(InputObject, GameProcessedEvent)
if GameProcessedEvent then return end;
if InputObject.KeyCode ~= FLY_KEY then return end;
Flying = not Flying;
if Flying then
workspace.Gravity = 0;
else
StopFlying();
end;
end);
Comments