Roblox · Движение
Прыгнул к стене из папки RunWalls, держишь «вперёд» — бежишь по стене 1,5 секунды, медленно сползая. Прыжок — отскок, можно перепрыгнуть на стену напротив.
Синим — что нужно создать.
StarterPlayer └─ StarterPlayerScripts └─ WallRunLocal (LocalScript) Workspace └─ RunWalls (Folder) — стены для бега
Где: StarterPlayer → StarterPlayerScripts · LocalScript
Зачем: Бег по стене и отскок.
-- события каждого кадра
local RunService = game:GetService("RunService")
-- прыжок
local UIS = game:GetService("UserInputService")
-- этот игрок
local player = game.Players.LocalPlayer
-- стены для бега
local runWalls = workspace:WaitForChild("RunWalls")
-- сколько секунд можно бежать по одной стене
local WALL_TIME = 1.5
-- скорость бега по стене
local SPEED = 28
-- как быстро сползаешь вниз
local FALL = 3
-- настройки луча
local params = RaycastParams.new()
-- только список
params.FilterType = Enum.RaycastFilterType.Include
-- стены для бега
params.FilterDescendantsInstances = {runWalls}
-- бежим по стене?
local running = false
-- когда начали
local started = 0
-- устали — до приземления по стенам не бегаем
local tired = false
-- в какую сторону смотрит стена
local wallNormal = nil
-- игрок нажал прыжок
UIS.JumpRequest:Connect(function()
-- не на стене
if not running then return end
-- центр персонажа
local root = player.Character and player.Character:FindFirstChild("HumanoidRootPart")
-- нет
if not root then return end
-- отскок от стены вверх — можно на соседнюю
root.AssemblyLinearVelocity = wallNormal * 35 + Vector3.new(0, 40, 0)
-- со стены спрыгнули
running = false
-- на следующей стене — новый отсчёт
started = 0
-- конец обработчика
end)
-- каждый кадр
RunService.Heartbeat:Connect(function()
-- персонаж
local character = player.Character
-- Humanoid
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
-- центр
local root = character and character:FindFirstChild("HumanoidRootPart")
-- нет персонажа
if not humanoid or not root or humanoid.Health <= 0 then return end
-- стоит на земле
if humanoid.FloorMaterial ~= Enum.Material.Air then
-- не бежит по стене
running = false
-- отдохнул
tired = false
-- дальше не нужно
return
-- конец проверки
end
-- устал или не жмёт вперёд
if tired or humanoid.MoveDirection.Magnitude < 0.1 then
-- падает
running = false
-- дальше не нужно
return
-- конец проверки
end
-- вправо по земле
local right = root.CFrame.RightVector * Vector3.new(1, 0, 1)
-- стена справа или слева
local result = workspace:Raycast(root.Position, right.Unit * 2.5, params) or workspace:Raycast(root.Position, -right.Unit * 2.5, params)
-- стены сбоку нет
if not result then
-- падает
running = false
-- дальше не нужно
return
-- конец проверки
end
-- только что прыгнул на стену
if not running then
-- бежим
running = true
-- засекаем время
if started == 0 then started = os.clock() end
-- конец проверки
end
-- время вышло
if os.clock() - started > WALL_TIME then
-- срываемся
running = false
-- до приземления больше нельзя
tired = true
-- сброс
started = 0
-- дальше не нужно
return
-- конец проверки
end
-- запоминаем стену — для отскока
wallNormal = result.Normal
-- направление вдоль стены
local along = result.Normal:Cross(Vector3.yAxis)
-- в ту сторону, куда смотрим
if along:Dot(root.CFrame.LookVector) < 0 then along = -along end
-- бежим вдоль, прижимаемся, медленно сползаем
root.AssemblyLinearVelocity = along * SPEED - result.Normal * 2 + Vector3.new(0, -FALL, 0)
-- конец обработчика
end)Запусти Play (или Run) и убедись: