local Players = game:GetService("Players") local Workspace = game:GetService("Workspace") local Debris = game:GetService("Debris") local LocalPlayer = Players.LocalPlayer local WEAPON_ASSET_ID = 136461991241487 -- ID da Arma 3D local PORTAL_ASSET_ID = 12205993987 -- ID do Portal 3D local TOOL_ICON_ID = 108295273868319 -- ID da Imagem do Ícone da Tool local TOOL_NAME = "Portal Gun" -- Ajustes de Posição e Rotação da Arma na Mão local POSITION_OFFSET = Vector3.new(0, -0.2, -1) local ROTATION_OFFSET = CFrame.Angles(math.rad(180), math.rad(90), math.rad(0)) -- Controle de Estado local cliqueCount = 0 local portal1 = nil local portal2 = nil local cooldownTeleport = false local executandoDisparo = false -- Remove peso e colisão do modelo local function ajustarFisicaDaPart(part) if part:IsA("BasePart") then part.Anchored = false part.CanCollide = false part.CanTouch = false part.CanQuery = false part.Massless = true part.CustomPhysicalProperties = PhysicalProperties.new(0.001, 0, 0, 0, 0) end end -- Solda as partes do modelo para não caírem local function soldarModeloEPreparar(instancia) local parts = {} if instancia:IsA("BasePart") then table.insert(parts, instancia) ajustarFisicaDaPart(instancia) end for _, child in ipairs(instancia:GetDescendants()) do if child:IsA("BasePart") then table.insert(parts, child) ajustarFisicaDaPart(child) end end if #parts > 1 then local mainPart = parts[1] for i = 2, #parts do local weld = Instance.new("WeldConstraint") weld.Part0 = mainPart weld.Part1 = parts[i] weld.Parent = mainPart end end end -- Carrega o Portal 3D local function carregarModeloPortal(cframeTarget) local success, result = pcall(function() return game:GetObjects("rbxassetid://" .. PORTAL_ASSET_ID)[1] end) local portalObj = nil if success and result then portalObj = result else portalObj = Instance.new("Part") portalObj.Size = Vector3.new(4, 7, 0.5) portalObj.Color = Color3.fromRGB(0, 150, 255) portalObj.Material = Enum.Material.Neon end if portalObj:IsA("Model") then portalObj:PivotTo(cframeTarget) for _, child in ipairs(portalObj:GetDescendants()) do if child:IsA("BasePart") then child.Anchored = true child.CanCollide = false end end elseif portalObj:IsA("BasePart") then portalObj.CFrame = cframeTarget portalObj.Anchored = true portalObj.CanCollide = false end portalObj.Parent = Workspace return portalObj end local function getPortalCFrame(portal) if not portal then return nil end if portal:IsA("Model") then return portal:GetPivot() elseif portal:IsA("BasePart") then return portal.CFrame end return nil end -- Configuração do Teletransporte entre os 2 Portais local function configurarGatilhosDeTeleport() if not portal1 or not portal2 then return end local function aplicarGatilho(portalOrigem, obterPortalDestino) local partsTarget = {} if portalOrigem:IsA("BasePart") then table.insert(partsTarget, portalOrigem) else for _, v in ipairs(portalOrigem:GetDescendants()) do if v:IsA("BasePart") then table.insert(partsTarget, v) end end end for _, part in ipairs(partsTarget) do part.Touched:Connect(function(hit) if cooldownTeleport then return end local char = hit.Parent local hrp = char:FindFirstChild("HumanoidRootPart") if hrp and char == LocalPlayer.Character then local destPortal = obterPortalDestino() if destPortal then local destCFrame = getPortalCFrame(destPortal) if destCFrame then cooldownTeleport = true -- Teleporta para fora da superfície do portal de saída hrp.CFrame = destCFrame * CFrame.new(0, 0, -3) -- Tempo de recarga de 1 segundo task.wait(1) cooldownTeleport = false end end end end) end end aplicarGatilho(portal1, function() return portal2 end) aplicarGatilho(portal2, function() return portal1 end) end -- Disparo da Bola Preta local function dispararBolaPreta(etapa) local char = LocalPlayer.Character if not char or not char:FindFirstChild("HumanoidRootPart") then executandoDisparo = false return end local mouse = LocalPlayer:GetMouse() local targetPos = mouse.Hit and mouse.Hit.Position or (char.HumanoidRootPart.CFrame * CFrame.new(0, 0, -50)).Position local startPos = char.HumanoidRootPart.Position + Vector3.new(0, 1.5, 0) local direction = (targetPos - startPos).Unit local bola = Instance.new("Part") bola.Shape = Enum.PartType.Ball bola.Size = Vector3.new(1.5, 1.5, 1.5) bola.Color = Color3.fromRGB(15, 15, 15) bola.Material = Enum.Material.SmoothPlastic bola.CanCollide = false bola.Anchored = false bola.CFrame = CFrame.new(startPos, startPos + direction) local bv = Instance.new("BodyVelocity") bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge) bv.Velocity = direction * 150 bv.Parent = bola bola.Parent = Workspace Debris:AddItem(bola, 4) local conect conect = game:GetService("RunService").Heartbeat:Connect(function() if not bola or not bola.Parent then conect:Disconnect() executandoDisparo = false return end local raycastParams = RaycastParams.new() raycastParams.FilterDescendantsInstances = {char, bola} raycastParams.FilterType = Enum.RaycastFilterType.Exclude local result = Workspace:Raycast(bola.Position, direction * 3, raycastParams) if result then conect:Disconnect() local hitCFrame = CFrame.new(result.Position, result.Position + result.Normal) bola:Destroy() if etapa == 1 then if portal1 then portal1:Destroy() end portal1 = carregarModeloPortal(hitCFrame) elseif etapa == 2 then if portal2 then portal2:Destroy() end portal2 = carregarModeloPortal(hitCFrame) configurarGatilhosDeTeleport() end executandoDisparo = false end end) end -- Processador da Ação local function processarClique() if executandoDisparo then return end cliqueCount = cliqueCount + 1 if cliqueCount == 1 then executandoDisparo = true dispararBolaPreta(1) elseif cliqueCount == 2 then executandoDisparo = true dispararBolaPreta(2) elseif cliqueCount >= 3 then -- No 3º clique destrói ambos os portais if portal1 then portal1:Destroy() portal1 = nil end if portal2 then portal2:Destroy() portal2 = nil end cliqueCount = 0 end end -- Criador da Tool Única com Imagem local function criarPortalGun() local backpack = LocalPlayer:WaitForChild("Backpack") local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait() -- Limpa ferramentas repetidas da mochila/personagem for _, item in ipairs(backpack:GetChildren()) do if item.Name == TOOL_NAME or item.Name == "gun" or item.Name == "Gun" then item:Destroy() end end for _, item in ipairs(character:GetChildren()) do if item.Name == TOOL_NAME or item.Name == "gun" or item.Name == "Gun" then item:Destroy() end end local tool = Instance.new("Tool") tool.Name = TOOL_NAME tool.TextureId = "rbxassetid://" .. tostring(TOOL_ICON_ID) -- Aplica a imagem no ícone tool.RequiresHandle = true local handle = Instance.new("Part") handle.Name = "Handle" handle.Size = Vector3.new(0.2, 0.2, 0.2) handle.Transparency = 1 ajustarFisicaDaPart(handle) handle.Parent = tool tool.Parent = backpack local modelo3D = nil -- Ao Equipar tool.Equipped:Connect(function() local char = LocalPlayer.Character if not char then return end local success, result = pcall(function() return game:GetObjects("rbxassetid://" .. WEAPON_ASSET_ID)[1] end) if success and result then if result:IsA("Tool") then local visualContainer = Instance.new("Model") visualContainer.Name = "VisualModel" for _, child in ipairs(result:GetChildren()) do if child:IsA("BasePart") or child:IsA("Model") or child:IsA("Accessory") then child.Parent = visualContainer end end result:Destroy() modelo3D = visualContainer else modelo3D = result end soldarModeloEPreparar(modelo3D) local rightHand = char:FindFirstChild("RightHand") or char:FindFirstChild("Right Arm") if rightHand then local offsetCFrame = CFrame.new(POSITION_OFFSET) * ROTATION_OFFSET local mainPart = modelo3D:IsA("Model") and (modelo3D.PrimaryPart or modelo3D:FindFirstChildWhichIsA("BasePart")) or modelo3D if mainPart then if modelo3D:IsA("Model") then modelo3D:PivotTo(rightHand.CFrame * offsetCFrame) else mainPart.CFrame = rightHand.CFrame * offsetCFrame end local weldToHand = Instance.new("WeldConstraint") weldToHand.Part0 = rightHand weldToHand.Part1 = mainPart weldToHand.Parent = mainPart end end modelo3D.Parent = char end end) -- Ao Clicar / Usar a Tool tool.Activated:Connect(function() processarClique() end) -- Ao Desequipar tool.Unequipped:Connect(function() if modelo3D then modelo3D:Destroy() modelo3D = nil end end) end criarPortalGun()