-- Wall Glide (pushes the whole avatar's parts inside the wall slightly) -- Place in StarterPlayer > StarterPlayerScripts local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UIS = game:GetService("UserInputService") local player = Players.LocalPlayer -- safe char local function getChar() local char = player.Character or player.CharacterAdded:Wait() local hum = char:WaitForChild("Humanoid") local hrp = char:WaitForChild("HumanoidRootPart") return char, hum, hrp end local char, humanoid, hrp = getChar() -- GUI local gui = Instance.new("ScreenGui") gui.Name = "WallGlideGui" gui.ResetOnSpawn = false gui.IgnoreGuiInset = true gui.Parent = player:WaitForChild("PlayerGui") local button = Instance.new("TextButton") button.Name = "GlideButton" button.Size = UDim2.fromOffset(140, 40) button.Position = UDim2.new(0, 20, 1, -60) button.AnchorPoint = Vector2.new(0, 1) button.TextScaled = true button.Text = "Glide: OFF" button.BackgroundColor3 = Color3.fromRGB(40, 40, 40) button.TextColor3 = Color3.fromRGB(255, 255, 255) button.Parent = gui -- State local glideEnabled = false local cachedWallNormal = nil button.MouseButton1Click:Connect(function() glideEnabled = not glideEnabled button.Text = glideEnabled and "Glide: ON" or "Glide: OFF" end) -- raycast settings local rayParams = RaycastParams.new() rayParams.FilterType = Enum.RaycastFilterType.Blacklist rayParams.FilterDescendantsInstances = {char} -- tunables local RAY_LEN = 2.5 local DEPTH_INTO_WALL = 0.2 local MAX_FALL = -10 -- push ALL avatar parts into wall local function embedAvatar(normal) for _, part in ipairs(char:GetDescendants()) do if part:IsA("BasePart") and part.CanCollide then part.CFrame = part.CFrame * CFrame.new(normal * -DEPTH_INTO_WALL) end end end RunService.Heartbeat:Connect(function() if not char or not char.Parent or not hrp or not hrp.Parent then char, humanoid, hrp = getChar() rayParams.FilterDescendantsInstances = {char} end if not glideEnabled then cachedWallNormal = nil return end if humanoid:GetState() ~= Enum.HumanoidStateType.Freefall then cachedWallNormal = nil return end -- check in front of avatar local result = workspace:Raycast(hrp.Position, hrp.CFrame.LookVector * RAY_LEN, rayParams) if result and result.Instance and result.Instance.CanCollide then cachedWallNormal = result.Normal -- actually push whole avatar in embedAvatar(result.Normal) -- limit fall speed local v = hrp.Velocity local y = (v.Y < MAX_FALL) and MAX_FALL or v.Y hrp.Velocity = Vector3.new(v.X, y, v.Z) else cachedWallNormal = nil end end) -- optional wall jump UIS.JumpRequest:Connect(function() if glideEnabled and cachedWallNormal then local away = cachedWallNormal * 28 hrp.Velocity = hrp.Velocity + away + Vector3.new(0, 28, 0) end end) -- respawn support player.CharacterAdded:Connect(function(newChar) char = newChar humanoid = char:WaitForChild("Humanoid") hrp = char:WaitForChild("HumanoidRootPart") rayParams.FilterDescendantsInstances = {char} end)