ParkourSystem_v3

Run Settings
LanguageLua
Language Version
Run Command
--[[ ██████╗ █████╗ ██████╗ ██╗ ██╗ ██████╗ ██╗ ██╗██████╗ ██╔══██╗██╔══██╗██╔══██╗██║ ██╔╝██╔═══██╗██║ ██║██╔══██╗ ██████╔╝███████║██████╔╝█████╔╝ ██║ ██║██║ ██║██████╔╝ ██╔═══╝ ██╔══██║██╔══██╗██╔═██╗ ██║ ██║██║ ██║██╔══██╗ ██║ ██║ ██║██║ ██║██║ ██╗╚██████╔╝╚██████╔╝██║ ██║ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ Advanced Parkour System v3.0 Motor6D CFrame animation (no server APIs needed) Keybinds: [LEFT SHIFT] while sprinting = Slide [SPACE] near wall + moving = Wall Run [SPACE] near low obstacle = Vault [LEFT SHIFT] + moving = Sprint ]] -- // Services local Players = game:GetService("Players") local RunService = game:GetService("RunService") local UserInputService = game:GetService("UserInputService") local TweenService = game:GetService("TweenService") local Debris = game:GetService("Debris") local Player = Players.LocalPlayer local Camera = workspace.CurrentCamera -- // CONFIG local CFG = { WallRunSpeed = 26, WallRunDuration = 1.3, WallRunGravity = 0.4, WallRunRayDist = 3.5, WallRunCooldown = 0.4, WallRunCamTilt = 14, SlideSpeed = 36, SlideDuration = 0.9, SlideCooldown = 0.5, SlideCamTilt = -7, SlideFriction = 0.93, SlideMinSpeed = 8, VaultRayDist = 4.5, VaultMaxHeight = 7, VaultMinHeight = 1.2, VaultDuration = 0.28, VaultCooldown = 0.35, MaxStamina = 100, StaminaRegen = 20, WallRunDrain = 28, SlideCost = 12, VaultCost = 8, WalkSpeed = 16, SprintSpeed = 22, } -- // CHARACTER SETUP local Character, Humanoid, RootPart local Motors = {} -- Store Motor6D references + their original C0 local function CacheMotors() Motors = {} if not Character then return end for _, desc in ipairs(Character:GetDescendants()) do if desc:IsA("Motor6D") then Motors[desc.Name] = { Motor = desc, OriginalC0 = desc.C0, } end end end local function SetupCharacter(char) Character = char Humanoid = char:WaitForChild("Humanoid") RootPart = char:WaitForChild("HumanoidRootPart") char:WaitForChild("Head") -- ensure loaded task.wait(0.1) CacheMotors() end if Player.Character then SetupCharacter(Player.Character) end Player.CharacterAdded:Connect(function(char) SetupCharacter(char) end) -- // STATE local State = { isWallRunning = false, wallSide = nil, wallTime = 0, wallCD = 0, isSliding = false, slideTime = 0, slideDir = Vector3.zero, slideCD = 0, isVaulting = false, vaultCD = 0, stamina = CFG.MaxStamina, sprinting = false, shiftHeld = false, spaceHeld = false, } ------------------------------------------------------------------------ -- MOTOR6D ANIMATION SYSTEM (client-side, no server APIs) ------------------------------------------------------------------------ local AnimTargets = {} -- {motorName = targetCFrame} local AnimAlpha = 0 local AnimSpeed = 8 local function ResetAnimTargets() AnimTargets = {} end -- Smoothly blend Motor6D C0 toward targets each frame local function UpdateMotorAnimation(dt) for name, data in pairs(Motors) do local target = AnimTargets[name] if target then data.Motor.C0 = data.Motor.C0:Lerp(data.OriginalC0 * target, math.min(dt * AnimSpeed, 1)) else -- Return to original data.Motor.C0 = data.Motor.C0:Lerp(data.OriginalC0, math.min(dt * AnimSpeed, 1)) end end end -- Pose presets local function SetWallRunPose(side, phase) local tilt = side == "Right" and -30 or 30 local legSwing = math.sin(phase * math.pi * 2) * 50 AnimTargets = { ["RootJoint"] = CFrame.Angles(0, 0, math.rad(tilt * 0.4)), ["Left Hip"] = CFrame.Angles(math.rad(-legSwing), 0, 0), ["Right Hip"] = CFrame.Angles(math.rad(legSwing), 0, 0), ["Left Shoulder"] = CFrame.Angles(math.rad(legSwing * 0.6), 0, math.rad(-10)), ["Right Shoulder"] = CFrame.Angles(math.rad(-legSwing * 0.6), 0, math.rad(10)), ["Neck"] = CFrame.Angles(math.rad(5), math.rad(side == "Right" and -15 or 15), 0), -- R15 equivalents ["Root"] = CFrame.Angles(0, 0, math.rad(tilt * 0.4)), ["LeftHip"] = CFrame.Angles(math.rad(-legSwing), 0, 0), ["RightHip"] = CFrame.Angles(math.rad(legSwing), 0, 0), ["LeftShoulder"] = CFrame.Angles(math.rad(legSwing * 0.6), 0, math.rad(-10)), ["RightShoulder"] = CFrame.Angles(math.rad(-legSwing * 0.6), 0, math.rad(10)), } AnimSpeed = 12 end local function SetSlidePose() AnimTargets = { -- R6 ["RootJoint"] = CFrame.Angles(math.rad(-15), 0, 0), ["Left Hip"] = CFrame.Angles(math.rad(60), 0, 0), ["Right Hip"] = CFrame.Angles(math.rad(10), 0, math.rad(8)), ["Left Shoulder"] = CFrame.Angles(math.rad(25), 0, math.rad(-30)), ["Right Shoulder"] = CFrame.Angles(math.rad(25), 0, math.rad(30)), ["Neck"] = CFrame.Angles(math.rad(15), 0, 0), -- R15 ["Root"] = CFrame.Angles(math.rad(-15), 0, 0), ["LeftHip"] = CFrame.Angles(math.rad(60), 0, 0), ["RightHip"] = CFrame.Angles(math.rad(10), 0, math.rad(8)), ["LeftShoulder"] = CFrame.Angles(math.rad(25), 0, math.rad(-30)), ["RightShoulder"] = CFrame.Angles(math.rad(25), 0, math.rad(30)), ["Waist"] = CFrame.Angles(math.rad(-25), 0, 0), } AnimSpeed = 14 end local function SetVaultPose(phase) local armAngle = phase < 0.5 and -110 or 40 local legAngle = phase < 0.5 and -35 or 45 local torsoAngle = phase < 0.5 and 12 or -18 AnimTargets = { -- R6 ["RootJoint"] = CFrame.Angles(math.rad(torsoAngle), 0, 0), ["Left Hip"] = CFrame.Angles(math.rad(legAngle), 0, 0), ["Right Hip"] = CFrame.Angles(math.rad(legAngle), 0, 0), ["Left Shoulder"] = CFrame.Angles(math.rad(armAngle), 0, math.rad(-12)), ["Right Shoulder"] = CFrame.Angles(math.rad(armAngle), 0, math.rad(12)), -- R15 ["Root"] = CFrame.Angles(math.rad(torsoAngle), 0, 0), ["LeftHip"] = CFrame.Angles(math.rad(legAngle), 0, 0), ["RightHip"] = CFrame.Angles(math.rad(legAngle), 0, 0), ["LeftShoulder"] = CFrame.Angles(math.rad(armAngle), 0, math.rad(-12)), ["RightShoulder"] = CFrame.Angles(math.rad(armAngle), 0, math.rad(12)), ["Waist"] = CFrame.Angles(math.rad(torsoAngle * 0.5), 0, 0), } AnimSpeed = 18 end ------------------------------------------------------------------------ -- RAYCAST HELPERS ------------------------------------------------------------------------ local RayParams = RaycastParams.new() RayParams.FilterType = Enum.RaycastFilterType.Exclude local function UpdateFilter() if Character then RayParams.FilterDescendantsInstances = {Character} end end local function Cast(origin, dir) UpdateFilter() return workspace:Raycast(origin, dir, RayParams) end local function CheckWall(side) if not RootPart or not RootPart.Parent then return nil end local dir = side == "Right" and RootPart.CFrame.RightVector or -RootPart.CFrame.RightVector local hit = Cast(RootPart.Position, dir * CFG.WallRunRayDist) if hit and hit.Instance and hit.Instance.CanCollide then local dot = math.abs(hit.Normal:Dot(Vector3.yAxis)) if dot < 0.3 then return hit end end return nil end local function CheckVault() if not RootPart or not RootPart.Parent then return nil, nil end local look = RootPart.CFrame.LookVector local waist = Cast(RootPart.Position + Vector3.new(0, -1, 0), look * CFG.VaultRayDist) if not waist or not waist.Instance or not waist.Instance.CanCollide then return nil, nil end local topOrigin = waist.Position + look * 1.5 + Vector3.new(0, CFG.VaultMaxHeight, 0) local top = Cast(topOrigin, Vector3.new(0, -CFG.VaultMaxHeight * 2, 0)) if top then local h = top.Position.Y - (RootPart.Position.Y - 3) if h >= CFG.VaultMinHeight and h <= CFG.VaultMaxHeight then return waist, top end end return nil, nil end local function IsGrounded() if not RootPart or not RootPart.Parent then return false end return Cast(RootPart.Position, Vector3.new(0, -3.5, 0)) ~= nil end local function MoveDir() if not Humanoid then return Vector3.zero end return Humanoid.MoveDirection end local function IsMoving() return MoveDir().Magnitude > 0.1 end ------------------------------------------------------------------------ -- HUD (Minecraft-style, blocky, Code font only) ------------------------------------------------------------------------ local function CreateHUD() local old = Player.PlayerGui:FindFirstChild("ParkourHUD") if old then old:Destroy() end local Gui = Instance.new("ScreenGui") Gui.Name = "ParkourHUD" Gui.ResetOnSpawn = false Gui.ZIndexBehavior = Enum.ZIndexBehavior.Sibling Gui.Parent = Player.PlayerGui -- Bottom bar container local Bar = Instance.new("Frame") Bar.Name = "Bar" Bar.Size = UDim2.new(0, 280, 0, 58) Bar.Position = UDim2.new(0.5, -140, 1, -82) Bar.BackgroundColor3 = Color3.fromRGB(28, 28, 28) Bar.BorderSizePixel = 0 Bar.Parent = Gui local stroke = Instance.new("UIStroke") stroke.Thickness = 3 stroke.Color = Color3.fromRGB(10, 10, 10) stroke.Parent = Bar -- Inner panel local Inner = Instance.new("Frame") Inner.Size = UDim2.new(1, -8, 1, -8) Inner.Position = UDim2.new(0, 4, 0, 4) Inner.BackgroundColor3 = Color3.fromRGB(42, 42, 42) Inner.BorderSizePixel = 0 Inner.Parent = Bar Instance.new("UIStroke", Inner).Color = Color3.fromRGB(55, 55, 55) -- Stamina text local sLabel = Instance.new("TextLabel") sLabel.Size = UDim2.new(0, 60, 0, 12) sLabel.Position = UDim2.new(0, 8, 0, 3) sLabel.BackgroundTransparency = 1 sLabel.Text = "STAMINA" sLabel.TextColor3 = Color3.fromRGB(170, 170, 170) sLabel.TextSize = 10 sLabel.Font = Enum.Font.Code sLabel.TextXAlignment = Enum.TextXAlignment.Left sLabel.Parent = Inner -- Stamina bar bg local sBG = Instance.new("Frame") sBG.Size = UDim2.new(1, -16, 0, 12) sBG.Position = UDim2.new(0, 8, 0, 16) sBG.BackgroundColor3 = Color3.fromRGB(18, 18, 18) sBG.BorderSizePixel = 0 sBG.Parent = Inner Instance.new("UIStroke", sBG).Color = Color3.fromRGB(8, 8, 8) -- Stamina fill local sFill = Instance.new("Frame") sFill.Name = "Fill" sFill.Size = UDim2.new(1, 0, 1, 0) sFill.BackgroundColor3 = Color3.fromRGB(50, 205, 50) sFill.BorderSizePixel = 0 sFill.Parent = sBG -- Shine local shine = Instance.new("Frame") shine.Size = UDim2.new(1, 0, 0.3, 0) shine.BackgroundColor3 = Color3.fromRGB(255, 255, 255) shine.BackgroundTransparency = 0.82 shine.BorderSizePixel = 0 shine.Parent = sFill -- Action label local aLabel = Instance.new("TextLabel") aLabel.Name = "Action" aLabel.Size = UDim2.new(1, -16, 0, 16) aLabel.Position = UDim2.new(0, 8, 0, 30) aLabel.BackgroundTransparency = 1 aLabel.Text = "[ IDLE ]" aLabel.TextColor3 = Color3.fromRGB(150, 150, 150) aLabel.TextSize = 12 aLabel.Font = Enum.Font.Code aLabel.Parent = Inner -- Crosshair local cross = Instance.new("TextLabel") cross.Size = UDim2.new(0, 20, 0, 20) cross.Position = UDim2.new(0.5, -10, 0.5, -10) cross.BackgroundTransparency = 1 cross.Text = "+" cross.TextColor3 = Color3.fromRGB(255, 255, 255) cross.TextSize = 20 cross.Font = Enum.Font.Code cross.TextStrokeTransparency = 0.4 cross.Parent = Gui -- Keybind hints local hints = Instance.new("Frame") hints.Size = UDim2.new(0, 210, 0, 70) hints.Position = UDim2.new(0, 10, 0, 10) hints.BackgroundColor3 = Color3.fromRGB(18, 8, 28) hints.BackgroundTransparency = 0.2 hints.BorderSizePixel = 0 hints.Parent = Gui local hs = Instance.new("UIStroke") hs.Color = Color3.fromRGB(75, 35, 115) hs.Thickness = 2 hs.Parent = hints local ht = Instance.new("TextLabel") ht.Size = UDim2.new(1, -10, 1, -6) ht.Position = UDim2.new(0, 5, 0, 3) ht.BackgroundTransparency = 1 ht.RichText = true ht.Text = '<font color="#FFFF55">[SHIFT]</font> Slide / Sprint\n<font color="#FFFF55">[SPACE]</font> Wall Run / Vault' ht.TextColor3 = Color3.fromRGB(190, 190, 190) ht.TextSize = 12 ht.Font = Enum.Font.Code ht.TextXAlignment = Enum.TextXAlignment.Left ht.TextYAlignment = Enum.TextYAlignment.Top ht.Parent = hints task.delay(6, function() pcall(function() TweenService:Create(hints, TweenInfo.new(1.5), {BackgroundTransparency = 1}):Play() TweenService:Create(hs, TweenInfo.new(1.5), {Transparency = 1}):Play() TweenService:Create(ht, TweenInfo.new(1.5), {TextTransparency = 1}):Play() end) end) return {Fill = sFill, Action = aLabel} end local HUD = CreateHUD() ------------------------------------------------------------------------ -- CAMERA TILT ------------------------------------------------------------------------ local camTiltCurrent = 0 local camTiltTarget = 0 ------------------------------------------------------------------------ -- WALL RUN ------------------------------------------------------------------------ local wrBV = nil local wrConn = nil local function StopWallRun() if not State.isWallRunning then return end State.isWallRunning = false State.wallCD = tick() if wrBV then pcall(function() wrBV:Destroy() end) wrBV = nil end if wrConn then wrConn:Disconnect() wrConn = nil end -- Wall jump boost if RootPart and RootPart.Parent then local bv = Instance.new("BodyVelocity") bv.MaxForce = Vector3.new(30000, 30000, 30000) bv.Velocity = RootPart.CFrame.LookVector * 16 + Vector3.new(0, 26, 0) bv.Parent = RootPart Debris:AddItem(bv, 0.15) end camTiltTarget = 0 ResetAnimTargets() end local function StartWallRun(side, wallHit) if State.isWallRunning or State.isSliding or State.isVaulting then return end if State.stamina < 8 then return end if tick() - State.wallCD < CFG.WallRunCooldown then return end State.isWallRunning = true State.wallSide = side State.wallTime = 0 local wallNormal = wallHit.Normal local wallFwd = wallNormal:Cross(Vector3.yAxis).Unit if RootPart.CFrame.LookVector:Dot(wallFwd) < 0 then wallFwd = -wallFwd end wrBV = Instance.new("BodyVelocity") wrBV.MaxForce = Vector3.new(50000, 50000, 50000) wrBV.P = 10000 wrBV.Parent = RootPart camTiltTarget = side == "Right" and CFG.WallRunCamTilt or -CFG.WallRunCamTilt local start = tick() local phase = 0 wrConn = RunService.Heartbeat:Connect(function(dt) if not State.isWallRunning then return end State.wallTime = tick() - start State.stamina = math.max(0, State.stamina - CFG.WallRunDrain * dt) local t = State.wallTime / CFG.WallRunDuration local up = CFG.WallRunSpeed * (1 - t * CFG.WallRunGravity * 2.5) local fwd = CFG.WallRunSpeed * (1 - t * 0.3) if wrBV and wrBV.Parent then wrBV.Velocity = wallFwd * fwd + Vector3.new(0, math.max(up, -12), 0) end -- Leg cycling animation phase = phase + dt * 4 SetWallRunPose(side, phase) local wall = CheckWall(side) if State.wallTime >= CFG.WallRunDuration or State.stamina <= 0 or not wall or (IsGrounded() and State.wallTime > 0.2) or not State.spaceHeld then StopWallRun() end end) end ------------------------------------------------------------------------ -- SLIDE ------------------------------------------------------------------------ local slBV = nil local slConn = nil local origHipHeight = nil local function StopSlide() if not State.isSliding then return end State.isSliding = false State.slideCD = tick() if slBV then pcall(function() slBV:Destroy() end) slBV = nil end if slConn then slConn:Disconnect() slConn = nil end if origHipHeight and Humanoid then Humanoid.HipHeight = origHipHeight origHipHeight = nil end camTiltTarget = 0 ResetAnimTargets() end local function StartSlide() if State.isSliding or State.isWallRunning or State.isVaulting then return end if not IsGrounded() or not IsMoving() then return end if State.stamina < CFG.SlideCost then return end if tick() - State.slideCD < CFG.SlideCooldown then return end local vel = RootPart.AssemblyLinearVelocity local hSpeed = Vector3.new(vel.X, 0, vel.Z).Magnitude if hSpeed < CFG.SlideMinSpeed then return end State.isSliding = true State.slideTime = 0 State.slideDir = MoveDir().Unit State.stamina = math.max(0, State.stamina - CFG.SlideCost) origHipHeight = Humanoid.HipHeight Humanoid.HipHeight = origHipHeight * 0.45 slBV = Instance.new("BodyVelocity") slBV.MaxForce = Vector3.new(40000, 0, 40000) slBV.P = 8000 slBV.Velocity = State.slideDir * CFG.SlideSpeed slBV.Parent = RootPart SetSlidePose() camTiltTarget = CFG.SlideCamTilt local start = tick() slConn = RunService.Heartbeat:Connect(function(dt) if not State.isSliding then return end State.slideTime = tick() - start if slBV and slBV.Parent then slBV.Velocity = slBV.Velocity * CFG.SlideFriction end if State.slideTime >= CFG.SlideDuration or not State.shiftHeld then StopSlide() end end) end ------------------------------------------------------------------------ -- VAULT ------------------------------------------------------------------------ local function StartVault() if State.isVaulting or State.isWallRunning or State.isSliding then return end if not IsMoving() then return end if State.stamina < CFG.VaultCost then return end if tick() - State.vaultCD < CFG.VaultCooldown then return end local _, topHit = CheckVault() if not topHit then return end State.isVaulting = true State.stamina = math.max(0, State.stamina - CFG.VaultCost) local startPos = RootPart.Position local topPos = topHit.Position + Vector3.new(0, 3.5, 0) local endPos = topPos + RootPart.CFrame.LookVector * 4 local bg = Instance.new("BodyGyro") bg.MaxTorque = Vector3.new(1e5, 1e5, 1e5) bg.CFrame = RootPart.CFrame bg.Parent = RootPart local bv = Instance.new("BodyVelocity") bv.MaxForce = Vector3.new(1e5, 1e5, 1e5) bv.P = 15000 bv.Parent = RootPart local elapsed = 0 local conn conn = RunService.Heartbeat:Connect(function(dt) if not State.isVaulting then if conn then conn:Disconnect() end return end elapsed = elapsed + dt local a = math.min(elapsed / CFG.VaultDuration, 1) SetVaultPose(a) -- Quadratic bezier local p0, p1, p2 = startPos, topPos + Vector3.new(0, 2, 0), endPos local pos = (1 - a)^2 * p0 + 2 * (1 - a) * a * p1 + a^2 * p2 if bv and bv.Parent and RootPart and RootPart.Parent then bv.Velocity = (pos - RootPart.Position) * 30 end if a >= 1 then State.isVaulting = false State.vaultCD = tick() pcall(function() bv:Destroy() end) pcall(function() bg:Destroy() end) ResetAnimTargets() conn:Disconnect() end end) end ------------------------------------------------------------------------ -- INPUT ------------------------------------------------------------------------ UserInputService.InputBegan:Connect(function(input, gpe) if gpe then return end if input.KeyCode == Enum.KeyCode.LeftShift then State.shiftHeld = true if IsMoving() and IsGrounded() then local vel = RootPart.AssemblyLinearVelocity local hSpeed = Vector3.new(vel.X, 0, vel.Z).Magnitude if hSpeed >= CFG.SlideMinSpeed then StartSlide() else State.sprinting = true if Humanoid then Humanoid.WalkSpeed = CFG.SprintSpeed end end else State.sprinting = true if Humanoid then Humanoid.WalkSpeed = CFG.SprintSpeed end end end if input.KeyCode == Enum.KeyCode.Space then State.spaceHeld = true if not IsGrounded() and not State.isWallRunning then local rWall = CheckWall("Right") local lWall = CheckWall("Left") if rWall and IsMoving() then StartWallRun("Right", rWall) elseif lWall and IsMoving() then StartWallRun("Left", lWall) end elseif IsGrounded() and IsMoving() then StartVault() end end end) UserInputService.InputEnded:Connect(function(input, gpe) if input.KeyCode == Enum.KeyCode.LeftShift then State.shiftHeld = false State.sprinting = false if not State.isSliding and not State.isWallRunning and Humanoid then Humanoid.WalkSpeed = CFG.WalkSpeed end end if input.KeyCode == Enum.KeyCode.Space then State.spaceHeld = false end end) ------------------------------------------------------------------------ -- MAIN LOOP ------------------------------------------------------------------------ RunService.RenderStepped:Connect(function(dt) if not Character or not Character.Parent then return end if not Humanoid or Humanoid.Health <= 0 then return end -- Stamina regen if not State.isWallRunning and not State.isSliding and not State.isVaulting then State.stamina = math.min(CFG.MaxStamina, State.stamina + CFG.StaminaRegen * dt) end -- Speed guard if not State.isSliding and not State.isWallRunning and not State.isVaulting then Humanoid.WalkSpeed = State.sprinting and CFG.SprintSpeed or CFG.WalkSpeed end -- Motor6D animation blending UpdateMotorAnimation(dt) -- HUD update pcall(function() local pct = State.stamina / CFG.MaxStamina HUD.Fill.Size = UDim2.new(math.max(pct, 0), 0, 1, 0) if pct > 0.5 then HUD.Fill.BackgroundColor3 = Color3.fromRGB(50, 205, 50) elseif pct > 0.25 then HUD.Fill.BackgroundColor3 = Color3.fromRGB(255, 200, 40) else HUD.Fill.BackgroundColor3 = Color3.fromRGB(220, 50, 50) end local txt, col = "[ IDLE ]", Color3.fromRGB(150, 150, 150) if State.isWallRunning then txt = ">> WALL RUN [" .. (State.wallSide or "?") .. "] <<" col = Color3.fromRGB(85, 255, 255) elseif State.isSliding then txt = ">> SLIDE <<" col = Color3.fromRGB(255, 170, 50) elseif State.isVaulting then txt = ">> VAULT <<" col = Color3.fromRGB(170, 85, 255) elseif State.sprinting and IsMoving() then txt = ">> SPRINT <<" col = Color3.fromRGB(255, 255, 85) elseif IsMoving() then txt = "[ MOVING ]" col = Color3.fromRGB(200, 200, 200) end HUD.Action.Text = txt HUD.Action.TextColor3 = col end) -- Camera tilt camTiltCurrent = camTiltCurrent + (camTiltTarget - camTiltCurrent) * math.min(dt * 10, 1) Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, math.rad(camTiltCurrent)) end) ------------------------------------------------------------------------ -- DEATH CLEANUP ------------------------------------------------------------------------ local function OnDeath() StopWallRun() StopSlide() State.isVaulting = false camTiltTarget = 0 ResetAnimTargets() end if Humanoid then Humanoid.Died:Connect(OnDeath) end Player.CharacterAdded:Connect(function(char) task.wait(0.5) if Humanoid then Humanoid.Died:Connect(OnDeath) end HUD = CreateHUD() end) print("[PARKOUR v3] Loaded! SHIFT=Slide/Sprint | SPACE=WallRun/Vault")
Editor Settings
Theme
Key bindings
Full width
Lines