Universal BunnyHop source
Key RequiredUniversal

Universal BunnyHop source

Universal Scriptt1r4t1r4 4.3K views 2.1K executesUpdated Jul 15, 2026
5.0/ 5(1 votes)
10100% Positive
Lua Script•1039 lines (32445 chars)
local Players      = game:GetService("Players")
local UIS          = game:GetService("UserInputService")
local RunService   = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera

local conns = {}
local function bind(signal, fn)
	local c = signal:Connect(fn)
	table.insert(conns, c)
	return c
end

local UPS = 12.5

local S = {
	Enabled       = false,
	AutoHop       = true,
	ToggleKey     = Enum.KeyCode.V,
	MenuKey       = Enum.KeyCode.RightShift,

	GroundSpeed   = 20,
	JumpPower     = 50,
	Gravity       = 196.2,
	SetGravity    = false,

	AirAccelerate = 100,
	AirCap        = 30 / UPS,
	MinBhopSpeed  = 200 / UPS,
	MaxSpeed      = 3500 / UPS,
	LandBoost     = 0,

	BackwardsBhop = true,
	AutoStrafe    = false,

	Surf          = true,
	SurfMinAngle  = 35,
	SurfMaxAngle  = 85,
	SurfAccel     = 140,
	SurfGravity   = 220,
	SurfFriction  = 0,
	SurfDetect    = 7,

	FovBoost      = true,
	BaseFov       = 80,
	FovIntensity  = 35,
	FovMax        = 25,

	ShowHud       = true,
}

local spaceHeld   = false
local simVel      = Vector3.zero
local wasInAir    = false
local surfing     = false
local surfNormal  = Vector3.zero
local defaultWalkSpeed, defaultFov = 16, 70
local defaultGravity = workspace.Gravity

local function getCharacter()
	local char = player.Character
	if not char then return nil end
	local hum  = char:FindFirstChildOfClass("Humanoid")
	local root = char:FindFirstChild("HumanoidRootPart")
	if hum and root and hum.Health > 0 then return char, hum, root end
	return nil
end

local function horizontalOf(v) return Vector3.new(v.X, 0, v.Z) end

local function airAccelerate(vel, wishdir, wishspeed, accel, dt)
	local currentspeed = vel:Dot(wishdir)
	local addspeed = wishspeed - currentspeed
	if addspeed <= 0 then return vel end
	local accelspeed = math.min(accel * wishspeed * dt, addspeed)
	return vel + wishdir * accelspeed
end

local function getMoveInput()
	local f, r = 0, 0
	if UIS:IsKeyDown(Enum.KeyCode.W) then f += 1 end
	if UIS:IsKeyDown(Enum.KeyCode.S) then f -= 1 end
	if UIS:IsKeyDown(Enum.KeyCode.D) then r += 1 end
	if UIS:IsKeyDown(Enum.KeyCode.A) then r -= 1 end
	return f, r
end

local function getWishDir()
	local f, r = getMoveInput()
	if f == 0 and r == 0 then return nil, 0, 0 end

	local look  = camera.CFrame.LookVector
	local right = camera.CFrame.RightVector
	local flatLook  = Vector3.new(look.X, 0, look.Z)
	local flatRight = Vector3.new(right.X, 0, right.Z)
	if flatLook.Magnitude < 1e-4 then return nil, f, r end

	local wish = flatLook.Unit * f + flatRight.Unit * r
	if wish.Magnitude < 1e-4 then return nil, f, r end
	return wish.Unit, f, r
end

local lastYaw = nil
local function getAutoStrafeDir(currentVel)
	local f, r = getMoveInput()
	local yaw = math.atan2(camera.CFrame.LookVector.X, camera.CFrame.LookVector.Z)
	local dyaw = 0
	if lastYaw then
		dyaw = yaw - lastYaw
		if dyaw > math.pi then dyaw -= 2 * math.pi end
		if dyaw < -math.pi then dyaw += 2 * math.pi end
	end
	lastYaw = yaw

	if currentVel.Magnitude < 1e-3 then return getWishDir() end
	local velDir = currentVel.Unit
	local sideSign = dyaw >= 0 and 1 or -1
	if r ~= 0 then sideSign = r > 0 and 1 or -1 end

	local perp = Vector3.new(-velDir.Z, 0, velDir.X) * sideSign
	local wish = (velDir * 0.35 + perp).Unit
	return wish, 1, r
end

local rayParams = RaycastParams.new()
rayParams.FilterType = Enum.RaycastFilterType.Exclude
local function detectSurf(root)
	local char = player.Character
	if char then rayParams.FilterDescendantsInstances = { char } end
	local origin = root.Position
	local dirs = { Vector3.new(0, -1, 0) }
	local vel = root.AssemblyLinearVelocity
	if vel.Magnitude > 1e-3 then table.insert(dirs, vel.Unit) end
	local horiz = horizontalOf(vel)
	if horiz.Magnitude > 1e-3 then table.insert(dirs, horiz.Unit) end

	for _, d in ipairs(dirs) do
		local res = workspace:Raycast(origin, d * S.SurfDetect, rayParams)
		if res then
			local n = res.Normal
			local angle = math.deg(math.acos(math.clamp(n.Y, -1, 1)))
			if angle >= S.SurfMinAngle and angle <= S.SurfMaxAngle then
				return n
			end
		end
	end
	return nil
end

local function clipVelocity(vel, normal, overbounce)
	local backoff = vel:Dot(normal) * overbounce
	return vel - normal * backoff
end

local function applyMode()
	local _, hum = getCharacter()
	if S.Enabled then
		player.CameraMode = Enum.CameraMode.LockFirstPerson
		if hum then
			hum.WalkSpeed = S.GroundSpeed
			hum.UseJumpPower = true
			hum.JumpPower = S.JumpPower
		end
		if S.SetGravity then workspace.Gravity = S.Gravity end
	else
		player.CameraMode = Enum.CameraMode.Classic
		if hum then
			hum.WalkSpeed = defaultWalkSpeed
			hum.JumpPower = 50
		end
		workspace.Gravity = defaultGravity
		camera.FieldOfView = defaultFov
		simVel = Vector3.zero
		surfing = false
	end
end

local function doBhopJump(hum, root)
	local realH = horizontalOf(root.AssemblyLinearVelocity)
	if realH.Magnitude > simVel.Magnitude then simVel = realH end
	if simVel.Magnitude < S.MinBhopSpeed then simVel = realH end

	if S.LandBoost > 0 and simVel.Magnitude > S.MinBhopSpeed then
		simVel = simVel + simVel.Unit * (S.LandBoost / UPS)
		if simVel.Magnitude > S.MaxSpeed then simVel = simVel.Unit * S.MaxSpeed end
	end

	hum:ChangeState(Enum.HumanoidStateType.Jumping)
	root.AssemblyLinearVelocity = Vector3.new(simVel.X, S.JumpPower, simVel.Z)
end

bind(RunService.Stepped, function(_, dt)
	if not S.Enabled then return end
	local _, hum, root = getCharacter()
	if not hum then return end

	local inAir = hum.FloorMaterial == Enum.Material.Air
	local vel = root.AssemblyLinearVelocity

	surfing = false
	surfNormal = Vector3.zero
	if S.Surf and inAir then
		local n = detectSurf(root)
		if n then
			surfing = true
			surfNormal = n
		end
	end

	if surfing then
		local full = root.AssemblyLinearVelocity

		full = full + Vector3.new(0, -S.SurfGravity * dt, 0)

		local wishdir = getWishDir()
		if wishdir then
			local wishspeed = S.AirCap
			full = airAccelerate(full, wishdir, wishspeed, S.SurfAccel, dt)
		end

		if full:Dot(surfNormal) < 0 then
			full = clipVelocity(full, surfNormal, 1)
		end

		if S.SurfFriction > 0 then
			local sp = full.Magnitude
			if sp > 0 then
				local drop = sp * S.SurfFriction * dt
				full = full * (math.max(sp - drop, 0) / sp)
			end
		end

		if full.Magnitude > S.MaxSpeed then full = full.Unit * S.MaxSpeed end
		root.AssemblyLinearVelocity = full
		simVel = horizontalOf(full)
	elseif inAir then
		if not wasInAir then
			local realH = horizontalOf(vel)
			if realH.Magnitude > simVel.Magnitude then simVel = realH end
		end

		local wishdir, f, r = getWishDir()
		if S.AutoStrafe and (f ~= 0 or r ~= 0) then
			wishdir = getAutoStrafeDir(simVel)
			f = 1
		end

		if wishdir then
			local allow = true
			if not S.BackwardsBhop and f < 0 then allow = false end
			if allow then
				simVel = airAccelerate(simVel, wishdir, S.AirCap, S.AirAccelerate, dt)
				if simVel.Magnitude > S.MaxSpeed then
					simVel = simVel.Unit * S.MaxSpeed
				end
			end
		end

		local realH = horizontalOf(vel)
		if wasInAir and realH.Magnitude < simVel.Magnitude * 0.4 then
			simVel = realH
		end

		root.AssemblyLinearVelocity = Vector3.new(simVel.X, vel.Y, simVel.Z)
	else
		if S.AutoHop and spaceHeld then
			doBhopJump(hum, root)
		else
			simVel = horizontalOf(vel)
		end
	end

	wasInAir = inAir or surfing
end)

bind(RunService.RenderStepped, function(dt)
	if not S.Enabled or not S.FovBoost then return end
	local _, _, root = getCharacter()
	if not root then return end
	local speed = horizontalOf(root.AssemblyLinearVelocity).Magnitude
	local target = S.BaseFov + math.clamp((speed - S.GroundSpeed) * (S.FovIntensity / 100), 0, S.FovMax)
	camera.FieldOfView += (target - camera.FieldOfView) * math.min(dt * 8, 1)
end)

local keybindCapturing = false
local toggleFromKeybind
local menuFromKeybind

bind(UIS.InputBegan, function(input, gpe)
	if input.KeyCode == Enum.KeyCode.Space then
		spaceHeld = true
		if S.Enabled and not S.AutoHop and not gpe then
			local _, hum, root = getCharacter()
			if hum and hum.FloorMaterial ~= Enum.Material.Air then
				doBhopJump(hum, root)
			end
		end
	end
	if gpe or keybindCapturing then return end
	if input.KeyCode == S.ToggleKey then
		S.Enabled = not S.Enabled
		applyMode()
		if toggleFromKeybind then toggleFromKeybind(S.Enabled) end
	elseif input.KeyCode == S.MenuKey then
		if menuFromKeybind then menuFromKeybind() end
	end
end)
bind(UIS.InputEnded, function(input)
	if input.KeyCode == Enum.KeyCode.Space then spaceHeld = false end
end)

