-- ================= SERVIÇOS ================= local Players = game:GetService("Players") local RunService = game:GetService("RunService") local player = Players.LocalPlayer local cam = workspace.CurrentCamera -- ================= CONFIG ================= local MAX_SIZE = 25 local ADJUST_STEP = 2 local syncedLength = 10 -- ================= VARIÁVEIS ================= local hoveredPart local selectedPart local ropeStack = {} local linkMode = "Player" local firstObject local firstHighlight -- ================= HRP ================= local function getHRP() local char = player.Character if char then return char:FindFirstChild("HumanoidRootPart") end end -- ================= GUI ================= local gui = Instance.new("ScreenGui") gui.Parent = player.PlayerGui gui.ResetOnSpawn = false -- botão abrir/fechar (canto esquerdo) local toggleBtn = Instance.new("TextButton", gui) toggleBtn.Size = UDim2.fromScale(0.05,0.08) toggleBtn.Position = UDim2.fromScale(0.01,0.45) toggleBtn.Text = "≡" toggleBtn.TextScaled = true toggleBtn.BackgroundColor3 = Color3.fromRGB(30,30,30) toggleBtn.TextColor3 = Color3.new(1,1,1) toggleBtn.BorderSizePixel = 0 -- frame principal local frame = Instance.new("Frame", gui) frame.Size = UDim2.fromScale(0.18,0.5) frame.Position = UDim2.fromScale(0.8,0.3) frame.BackgroundColor3 = Color3.fromRGB(25,25,25) frame.BorderSizePixel = 0 frame.Visible = true -- mover GUI local dragging, dragStart, startPos frame.InputBegan:Connect(function(i) if i.UserInputType == Enum.UserInputType.MouseButton1 then dragging = true dragStart = i.Position startPos = frame.Position i.Changed:Connect(function() if i.UserInputState == Enum.UserInputState.End then dragging = false end end) end end) frame.InputChanged:Connect(function(i) if dragging and i.UserInputType == Enum.UserInputType.MouseMovement then local d = i.Position - dragStart frame.Position = UDim2.new( startPos.X.Scale, startPos.X.Offset + d.X, startPos.Y.Scale, startPos.Y.Offset + d.Y ) end end) -- ================= BOTÕES ================= local function mkBtn(t,y) local b = Instance.new("TextButton", frame) b.Size = UDim2.fromScale(0.9,0.13) b.Position = UDim2.fromScale(0.05,y) b.Text = t b.TextScaled = true b.BackgroundColor3 = Color3.fromRGB(45,45,45) b.TextColor3 = Color3.new(1,1,1) return b end local btnSelect = mkBtn("Selecionar",0.05) local btnRope = mkBtn("Criar Corda",0.2) local btnCut = mkBtn("Cortar Corda",0.35) local btnObj = mkBtn("Objeto ↔ Objeto",0.5) local btnPlus = mkBtn("+",0.65) local btnMinus = mkBtn("-",0.8) -- ================= HIGHLIGHT ================= local highlight = Instance.new("Highlight", gui) highlight.FillColor = Color3.fromRGB(0,255,255) highlight.OutlineColor = highlight.FillColor highlight.FillTransparency = 0.3 -- ================= VALIDAR ================= local function validPart(p) if not p or not p:IsA("BasePart") then return false end if p:IsDescendantOf(player.Character) then return false end if p.Anchored then return false end if p.Size.Magnitude > MAX_SIZE then return false end return true end -- ================= DETECÇÃO ================= RunService.RenderStepped:Connect(function() local ray = cam:ViewportPointToRay(cam.ViewportSize.X/2, cam.ViewportSize.Y/2) local params = RaycastParams.new() params.FilterDescendantsInstances = {player.Character} params.FilterType = Enum.RaycastFilterType.Blacklist local r = workspace:Raycast(ray.Origin, ray.Direction*60, params) if r and validPart(r.Instance) then hoveredPart = r.Instance highlight.Adornee = hoveredPart highlight.Enabled = true else hoveredPart = nil highlight.Enabled = false end end) -- ================= SELECIONAR ================= btnSelect.MouseButton1Click:Connect(function() if not hoveredPart then return end if linkMode == "Player" then selectedPart = hoveredPart else if not firstObject then firstObject = hoveredPart firstHighlight = Instance.new("Highlight", gui) firstHighlight.Adornee = firstObject firstHighlight.FillColor = Color3.fromRGB(0,0,255) firstHighlight.OutlineColor = firstHighlight.FillColor else local a1 = Instance.new("Attachment", firstObject) local a2 = Instance.new("Attachment", hoveredPart) local rope = Instance.new("RopeConstraint") rope.Attachment0 = a1 rope.Attachment1 = a2 rope.Length = syncedLength rope.Visible = true rope.Parent = firstObject table.insert(ropeStack,{rope=rope,att1=a1,att2=a2}) firstHighlight:Destroy() firstHighlight = nil firstObject = nil linkMode = "Player" end end end) -- ================= CRIAR CORDA (JOGADOR) ================= btnRope.MouseButton1Click:Connect(function() local hrp = getHRP() if not hrp or not selectedPart then return end local a1 = Instance.new("Attachment", hrp) local a2 = Instance.new("Attachment", selectedPart) local rope = Instance.new("RopeConstraint") rope.Attachment0 = a1 rope.Attachment1 = a2 rope.Length = syncedLength rope.Visible = true rope.Parent = hrp table.insert(ropeStack,{rope=rope,att1=a1,att2=a2}) end) -- ================= CORTAR ÚLTIMA ================= btnCut.MouseButton1Click:Connect(function() local last = table.remove(ropeStack) if last then last.rope:Destroy() last.att1:Destroy() last.att2:Destroy() end end) -- ================= MODO OBJETO ================= btnObj.MouseButton1Click:Connect(function() linkMode = "Object" firstObject = nil if firstHighlight then firstHighlight:Destroy() firstHighlight = nil end end) -- ================= SINCRONIZAÇÃO GLOBAL ================= local function syncAll() for _,r in ipairs(ropeStack) do r.rope.Length = syncedLength end end btnPlus.MouseButton1Click:Connect(function() syncedLength += ADJUST_STEP syncAll() end) btnMinus.MouseButton1Click:Connect(function() syncedLength = math.max(1, syncedLength - ADJUST_STEP) syncAll() end) -- ================= ABRIR / FECHAR GUI ================= toggleBtn.MouseButton1Click:Connect(function() frame.Visible = not frame.Visible end)