local Players = game:GetService("Players") local RunService = game:GetService("RunService") local Debris = game:GetService("Debris") local Workspace = game:GetService("Workspace") local player = Players.LocalPlayer local playerGui = player:WaitForChild("PlayerGui") ------------------------------------------------ -- LIMPEZA ------------------------------------------------ local oldGui = playerGui:FindFirstChild("SpiderUI") if oldGui then oldGui:Destroy() end ------------------------------------------------ -- CONFIGURAÇÕES ------------------------------------------------ local SWING_ANIM = "rbxassetid://507767968" local SWING_SOUND = "rbxassetid://1284846268" local ZIP_SOUND = "rbxassetid://9084017080" -- ANIMAÇÃO DE ESCALADA R15 local CLIMB_ANIM = "rbxassetid://507765644" local swinging = false local swingStep = 1 local zipStep = 1 local climbing = false local climbEnabled = false local swingConn = nil local swingAnchor = nil local swingRope = nil local swingTrack = nil local climbConn = nil local climbTrack = nil local climbVelocity = nil local climbAlign = nil local climbAttachment = nil local webs = {} local ikList = {} local gripAtt = nil ------------------------------------------------ -- PERSONAGEM ------------------------------------------------ local function getParts() local char = player.Character or player.CharacterAdded:Wait() local hrp = char:WaitForChild("HumanoidRootPart") local hum = char:WaitForChild("Humanoid") return char, hrp, hum end local function applyJump(char) local hum = char:WaitForChild("Humanoid") hum.UseJumpPower = true hum.JumpPower = 100 end if player.Character then task.spawn(applyJump, player.Character) end player.CharacterAdded:Connect(function(char) task.wait(0.5) applyJump(char) end) ------------------------------------------------ -- ANIMAÇÃO ------------------------------------------------ local function getAnimator(hum) local animator = hum:FindFirstChildOfClass("Animator") if not animator then animator = Instance.new("Animator") animator.Parent = hum end return animator end ------------------------------------------------ -- MÃOS ------------------------------------------------ local function getHand(char, side) if side == "Right" then return char:FindFirstChild("RightHand") or char:FindFirstChild("Right Arm") end return char:FindFirstChild("LeftHand") or char:FindFirstChild("Left Arm") end ------------------------------------------------ -- BRAÇOS ------------------------------------------------ local function getArmRoot(char, side) if side == "Right" then return char:FindFirstChild("RightUpperArm") or char:FindFirstChild("Right Arm") or char:FindFirstChild("UpperTorso") end return char:FindFirstChild("LeftUpperArm") or char:FindFirstChild("Left Arm") or char:FindFirstChild("UpperTorso") end ------------------------------------------------ -- LIMPAR TEIAS ------------------------------------------------ local function clearWebs() for _, obj in ipairs(webs) do if obj and obj.Parent then obj:Destroy() end end table.clear(webs) end ------------------------------------------------ -- LIMPAR IK ------------------------------------------------ local function clearIK() for _, ik in ipairs(ikList) do if ik and ik.Parent then ik:Destroy() end end table.clear(ikList) end ------------------------------------------------ -- SOM ------------------------------------------------ local function playSound(hrp, id) local sound = Instance.new("Sound") sound.SoundId = id sound.Volume = 2 sound.Parent = hrp sound:Play() Debris:AddItem(sound, 3) end ------------------------------------------------ -- CRIAR TEIA ------------------------------------------------ local function addWebFromHand(char, targetAtt, side) local hand = getHand(char, side) if not hand or not targetAtt then return end local handAtt = Instance.new("Attachment") handAtt.Name = "WebHandAttachment" handAtt.Parent = hand local beam = Instance.new("Beam") beam.Attachment0 = targetAtt beam.Attachment1 = handAtt beam.Width0 = 0.18 beam.Width1 = 0.10 beam.Color = ColorSequence.new( Color3.fromRGB(255,255,255) ) beam.LightEmission = 1 beam.FaceCamera = true beam.Parent = hand table.insert(webs, beam) table.insert(webs, handAtt) end ------------------------------------------------ -- IK DO BRAÇO ------------------------------------------------ local function attachArm(char, hum, side, targetAtt) local hand = getHand(char, side) local root = getArmRoot(char, side) if not hand or not root or not targetAtt then return end local ik = Instance.new("IKControl") ik.Name = "WebArmIK_" .. side ik.Type = Enum.IKControlType.Position ik.EndEffector = hand ik.ChainRoot = root ik.Target = targetAtt ik.Weight = 1 ik.SmoothTime = 0.08 ik.Parent = hum table.insert(ikList, ik) end ------------------------------------------------ -- UI ------------------------------------------------ local gui = Instance.new("ScreenGui") gui.Name = "SpiderUI" gui.ResetOnSpawn = false gui.IgnoreGuiInset = true gui.Parent = playerGui ------------------------------------------------ -- BOTÃO DE ESCALAR ------------------------------------------------ local btnClimb = Instance.new("ImageButton") btnClimb.Name = "BtnClimb" btnClimb.Size = UDim2.fromOffset(75,75) btnClimb.Position = UDim2.new( 0.68, 0, 0.57, 0 ) btnClimb.BackgroundColor3 = Color3.fromRGB(190,25,25) btnClimb.Image = "rbxassetid://76038791676557" btnClimb.ScaleType = Enum.ScaleType.Fit btnClimb.Parent = gui local climbCorner = Instance.new("UICorner") climbCorner.CornerRadius = UDim.new(1,0) climbCorner.Parent = btnClimb local climbStroke = Instance.new("UIStroke") climbStroke.Color = Color3.fromRGB(0,110,255) climbStroke.Thickness = 4 climbStroke.Parent = btnClimb ------------------------------------------------ -- BOTÃO BALANÇO ------------------------------------------------ local btnSwing = Instance.new("ImageButton") btnSwing.Name = "BtnSwing" btnSwing.Size = UDim2.fromOffset(75,75) btnSwing.Position = UDim2.new( 0.68, 0, 0.78, 0 ) btnSwing.BackgroundColor3 = Color3.fromRGB(190,25,25) btnSwing.Image = "rbxassetid://124599639623520" btnSwing.ScaleType = Enum.ScaleType.Fit btnSwing.Parent = gui local corner = Instance.new("UICorner") corner.CornerRadius = UDim.new(1,0) corner.Parent = btnSwing local swingStroke = Instance.new("UIStroke") swingStroke.Color = Color3.fromRGB(0,110,255) swingStroke.Thickness = 4 swingStroke.Parent = btnSwing ------------------------------------------------ -- BOTÃO WEB ZIP ------------------------------------------------ local btnZip = Instance.new("ImageButton") btnZip.Name = "BtnZip" btnZip.Size = UDim2.fromOffset(75,75) btnZip.Position = UDim2.new(0.79,0,0.63,0) btnZip.BackgroundColor3 = Color3.fromRGB(190,25,25) btnZip.Image = "rbxassetid://87791451477905" btnZip.ScaleType = Enum.ScaleType.Fit btnZip.Parent = gui local zipCorner = Instance.new("UICorner") zipCorner.CornerRadius = UDim.new(1,0) zipCorner.Parent = btnZip local zipStroke = Instance.new("UIStroke") zipStroke.Color = Color3.fromRGB(0,110,255) zipStroke.Thickness = 4 zipStroke.Parent = btnZip ------------------------------------------------ -- DETECTAR PAREDE ------------------------------------------------ local function getWall() local char, hrp = getParts() local params = RaycastParams.new() params.FilterType = Enum.RaycastFilterType.Exclude params.FilterDescendantsInstances = {char} params.IgnoreWater = true local directions = { hrp.CFrame.LookVector, -hrp.CFrame.LookVector, hrp.CFrame.RightVector, -hrp.CFrame.RightVector } local closestResult = nil local closestDistance = math.huge for _, direction in ipairs(directions) do local result = Workspace:Raycast( hrp.Position, direction * 3.5, params ) if result then local distance = (result.Position - hrp.Position).Magnitude if distance < closestDistance then closestDistance = distance closestResult = result end end end return closestResult end ------------------------------------------------ -- PARAR ESCALADA ------------------------------------------------ local function stopClimb() if not climbing then return end climbing = false if climbConn then climbConn:Disconnect() climbConn = nil end if climbTrack then if climbTrack.IsPlaying then climbTrack:Stop(0.15) end climbTrack = nil end if climbVelocity then climbVelocity:Destroy() climbVelocity = nil end if climbAlign then climbAlign:Destroy() climbAlign = nil end if climbAttachment then climbAttachment:Destroy() climbAttachment = nil end local char, hrp, hum = getParts() hum.AutoRotate = true hum.PlatformStand = false hrp.AssemblyLinearVelocity = Vector3.zero end ------------------------------------------------ -- COMEÇAR ESCALADA ------------------------------------------------ local function startClimb() if climbing or not climbEnabled then return end local char, hrp, hum = getParts() local wall = getWall() if not wall then return end climbing = true hum.AutoRotate = false hum.PlatformStand = false ------------------------------------------------ -- ANIMAÇÃO DE ESCALADA R15 ------------------------------------------------ local animator = getAnimator(hum) local anim = Instance.new("Animation") anim.AnimationId = CLIMB_ANIM climbTrack = animator:LoadAnimation(anim) climbTrack.Priority = Enum.AnimationPriority.Action4 climbTrack.Looped = true climbTrack:Play(0.1) -- FORÇA O HUMANOID PARA O ESTADO DE ESCALADA hum:ChangeState(Enum.HumanoidStateType.Climbing) ------------------------------------------------ -- CONTROLE DE VELOCIDADE ------------------------------------------------ climbAttachment = Instance.new("Attachment") climbAttachment.Name = "SpiderClimbAttachment" climbAttachment.Parent = hrp climbVelocity = Instance.new("LinearVelocity") climbVelocity.Name = "SpiderClimbVelocity" climbVelocity.MaxForce = math.huge climbVelocity.RelativeTo = Enum.ActuatorRelativeTo.World climbVelocity.VectorVelocity = Vector3.zero climbVelocity.Attachment0 = climbAttachment climbVelocity.Parent = hrp ------------------------------------------------ -- ORIENTAÇÃO ------------------------------------------------ climbAlign = Instance.new("AlignOrientation") climbAlign.Name = "SpiderClimbOrientation" climbAlign.Mode = Enum.OrientationAlignmentMode.OneAttachment climbAlign.MaxTorque = math.huge climbAlign.Responsiveness = 25 climbAlign.RigidityEnabled = false climbAlign.Attachment0 = climbAttachment climbAlign.Parent = hrp ------------------------------------------------ -- CONTROLE ------------------------------------------------ climbConn = RunService.RenderStepped:Connect(function() if not climbing then return end if not hrp.Parent then stopClimb() return end local currentWall = getWall() if not currentWall then stopClimb() return end local normal = currentWall.Normal ------------------------------------------------ -- CÂMERA ------------------------------------------------ local camera = Workspace.CurrentCamera local cameraForward = camera.CFrame.LookVector local cameraRight = camera.CFrame.RightVector ------------------------------------------------ -- MOVIMENTO DO JOYSTICK ------------------------------------------------ local move = hum.MoveDirection local horizontal = Vector3.new( move.X, 0, move.Z ) local vertical = 0 if horizontal.Magnitude > 0.05 then local forwardAmount = horizontal:Dot(cameraForward) vertical = forwardAmount end ------------------------------------------------ -- MOVIMENTO NA PAREDE ------------------------------------------------ local up = Vector3.new(0,1,0) local wallRight = cameraRight wallRight = wallRight - normal * wallRight:Dot(normal) if wallRight.Magnitude > 0.01 then wallRight = wallRight.Unit end local climbUp = up * vertical * 8 local climbSide = wallRight * move:Dot(wallRight) * 8 local velocity = climbUp + climbSide ------------------------------------------------ -- MANTER NO PAREDÃO ------------------------------------------------ velocity += -normal * 3 climbVelocity.VectorVelocity = velocity ------------------------------------------------ -- VIRAR PARA A PAREDE ------------------------------------------------ local facing = -normal local look = Vector3.new( facing.X, 0, facing.Z ) if look.Magnitude > 0.01 then climbAlign.CFrame = CFrame.lookAt( Vector3.zero, look.Unit ) end ------------------------------------------------ -- MANTER ESTADO DE ESCALADA ------------------------------------------------ if hum:GetState() ~= Enum.HumanoidStateType.Climbing then hum:ChangeState(Enum.HumanoidStateType.Climbing) end end) end ------------------------------------------------ -- BOTÃO DE ESCALADA ------------------------------------------------ btnClimb.MouseButton1Down:Connect(function() climbEnabled = not climbEnabled if climbEnabled then local wall = getWall() if wall then startClimb() end else stopClimb() end end) ------------------------------------------------ -- PARAR BALANÇO ------------------------------------------------ local function stopSwing() if not swinging then return end swinging = false if swingConn then swingConn:Disconnect() swingConn = nil end if swingTrack then if swingTrack.IsPlaying then swingTrack:Stop(0.2) end end clearIK() clearWebs() local char, hrp, hum = getParts() hum.PlatformStand = false hum.JumpPower = 100 if swingRope then swingRope:Destroy() swingRope = nil end if swingAnchor then swingAnchor:Destroy() swingAnchor = nil end gripAtt = nil swingStep += 1 if swingStep > 3 then swingStep = 1 end end ------------------------------------------------ -- COMEÇAR BALANÇO ------------------------------------------------ local function startSwing() if swinging then return end swinging = true local char, hrp, hum = getParts() hum.PlatformStand = true local animator = getAnimator(hum) if not swingTrack then local anim = Instance.new("Animation") anim.AnimationId = SWING_ANIM swingTrack = animator:LoadAnimation(anim) swingTrack.Priority = Enum.AnimationPriority.Action swingTrack.Looped = true end swingTrack:Play(0.15) playSound(hrp, SWING_SOUND) ------------------------------------------------ -- PONTO DA TEIA ------------------------------------------------ swingAnchor = Instance.new("Part") swingAnchor.Name = "WebAnchor" swingAnchor.Anchored = true swingAnchor.CanCollide = false swingAnchor.Transparency = 1 swingAnchor.Size = Vector3.new(0.2,0.2,0.2) swingAnchor.Position = hrp.Position + hrp.CFrame.LookVector * 36 + Vector3.new(0,13,0) swingAnchor.Parent = Workspace local a0 = Instance.new("Attachment") a0.Parent = swingAnchor local a1 = Instance.new("Attachment") a1.Parent = hrp swingRope = Instance.new("RopeConstraint") swingRope.Attachment0 = a0 swingRope.Attachment1 = a1 swingRope.Length = (swingAnchor.Position - hrp.Position).Magnitude swingRope.Visible = false swingRope.Parent = hrp if swingStep == 1 then addWebFromHand(char,a0,"Right") attachArm(char,hum,"Right",a0) elseif swingStep == 2 then addWebFromHand(char,a0,"Left") attachArm(char,hum,"Left",a0) else addWebFromHand(char,a0,"Right") addWebFromHand(char,a0,"Left") attachArm(char,hum,"Right",a0) attachArm(char,hum,"Left",a0) end hrp.AssemblyLinearVelocity += hrp.CFrame.LookVector * 48 swingConn = RunService.Heartbeat:Connect(function() if not swinging then return end if not hrp.Parent or not swingAnchor.Parent then return end local offset = swingAnchor.Position - hrp.Position if offset.Magnitude < 0.1 then return end local dir = offset.Unit local vel = hrp.AssemblyLinearVelocity local radial = dir * vel:Dot(dir) hrp.AssemblyLinearVelocity = (vel - radial) + Vector3.new( 0, -Workspace.Gravity * 0.03, 0 ) end) end ------------------------------------------------ -- WEB ZIP ------------------------------------------------ btnZip.MouseButton1Down:Connect(function() stopSwing() local char, hrp, hum = getParts() local sides if zipStep == 1 then sides = {"Right"} elseif zipStep == 2 then sides = {"Left"} else sides = {"Right","Left"} end local tip = Instance.new("Part") tip.Name = "WebZipTarget" tip.Anchored = true tip.CanCollide = false tip.Transparency = 1 tip.Size = Vector3.new(0.2,0.2,0.2) tip.Position = hrp.Position + hrp.CFrame.LookVector * 34 + Vector3.new(0,12,0) tip.Parent = Workspace local tipAtt = Instance.new("Attachment") tipAtt.Parent = tip for _, side in ipairs(sides) do addWebFromHand( char, tipAtt, side ) attachArm( char, hum, side, tipAtt ) end playSound(hrp, ZIP_SOUND) local push = Instance.new("BodyVelocity") push.MaxForce = Vector3.new( 1e7, 1e7, 1e7 ) push.Velocity = hrp.CFrame.LookVector * 120 + Vector3.new(0,55,0) push.Parent = hrp Debris:AddItem(tip,0.32) Debris:AddItem(push,0.28) task.delay(0.32,function() clearWebs() clearIK() end) zipStep += 1 if zipStep > 3 then zipStep = 1 end end) ------------------------------------------------ -- CONTROLES ------------------------------------------------ btnSwing.MouseButton1Down:Connect( startSwing ) btnSwing.MouseButton1Up:Connect( stopSwing ) btnSwing.MouseLeave:Connect( stopSwing ) ------------------------------------------------ -- RESPAWN ------------------------------------------------ player.CharacterAdded:Connect(function() if swinging then stopSwing() end if climbing then stopClimb() end climbEnabled = false swingStep = 1 zipStep = 1 end) print("🕷️ Spider-Man Web System + Wall Climb carregado!")