bind(player.CharacterAdded, function()
	task.wait(0.2)
	simVel = Vector3.zero
	wasInAir = false
	surfing = false
	applyMode()
end)

local BG0     = Color3.fromRGB(13, 14, 17)
local BG1     = Color3.fromRGB(19, 20, 25)
local BG2     = Color3.fromRGB(28, 30, 37)
local LINE    = Color3.fromRGB(44, 47, 56)
local TXT     = Color3.fromRGB(233, 235, 240)
local TXT_DIM = Color3.fromRGB(126, 131, 145)
local ACCENT  = Color3.fromRGB(96, 224, 168)
local ACCENT_D= Color3.fromRGB(58, 150, 112)

local SPRING = TweenInfo.new(0.55, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
local FAST   = TweenInfo.new(0.28, Enum.EasingStyle.Quint, Enum.EasingDirection.Out)
local SNAP   = TweenInfo.new(0.16, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)

local function tween(obj, info, props) local t = TweenService:Create(obj, info, props) t:Play() return t end

local gui = Instance.new("ScreenGui")
gui.Name = "BhopSuite"
gui.ResetOnSpawn = false
gui.IgnoreGuiInset = true
gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling
gui.DisplayOrder = 50
gui.Parent = player:WaitForChild("PlayerGui")

local function round(obj, r)
	local c = Instance.new("UICorner")
	c.CornerRadius = UDim.new(0, r)
	c.Parent = obj
	return c
end
local function stroke(obj, color, thick, tr)
	local s = Instance.new("UIStroke")
	s.Color = color
	s.Thickness = thick or 1
	s.Transparency = tr or 0
	s.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
	s.Parent = obj
	return s
end
local function pad(obj, l, t, r, b)
	local p = Instance.new("UIPadding")
	p.PaddingLeft = UDim.new(0, l)
	p.PaddingTop = UDim.new(0, t)
	p.PaddingRight = UDim.new(0, r or l)
	p.PaddingBottom = UDim.new(0, b or t)
	p.Parent = obj
	return p
end

local MENU_W, MENU_H = 380, 460

local main = Instance.new("Frame")
main.Size = UDim2.fromOffset(MENU_W, MENU_H)
main.Position = UDim2.new(0.5, 0, 0.5, 0)
main.AnchorPoint = Vector2.new(0.5, 0.5)
main.BackgroundColor3 = BG0
main.BorderSizePixel = 0
main.Active = true
main.ClipsDescendants = true
main.Parent = gui
round(main, 16)
stroke(main, LINE, 1, 0.2)

local header = Instance.new("Frame")
header.Size = UDim2.new(1, 0, 0, 58)
header.BackgroundTransparency = 1
header.Parent = main

local dot = Instance.new("Frame")
dot.Size = UDim2.fromOffset(7, 7)
dot.Position = UDim2.fromOffset(24, 26)
dot.BackgroundColor3 = TXT_DIM
dot.BorderSizePixel = 0
dot.Parent = header
round(dot, 4)

local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, -120, 0, 20)
title.Position = UDim2.fromOffset(42, 16)
title.BackgroundTransparency = 1
title.Font = Enum.Font.GothamBold
title.TextSize = 15
title.TextXAlignment = Enum.TextXAlignment.Left
title.TextColor3 = TXT
title.Text = "bunnyhop"
title.Parent = header

local subtitle = Instance.new("TextLabel")
subtitle.Size = UDim2.new(1, -120, 0, 14)
subtitle.Position = UDim2.fromOffset(42, 34)
subtitle.BackgroundTransparency = 1
subtitle.Font = Enum.Font.GothamMedium
subtitle.TextSize = 11
subtitle.TextXAlignment = Enum.TextXAlignment.Left
subtitle.TextColor3 = TXT_DIM
subtitle.Text = "by t1r4"
subtitle.Parent = header

local closeBtn = Instance.new("TextButton")
closeBtn.Size = UDim2.fromOffset(28, 28)
closeBtn.Position = UDim2.new(1, -44, 0, 16)
closeBtn.BackgroundColor3 = BG2
closeBtn.Font = Enum.Font.GothamBold
closeBtn.TextSize = 15
closeBtn.Text = "×"
closeBtn.AutoButtonColor = false
closeBtn.TextColor3 = TXT_DIM
closeBtn.Parent = header
round(closeBtn, 8)
closeBtn.MouseEnter:Connect(function()
	tween(closeBtn, SNAP, { BackgroundColor3 = Color3.fromRGB(190, 70, 70), TextColor3 = Color3.new(1, 1, 1) })
end)
closeBtn.MouseLeave:Connect(function()
	tween(closeBtn, SNAP, { BackgroundColor3 = BG2, TextColor3 = TXT_DIM })
end)

local divider = Instance.new("Frame")
divider.Size = UDim2.new(1, -48, 0, 1)
divider.Position = UDim2.fromOffset(24, 58)
divider.BackgroundColor3 = LINE
divider.BorderSizePixel = 0
divider.Parent = main

local tabBar = Instance.new("Frame")
tabBar.Size = UDim2.new(1, -48, 0, 34)
tabBar.Position = UDim2.fromOffset(24, 70)
tabBar.BackgroundColor3 = BG1
tabBar.BorderSizePixel = 0
tabBar.Parent = main
round(tabBar, 9)

local pill = Instance.new("Frame")
pill.Size = UDim2.fromOffset(0, 28)
pill.Position = UDim2.fromOffset(3, 3)
pill.BackgroundColor3 = BG2
pill.BorderSizePixel = 0
pill.Parent = tabBar
round(pill, 7)
stroke(pill, LINE, 1, 0.4)

local pages = Instance.new("Frame")
pages.Size = UDim2.new(1, -48, 1, -128)
pages.Position = UDim2.fromOffset(24, 116)
pages.BackgroundTransparency = 1
pages.ClipsDescendants = true
pages.Parent = main

local TAB_NAMES = { "Основное", "Физика", "Серф" }
local tabButtons = {}
local pageFrames = {}
local currentTab = 1

local function makePage(name)
	local scroll = Instance.new("ScrollingFrame")
	scroll.Size = UDim2.new(1, 0, 1, 0)
	scroll.BackgroundTransparency = 1
	scroll.BorderSizePixel = 0
	scroll.ScrollBarThickness = 3
	scroll.ScrollBarImageColor3 = LINE
	scroll.CanvasSize = UDim2.new(0, 0, 0, 0)
	scroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
	scroll.ScrollingDirection = Enum.ScrollingDirection.Y
	scroll.Visible = false
	scroll.Parent = pages
	local list = Instance.new("UIListLayout")
	list.Padding = UDim.new(0, 8)
	list.SortOrder = Enum.SortOrder.LayoutOrder
	list.Parent = scroll
	pad(scroll, 0, 2, 6, 2)
	return scroll
end

for i, n in ipairs(TAB_NAMES) do
	pageFrames[i] = makePage(n)
end

local function positionPill(i, animate)
	local w = tabBar.AbsoluteSize.X - 6
	local seg = w / #TAB_NAMES
	local info = animate and TweenInfo.new(0.5, Enum.EasingStyle.Quint, Enum.EasingDirection.Out) or TweenInfo.new(0)
	tween(pill, info, {
		Position = UDim2.fromOffset(3 + seg * (i - 1), 3),
		Size = UDim2.fromOffset(seg, 28),
	})
end

local function selectTab(i, animate)
	currentTab = i
	positionPill(i, animate)
	for idx, btn in ipairs(tabButtons) do
		tween(btn, FAST, { TextColor3 = idx == i and TXT or TXT_DIM })
	end
	for idx, pg in ipairs(pageFrames) do
		if idx == i then
			pg.Visible = true
			pg.Position = UDim2.fromOffset(animate and 14 or 0, 0)
			tween(pg, SPRING, { Position = UDim2.fromOffset(0, 0) })
		else
			pg.Visible = false
		end
	end
end

