I took your script and made a cleaned up version of it, just to fix a few things and make it more reliable overall.
The idea you had is using UserInputService to detect the key press and then applying AngularVelocity for a spin effect works well. I just noticed a few small issues that could cause problems in actual gameplay.
For example the script assumes the character, Humanoid and HumanoidRootPart are always there, but in practice those can be nil sometimes (like right after respawn) which could cause errors. I also adjusted the flow a bit so everything is checked properly before running anything.
Another thing is the cleanup your version does destroy the attachment and angular velocity after a delay which is good, but I made it a bit safer and more consistent so it won’t break if something interrupts the timing
Overall I didn’t change the idea at all, just fixed up the structure and made it more stable and easier to build on later if you ever want to add cooldowns or extra features, So here’s the script I upgraded for you, It should match how you want the script to work. I made it because I have so much free time today so I hope it’s in your preferences:
local Players = game:GetService("Players")
local GuiService = game:GetService("GuiService")
local UserInputService = game:GetService("UserInputService")
local TweenService = game:GetService("TweenService")
local plr = Players.LocalPlayer
local gui = plr:WaitForChild("PlayerGui")
local busy = false
local input = nil
local btn
local info = TweenInfo.new(0.03, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
repeat
task.wait(0.5)
until GuiService.TouchControlsEnabled and UserInputService.TouchEnabled
local function wallhop()
if busy then return end
local char = plr.Character
if not char then return end
local hum = char:FindFirstChildWhichIsA("Humanoid")
local root = char:FindFirstChild("HumanoidRootPart")
if not hum or not root then return end
busy = true
local oldRot = hum.AutoRotate
task.delay(0.01, function()
if hum
and hum.FloorMaterial ~= Enum.Material.Air
and hum.FloorMaterial ~= Enum.Material.Water then
pcall(function()
hum:ChangeState(Enum.HumanoidStateType.Jumping)
end)
end
end)
if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter then
hum.AutoRotate = false
end
TweenService:Create(root, info, {
CFrame = root.CFrame * CFrame.Angles(0, math.pi, 0)
}):Play()
task.wait(0.12)
TweenService:Create(root, info, {
CFrame = root.CFrame * CFrame.Angles(0, -math.pi, 0)
}):Play()
task.wait(0.05)
hum.AutoRotate = oldRot
busy = false
end
local function makeButton()
if btn then
btn:Destroy()
end
local screen = Instance.new("ScreenGui")
screen.Name = "WallhopGui"
screen.ResetOnSpawn = false
screen.Parent = gui
btn = Instance.new("TextButton")
btn.Parent = screen
btn.Name = "btn"
btn.AnchorPoint = Vector2.new(0.5, 0.5)
btn.Position = UDim2.new(0.5, 0, 0.5, 0)
btn.Size = UDim2.new(0, 80, 0, 80)
btn.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
btn.BackgroundTransparency = 0.2
btn.Text = "WH"
btn.TextColor3 = Color3.fromRGB(255, 255, 255)
btn.TextScaled = true
local c = Instance.new("UICorner")
c.CornerRadius = UDim.new(1, 0)
c.Parent = btn
btn.InputBegan:Connect(function(i)
if input then return end
if i.UserInputType == Enum.UserInputType.Touch then
input = i
btn.BackgroundColor3 = Color3.fromRGB(0, 170, 255)
wallhop()
end
end)
btn.InputEnded:Connect(function(i)
if not input then return end
if i.UserInputType == input.UserInputType then
local dist = (i.Position - input.Position).Magnitude
if dist < 100 then
input = nil
btn.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
end
end
end)
end
makeButton()
GuiService.MenuOpened:Connect(function()
if input then
input = nil
if btn then
btn.BackgroundColor3 = Color3.fromRGB(30, 30, 30)
end
end
end)