for i, n in ipairs(TAB_NAMES) do
	local btn = Instance.new("TextButton")
	btn.Size = UDim2.new(1 / #TAB_NAMES, 0, 1, 0)
	btn.Position = UDim2.new((i - 1) / #TAB_NAMES, 0, 0, 0)
	btn.BackgroundTransparency = 1
	btn.Font = Enum.Font.GothamBold
	btn.TextSize = 12
	btn.TextColor3 = i == 1 and TXT or TXT_DIM
	btn.Text = n
	btn.AutoButtonColor = false
	btn.ZIndex = 2
	btn.Parent = tabBar
	tabButtons[i] = btn
	btn.MouseButton1Click:Connect(function() selectTab(i, true) end)
end

local function makeSection(page, text, order)
	local lbl = Instance.new("TextLabel")
	lbl.Size = UDim2.new(1, 0, 0, 22)
	lbl.BackgroundTransparency = 1
	lbl.Font = Enum.Font.GothamBold
	lbl.TextSize = 11
	lbl.TextXAlignment = Enum.TextXAlignment.Left
	lbl.TextYAlignment = Enum.TextYAlignment.Bottom
	lbl.TextColor3 = TXT_DIM
	lbl.Text = string.upper(text)
	lbl.LayoutOrder = order
	lbl.Parent = page
end

local function makeToggle(page, text, initial, order, callback)
	local row = Instance.new("Frame")
	row.Size = UDim2.new(1, 0, 0, 40)
	row.BackgroundColor3 = BG1
	row.BorderSizePixel = 0
	row.LayoutOrder = order
	row.Parent = page
	round(row, 10)

	local lbl = Instance.new("TextLabel")
	lbl.Size = UDim2.new(1, -80, 1, 0)
	lbl.Position = UDim2.fromOffset(14, 0)
	lbl.BackgroundTransparency = 1
	lbl.Font = Enum.Font.GothamMedium
	lbl.TextSize = 13
	lbl.TextXAlignment = Enum.TextXAlignment.Left
	lbl.TextColor3 = TXT
	lbl.Text = text
	lbl.Parent = row

	local track = Instance.new("TextButton")
	track.Size = UDim2.fromOffset(42, 22)
	track.Position = UDim2.new(1, -56, 0.5, -11)
	track.BackgroundColor3 = initial and ACCENT or LINE
	track.Text = ""
	track.AutoButtonColor = false
	track.Parent = row
	round(track, 11)

	local knob = Instance.new("Frame")
	knob.Size = UDim2.fromOffset(16, 16)
	knob.Position = initial and UDim2.new(1, -19, 0.5, -8) or UDim2.new(0, 3, 0.5, -8)
	knob.BackgroundColor3 = Color3.new(1, 1, 1)
	knob.BorderSizePixel = 0
	knob.Parent = track
	round(knob, 8)

	local state = initial
	local function setState(v, fire)
		state = v
		tween(knob, TweenInfo.new(0.45, Enum.EasingStyle.Back, Enum.EasingDirection.Out), {
			Position = v and UDim2.new(1, -19, 0.5, -8) or UDim2.new(0, 3, 0.5, -8)
		})
		tween(track, FAST, { BackgroundColor3 = v and ACCENT or LINE })
		if fire then callback(v) end
	end
	track.MouseButton1Click:Connect(function() setState(not state, true) end)
	row.MouseEnter:Connect(function() tween(row, SNAP, { BackgroundColor3 = BG2 }) end)
	row.MouseLeave:Connect(function() tween(row, SNAP, { BackgroundColor3 = BG1 }) end)
	return setState
end

local function makeSlider(page, text, minV, maxV, initial, step, suffix, order, callback)
	step = step or 1
	local row = Instance.new("Frame")
	row.Size = UDim2.new(1, 0, 0, 54)
	row.BackgroundColor3 = BG1
	row.BorderSizePixel = 0
	row.LayoutOrder = order
	row.Parent = page
	round(row, 10)

	local lbl = Instance.new("TextLabel")
	lbl.Size = UDim2.new(1, -110, 0, 18)
	lbl.Position = UDim2.fromOffset(14, 9)
	lbl.BackgroundTransparency = 1
	lbl.Font = Enum.Font.GothamMedium
	lbl.TextSize = 13
	lbl.TextXAlignment = Enum.TextXAlignment.Left
	lbl.TextColor3 = TXT
	lbl.Text = text
	lbl.Parent = row

	local value = initial

	local function fmt(v)
		if step < 1 then return string.format("%.1f", v) else return tostring(math.floor(v + 0.5)) end
	end

	local valBox = Instance.new("TextBox")
	valBox.Size = UDim2.new(0, 90, 0, 20)
	valBox.Position = UDim2.new(1, -104, 0, 8)
	valBox.BackgroundColor3 = BG2
	valBox.BackgroundTransparency = 1
	valBox.Font = Enum.Font.GothamBold
	valBox.TextSize = 13
	valBox.TextXAlignment = Enum.TextXAlignment.Right
	valBox.TextColor3 = ACCENT
	valBox.ClearTextOnFocus = false
	valBox.Text = fmt(initial) .. (suffix or "")
	valBox.Parent = row
	round(valBox, 6)
	pad(valBox, 6, 0, 6, 0)

	local bar = Instance.new("Frame")
	bar.Size = UDim2.new(1, -28, 0, 5)
	bar.Position = UDim2.new(0, 14, 1, -18)
	bar.BackgroundColor3 = LINE
	bar.BorderSizePixel = 0
	bar.Parent = row
	round(bar, 3)

	local fill = Instance.new("Frame")
	fill.Size = UDim2.new(math.clamp((initial - minV) / (maxV - minV), 0, 1), 0, 1, 0)
	fill.BackgroundColor3 = ACCENT
	fill.BorderSizePixel = 0
	fill.Parent = bar
	round(fill, 3)

	local grip = Instance.new("Frame")
	grip.Size = UDim2.fromOffset(13, 13)
	grip.AnchorPoint = Vector2.new(0.5, 0.5)
	grip.Position = UDim2.new(1, 0, 0.5, 0)
	grip.BackgroundColor3 = Color3.new(1, 1, 1)
	grip.BorderSizePixel = 0
	grip.Parent = fill
	round(grip, 7)
	stroke(grip, ACCENT_D, 1, 0.3)

	local function applyValue(v, instant, updateText)
		value = v
		local shownRel = math.clamp((v - minV) / (maxV - minV), 0, 1)
		tween(fill, TweenInfo.new(instant and 0.06 or 0.14, Enum.EasingStyle.Quad), { Size = UDim2.new(shownRel, 0, 1, 0) })
		if updateText then valBox.Text = fmt(v) .. (suffix or "") end
		callback(v)
	end

	local dragging = false
	local function updateFromMouse(x, instant)
		local rel = math.clamp((x - bar.AbsolutePosition.X) / bar.AbsoluteSize.X, 0, 1)
		local raw = minV + rel * (maxV - minV)
		local v = math.floor(raw / step + 0.5) * step
		v = math.clamp(v, minV, maxV)
		applyValue(v, instant, true)
	end

	bar.InputBegan:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			updateFromMouse(input.Position.X)
			tween(grip, SNAP, { Size = UDim2.fromOffset(17, 17) })
		end
	end)
	UIS.InputChanged:Connect(function(input)
		if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
			updateFromMouse(input.Position.X, true)
		end
	end)
	UIS.InputEnded:Connect(function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 and dragging then
			dragging = false
			tween(grip, SNAP, { Size = UDim2.fromOffset(13, 13) })
		end
	end)

	valBox.Focused:Connect(function()
		tween(valBox, SNAP, { BackgroundTransparency = 0 })
		valBox.Text = fmt(value)
	end)
	valBox.FocusLost:Connect(function()
		tween(valBox, SNAP, { BackgroundTransparency = 1 })
		local n = tonumber(valBox.Text)
		if n then
			if n < minV then n = minV end
			applyValue(n, false, false)
		end
		valBox.Text = fmt(value) .. (suffix or "")
	end)

	row.MouseEnter:Connect(function() tween(row, SNAP, { BackgroundColor3 = BG2 }) end)
	row.MouseLeave:Connect(function() tween(row, SNAP, { BackgroundColor3 = BG1 }) end)
	return valBox
end

local function makeKeybind(page, text, getKey, order, callback)
	local row = Instance.new("Frame")
	row.Size = UDim2.new(1, 0, 0, 40)
	row.BackgroundColor3 = BG1
	row.BorderSizePixel = 0
	row.LayoutOrder = order
	row.Parent = page
	round(row, 10)

	local lbl = Instance.new("TextLabel")
	lbl.Size = UDim2.new(1, -100, 1, 0)
	lbl.Position = UDim2.fromOffset(14, 0)
	lbl.BackgroundTransparency = 1
	lbl.Font = Enum.Font.GothamMedium
	lbl.TextSize = 13
	lbl.TextXAlignment = Enum.TextXAlignment.Left
	lbl.TextColor3 = TXT
	lbl.Text = text
	lbl.Parent = row

	local btn = Instance.new("TextButton")
	btn.Size = UDim2.fromOffset(78, 26)
	btn.Position = UDim2.new(1, -92, 0.5, -13)
	btn.BackgroundColor3 = BG2
	btn.Font = Enum.Font.GothamBold
	btn.TextSize = 12
	btn.TextColor3 = ACCENT
	btn.AutoButtonColor = false
	btn.Text = getKey().Name
	btn.Parent = row
	round(btn, 7)
	stroke(btn, LINE, 1, 0.3)

	btn.MouseButton1Click:Connect(function()
		if keybindCapturing then return end
		keybindCapturing = true
		btn.Text = "..."
		tween(btn, SNAP, { BackgroundColor3 = ACCENT, TextColor3 = BG0 })
		local conn
		conn = UIS.InputBegan:Connect(function(input)
			if input.UserInputType ~= Enum.UserInputType.Keyboard then return end
			conn:Disconnect()
			if input.KeyCode ~= Enum.KeyCode.Escape and input.KeyCode ~= Enum.KeyCode.Space then
				callback(input.KeyCode)
			end
			btn.Text = getKey().Name
			tween(btn, SNAP, { BackgroundColor3 = BG2, TextColor3 = ACCENT })
			task.wait(0.1)
			keybindCapturing = false
		end)
	end)
	row.MouseEnter:Connect(function() tween(row, SNAP, { BackgroundColor3 = BG2 }) end)
	row.MouseLeave:Connect(function() tween(row, SNAP, { BackgroundColor3 = BG1 }) end)
end

local dotPulse
local function setDotState(on)
	if dotPulse then dotPulse:Cancel() end
	if on then
		dot.BackgroundColor3 = ACCENT
		dotPulse = TweenService:Create(dot,
			TweenInfo.new(0.9, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true),
			{ BackgroundTransparency = 0.65 })
		dotPulse:Play()
	else
		dot.BackgroundTransparency = 0
		dot.BackgroundColor3 = TXT_DIM
	end
end

local p1 = pageFrames[1]
makeSection(p1, "Управление", 0)
local setBhopToggle = makeToggle(p1, "Bunny Hop", false, 1, function(v)
	S.Enabled = v
	applyMode()
	setDotState(v)
end)
makeToggle(p1, "Auto Hop (зажать пробел)", S.AutoHop, 2, function(v) S.AutoHop = v end)
makeKeybind(p1, "Кейбинд бхопа", function() return S.ToggleKey end, 3, function(k) S.ToggleKey = k end)
makeKeybind(p1, "Кейбинд меню", function() return S.MenuKey end, 4, function(k) S.MenuKey = k end)

makeSection(p1, "Камера", 5)
makeToggle(p1, "FOV от скорости", S.FovBoost, 6, function(v)
	S.FovBoost = v
	if not v then camera.FieldOfView = S.Enabled and S.BaseFov or defaultFov end
end)
makeSlider(p1, "Базовый FOV", 60, 110, S.BaseFov, 1, "", 7, function(v) S.BaseFov = v end)
makeSlider(p1, "Сила FOV", 5, 100, S.FovIntensity, 1, "%", 8, function(v) S.FovIntensity = v end)
makeSlider(p1, "Макс. прибавка FOV", 5, 60, S.FovMax, 1, "", 9, function(v) S.FovMax = v end)
makeToggle(p1, "Спидометр (HUD)", S.ShowHud, 10, function(v) S.ShowHud = v end)

local p2 = pageFrames[2]
makeSection(p2, "Скорость и прыжок", 0)
makeSlider(p2, "Скорость бега", 12, 60, S.GroundSpeed, 1, "", 1, function(v)
	S.GroundSpeed = v
	if S.Enabled then local _, hum = getCharacter() if hum then hum.WalkSpeed = v end end
end)
makeSlider(p2, "Высота прыжка", 20, 120, S.JumpPower, 1, "", 2, function(v)
	S.JumpPower = v
	if S.Enabled then local _, hum = getCharacter() if hum then hum.JumpPower = v end end
end)
makeToggle(p2, "Своя гравитация", S.SetGravity, 3, function(v)
	S.SetGravity = v
	if S.Enabled then workspace.Gravity = v and S.Gravity or defaultGravity end
end)
makeSlider(p2, "Гравитация", 50, 400, S.Gravity, 1, "", 4, function(v)
	S.Gravity = v
	if S.Enabled and S.SetGravity then workspace.Gravity = v end
end)

makeSection(p2, "Распрыжка (air)", 5)
makeSlider(p2, "Air Accelerate", 10, 400, S.AirAccelerate, 5, "", 6, function(v) S.AirAccelerate = v end)
makeSlider(p2, "Air Cap (ups)", 10, 100, math.floor(S.AirCap * UPS), 1, "", 7, function(v) S.AirCap = v / UPS end)
makeSlider(p2, "Порог бхопа (ups)", 50, 400, math.floor(S.MinBhopSpeed * UPS), 5, "", 8, function(v) S.MinBhopSpeed = v / UPS end)
makeSlider(p2, "Потолок (ups)", 500, 6000, math.floor(S.MaxSpeed * UPS), 50, "", 9, function(v) S.MaxSpeed = v / UPS end)
makeSlider(p2, "Буст при прыжке (ups)", 0, 100, S.LandBoost, 1, "", 10, function(v) S.LandBoost = v end)
makeToggle(p2, "Бхоп задом (S/back)", S.BackwardsBhop, 11, function(v) S.BackwardsBhop = v end)
makeToggle(p2, "Авто-стрейф", S.AutoStrafe, 12, function(v) S.AutoStrafe = v end)

local p3 = pageFrames[3]
makeSection(p3, "Серфинг", 0)
makeToggle(p3, "Включить серф", S.Surf, 1, function(v) S.Surf = v end)
makeSlider(p3, "Мин. угол рампы", 10, 60, S.SurfMinAngle, 1, "°", 2, function(v) S.SurfMinAngle = v end)
makeSlider(p3, "Макс. угол рампы", 60, 89, S.SurfMaxAngle, 1, "°", 3, function(v) S.SurfMaxAngle = v end)
makeSlider(p3, "Дистанция детекта", 3, 20, S.SurfDetect, 1, "", 4, function(v) S.SurfDetect = v end)

makeSection(p3, "Физика серфа", 5)
makeSlider(p3, "Ускорение", 20, 300, S.SurfAccel, 5, "", 6, function(v) S.SurfAccel = v end)
makeSlider(p3, "Гравитация серфа", 50, 400, S.SurfGravity, 5, "", 7, function(v) S.SurfGravity = v end)
makeSlider(p3, "Трение", 0, 10, S.SurfFriction, 0.5, "", 8, function(v) S.SurfFriction = v end)

local hintRow = Instance.new("TextLabel")
hintRow.Size = UDim2.new(1, 0, 0, 44)
hintRow.BackgroundTransparency = 1
hintRow.Font = Enum.Font.Gotham
hintRow.TextSize = 11
hintRow.TextWrapped = true
hintRow.TextColor3 = TXT_DIM
hintRow.TextXAlignment = Enum.TextXAlignment.Left
hintRow.Text = "никаких неиронок в создании кода, чистый вайбкод"
hintRow.LayoutOrder = 9
hintRow.Parent = p3

toggleFromKeybind = function(v) setBhopToggle(v, false); setDotState(v) end

local hud = Instance.new("Frame")
hud.Size = UDim2.fromOffset(180, 76)
hud.Position = UDim2.new(0.5, 0, 1, -110)
hud.AnchorPoint = Vector2.new(0.5, 0.5)
hud.BackgroundColor3 = BG0
hud.BackgroundTransparency = 1
hud.BorderSizePixel = 0
hud.Visible = false
hud.Parent = gui
round(hud, 12)
local hudStroke = stroke(hud, LINE, 1, 1)

local speedLbl = Instance.new("TextLabel")
speedLbl.Size = UDim2.new(1, 0, 0, 34)
speedLbl.Position = UDim2.fromOffset(0, 10)
speedLbl.BackgroundTransparency = 1
speedLbl.Font = Enum.Font.GothamBold
speedLbl.TextSize = 28
speedLbl.TextColor3 = TXT
speedLbl.TextTransparency = 1
speedLbl.Text = "0"
speedLbl.Parent = hud

local unitLbl = Instance.new("TextLabel")
unitLbl.Size = UDim2.new(1, 0, 0, 12)
unitLbl.Position = UDim2.fromOffset(0, 42)
unitLbl.BackgroundTransparency = 1
unitLbl.Font = Enum.Font.GothamMedium
unitLbl.TextSize = 10
unitLbl.TextColor3 = TXT_DIM
unitLbl.TextTransparency = 1
unitLbl.Text = "UPS"
unitLbl.Parent = hud

local speedBarBg = Instance.new("Frame")
speedBarBg.Size = UDim2.new(1, -28, 0, 4)
speedBarBg.Position = UDim2.new(0, 14, 1, -14)
speedBarBg.BackgroundColor3 = LINE
speedBarBg.BackgroundTransparency = 1
speedBarBg.BorderSizePixel = 0
speedBarBg.Parent = hud
round(speedBarBg, 2)

local speedBar = Instance.new("Frame")
speedBar.Size = UDim2.new(0, 0, 1, 0)
speedBar.BackgroundColor3 = ACCENT
speedBar.BorderSizePixel = 0
speedBar.Parent = speedBarBg
round(speedBar, 2)

local hudShown = false
bind(RunService.RenderStepped, function()
	local wantHud = S.Enabled and S.ShowHud
	if wantHud ~= hudShown then
		hudShown = wantHud
		if wantHud then hud.Visible = true end
		local tt = wantHud and 0 or 1
		tween(hud, FAST, { BackgroundTransparency = wantHud and 0.1 or 1 })
		tween(hudStroke, FAST, { Transparency = wantHud and 0.2 or 1 })
		tween(speedLbl, FAST, { TextTransparency = tt })
		tween(unitLbl, FAST, { TextTransparency = tt })
		tween(speedBarBg, FAST, { BackgroundTransparency = wantHud and 0.4 or 1 })
		local tb = tween(speedBar, FAST, { BackgroundTransparency = tt })
		if not wantHud then tb.Completed:Once(function() if not hudShown then hud.Visible = false end end) end
	end
	if not S.Enabled or not S.ShowHud then return end
	local _, hum, root = getCharacter()
	if not root then return end
	local speed = horizontalOf(root.AssemblyLinearVelocity).Magnitude
	local ups = math.floor(speed * UPS)
	speedLbl.Text = tostring(ups)
	local t = math.clamp((ups - 200) / 200, 0, 1)
	speedLbl.TextColor3 = TXT:Lerp(ACCENT, t)
	local barRel = math.clamp(ups / 800, 0, 1)
	tween(speedBar, TweenInfo.new(0.1, Enum.EasingStyle.Linear), { Size = UDim2.new(barRel, 0, 1, 0) })
	speedBar.BackgroundColor3 = surfing and Color3.fromRGB(120, 180, 255) or (ups >= 200 and ACCENT or TXT_DIM)
	if surfing then
		unitLbl.Text = "SURF"
	elseif hum and hum.FloorMaterial == Enum.Material.Air then
		unitLbl.Text = "AIR"
	else
		unitLbl.Text = "UPS"
	end
end)

do
	local dragging = false
	local dragStart, startPos = nil, nil
	local targetPos = main.Position

	bind(header.InputBegan, function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			dragging = true
			dragStart = input.Position
			startPos = main.Position
			targetPos = main.Position
		end
	end)
	bind(UIS.InputChanged, function(input)
		if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
			local d = input.Position - dragStart
			targetPos = UDim2.new(startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y)
		end
	end)
	bind(UIS.InputEnded, function(input)
		if input.UserInputType == Enum.UserInputType.MouseButton1 then dragging = false end
	end)

	-- мягкое перетаскивание: окно плавно догоняет курсор с лёгким отставанием
	bind(RunService.RenderStepped, function(dt)
		local cur = main.Position
		local a = 1 - math.exp(-dt * 12)
		main.Position = UDim2.new(
			targetPos.X.Scale,
			cur.X.Offset + (targetPos.X.Offset - cur.X.Offset) * a,
			targetPos.Y.Scale,
			cur.Y.Offset + (targetPos.Y.Offset - cur.Y.Offset) * a
		)
	end)
end

local closed = false
local function destroy()
	if closed then return end
	closed = true
	S.Enabled = false
	applyMode()
	for _, c in ipairs(conns) do
		pcall(function() c:Disconnect() end)
	end
	table.clear(conns)
	local tw = tween(main, TweenInfo.new(0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.In), {
		Size = UDim2.fromOffset(MENU_W * 0.9, MENU_H * 0.9),
		BackgroundTransparency = 1,
	})
	tw.Completed:Once(function() gui:Destroy() end)
end

local menuVisible = true
local function setMenuVisible(v)
	if closed then return end
	menuVisible = v
	if v then
		main.Visible = true
		main.Size = UDim2.fromOffset(MENU_W * 0.9, MENU_H * 0.9)
		main.BackgroundTransparency = 1
		tween(main, TweenInfo.new(0.5, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), { Size = UDim2.fromOffset(MENU_W, MENU_H) })
		tween(main, FAST, { BackgroundTransparency = 0 })
	else
		local tw = tween(main, TweenInfo.new(0.28, Enum.EasingStyle.Quint, Enum.EasingDirection.In), {
			Size = UDim2.fromOffset(MENU_W * 0.9, MENU_H * 0.9),
			BackgroundTransparency = 1,
		})
		tw.Completed:Once(function() if not menuVisible then main.Visible = false end end)
	end
end

menuFromKeybind = function() setMenuVisible(not menuVisible) end
closeBtn.MouseButton1Click:Connect(function() destroy() end)

task.defer(function()
	positionPill(1, false)
	selectTab(1, false)
end)

applyMode()
print("[bunnyhop] загружен. " .. S.ToggleKey.Name .. " — вкл/выкл, " .. S.MenuKey.Name .. " — меню (крестик закрывает скрипт).")

Features & Information

Bunny Hop Auto Hop (зажать пробел) Кейбинд бхопа Кейбинд меню FOV от скорости Базовый FOV Сила FOV Макс. прибавка FOV Спидометр (HUD) Скорость бега Высота прыжка Своя гравитация Гравитация Air Accelerate Air Cap (ups) Порог бхопа (ups) Потолок (ups) Буст при прыжке (ups) Бхоп задом (S/back) Авто-стрейф Включить серф Мин. угол рампы Макс. угол рампы Дистанция детекта Ускорение Гравитация серфа Трение

Community Comments (3)

Jonny_thaanJonny_thaanJul 15, 2026

i cant even download the file my internet is washed

Replying to @Jonny_thaan
t1r4t1r4Jul 16, 2026

@Jonny_thaan well, you're *ing great

JorsaJorsaOct 11, 2026

Hi, I have a question. How do you jump correctly? I pressed “W”, “Ctrl”, moved the mouse left and right, and alternated pressing the “A” and “D” keys, but I could only reach a maximum of 280 ups (the character’s usual speed is 230 ups), while the settings indicate a ceiling of 2300, and I’m not sure if I’m doing it right. I usually performed all the actions with a jump height of 20.

More Scripts for Universal Scripts