
KeylessUniversal

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 = 2160656233 -- ID do Portal 3D
local TOOL_ICON_ID = 120404128273122 -- Novo ID da Imagem do Ícone no Inventário
local TOOL_NAME = "Portal Gun"
-- Nomes Atualizados dos Portais
local NOME_PORTAL_1 = "Porta9202837"
local NOME_PORTAL_2 = "portal81738380"
-- 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
-- Interface do Canto Inferior Direito
local function mostrarNotificacaoDireita()
local pGui = LocalPlayer:WaitForChild("PlayerGui")
local sg = pGui:FindFirstChild("PortalGunNotif") or Instance.new("ScreenGui")
sg.Name = "PortalGunNotif"
sg.ResetOnSpawn = false
sg.Parent = pGui
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 200, 0, 40)
frame.Position = UDim2.new(1, -210, 1, -50)
frame.BackgroundColor3 = Color3.fromRGB(25, 25, 25)
frame.BorderSizePixel = 0
frame.Parent = sg
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 8)
corner.Parent = frame
local label = Instance.new("TextLabel")
label.Size = UDim2.new(1, 0, 1, 0)
label.BackgroundTransparency = 1
label.Text = "Portal gun 1.2 Carregado"
label.TextColor3 = Color3.fromRGB(255, 255, 255)
label.TextSize = 14
label.Font = Enum.Font.SourceSansBold
label.Parent = frame
task.delay(4, function()
if sg then sg:Destroy() end
end)
end
-- Ajuste físico do modelo da arma
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 o modelo da arma
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 e limpa scripts internos
local function carregarModeloPortal(cframeTarget, nomePortal)
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(150, 0, 255)
portalObj.Material = Enum.Material.Neon
end
portalObj.Name = nomePortal
-- Apaga scripts, avisos e prompts nativos do asset
for _, child in ipairs(portalObj:GetDescendants()) do
if child:IsA("ProximityPrompt") or child:IsA("BillboardGui") or child:IsA("SurfaceGui") or child:IsA("Script") or child:IsA("LocalScript") then
child:Destroy()
end
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
child.CanTouch = true
end
end
elseif portalObj:IsA("BasePart") then
portalObj.CFrame = cframeTarget
portalObj.Anchored = true
portalObj.CanCollide = false
portalObj.CanTouch = true
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 por Toque com Recarga de 2 Segundos
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
hrp.CFrame = destCFrame * CFrame.new(0, 0, -4)
task.wait(2)
cooldownTeleport = false
end
end
end
end)
end
end
aplicarGatilho(portal1, function() return portal2 end)
aplicarGatilho(portal2, function() return portal1 end)
end
-- Disparo da Bola Roxa com Cronômetro Máximo de 3 Segundos
local function dispararBolaRoxa(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(140, 0, 255)
bola.Material = Enum.Material.Neon
bola.CanCollide = true
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
local impactoProcessado = false
local conect = nil
local function criarPortalNoImpacto(hitCFrame)
if impactoProcessado then return end
impactoProcessado = true
if conect then
conect:Disconnect()
end
if bola and bola.Parent then
bola:Destroy()
end
if etapa == 1 then
if portal1 then portal1:Destroy() end
portal1 = carregarModeloPortal(hitCFrame, NOME_PORTAL_1)
elseif etapa == 2 then
if portal2 then portal2:Destroy() end
portal2 = carregarModeloPortal(hitCFrame, NOME_PORTAL_2)
configurarGatilhosDeTeleport()
end
executandoDisparo = false
end
-- Timer limite de 3 segundos para spawnar o portal caso dispare no céu
task.delay(3, function()
if not impactoProcessado and bola and bola.Parent then
local finalCFrame = CFrame.new(bola.Position, bola.Position + direction)
criarPortalNoImpacto(finalCFrame)
end
end)
bola.Touched:Connect(function(hit)
if hit and not hit:IsDescendantOf(char) and hit.Name ~= NOME_PORTAL_1 and hit.Name ~= NOME_PORTAL_2 then
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {char, bola}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local result = Workspace:Raycast(bola.Position, direction * 5, raycastParams)
local surfaceNormal = result and result.Normal or Vector3.new(0, 1, 0)
local hitPos = result and result.Position or bola.Position
local finalCFrame = CFrame.new(hitPos + (surfaceNormal * 0.5), hitPos + surfaceNormal) * CFrame.Angles(math.rad(90), 0, 0)
criarPortalNoImpacto(finalCFrame)
end
end)
conect = game:GetService("RunService").Heartbeat:Connect(function()
if impactoProcessado or not bola or not bola.Parent then
if conect then conect:Disconnect() end
return
end
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {char, bola}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local result = Workspace:Raycast(bola.Position, direction * 4, raycastParams)
if result then
if conect then conect:Disconnect() end
local finalCFrame = CFrame.new(result.Position + (result.Normal * 0.5), result.Position + result.Normal) * CFrame.Angles(math.rad(90), 0, 0)
criarPortalNoImpacto(finalCFrame)
end
end)
end
-- Processador da Ação
local function processarClique()
if executandoDisparo then return end
cliqueCount = cliqueCount + 1
if cliqueCount == 1 then
executandoDisparo = true
dispararBolaRoxa(1)
elseif cliqueCount == 2 then
executandoDisparo = true
dispararBolaRoxa(2)
elseif cliqueCount >= 3 then
if portal1 then portal1:Destroy() portal1 = nil end
if portal2 then portal2:Destroy() portal2 = nil end
cliqueCount = 0
end
end
-- Criador da Tool
local function criarPortalGun()
local backpack = LocalPlayer:WaitForChild("Backpack")
local character = LocalPlayer.Character or LocalPlayer.CharacterAdded:Wait()
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)
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
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)
tool.Activated:Connect(function()
processarClique()
end)
tool.Unequipped:Connect(function()
if modelo3D then
modelo3D:Destroy()
modelo3D = nil
end
end)
end
-- Limpeza e Verificação de Portais
local function verificarELimparPortais()
local pGui = LocalPlayer:WaitForChild("PlayerGui")
local portaisEncontrados = {}
for _, obj in ipairs(Workspace:GetChildren()) do
if obj.Name == NOME_PORTAL_1 or obj.Name == NOME_PORTAL_2 or obj.Name == "Portal1" or obj.Name == "Portal2" then
table.insert(portaisEncontrados, obj)
end
end
local totalPortais = #portaisEncontrados
local redGui = Instance.new("ScreenGui")
redGui.Name = "RedPortalCheckGUI"
redGui.ResetOnSpawn = false
redGui.Parent = pGui
local frameRed = Instance.new("Frame")
frameRed.Size = UDim2.new(0, 220, 0, 70)
frameRed.Position = UDim2.new(0.5, -110, 0.5, -35)
frameRed.BackgroundColor3 = Color3.fromRGB(180, 40, 40)
frameRed.BorderSizePixel = 0
frameRed.Parent = redGui
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 8)
corner.Parent = frameRed
local lblStatus = Instance.new("TextLabel")
lblStatus.Size = UDim2.new(1, 0, 1, 0)
lblStatus.BackgroundTransparency = 1
lblStatus.Text = "Verificando Portais... 0/" .. totalPortais
lblStatus.TextColor3 = Color3.fromRGB(255, 255, 255)
lblStatus.TextSize = 16
lblStatus.Font = Enum.Font.SourceSansBold
lblStatus.Parent = frameRed
task.wait(0.5)
if totalPortais > 0 then
for i, pObj in ipairs(portaisEncontrados) do
lblStatus.Text = "Limpando Portais... " .. i .. "/" .. totalPortais
pObj:Destroy()
task.wait(0.5)
end
end
redGui:Destroy()
criarPortalGun()
end
-- Janela Principal (GUI)
local function iniciarGUI()
mostrarNotificacaoDireita()
local pGui = LocalPlayer:WaitForChild("PlayerGui")
local mainGui = Instance.new("ScreenGui")
mainGui.Name = "PortalGunMainGUI"
mainGui.ResetOnSpawn = false
mainGui.Parent = pGui
local frame = Instance.new("Frame")
frame.Size = UDim2.new(0, 320, 0, 180)
frame.Position = UDim2.new(0.5, -160, 0.5, -90)
frame.BackgroundColor3 = Color3.fromRGB(35, 35, 35)
frame.BorderSizePixel = 0
frame.Parent = mainGui
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 10)
corner.Parent = frame
local title = Instance.new("TextLabel")
title.Size = UDim2.new(1, 0, 0, 40)
title.BackgroundTransparency = 1
title.Text = "Portal gun foi iniciado você está na versão 1.2"
title.TextColor3 = Color3.fromRGB(255, 255, 255)
title.TextSize = 13
title.Font = Enum.Font.SourceSansBold
title.Parent = frame
local bugs = Instance.new("TextLabel")
bugs.Size = UDim2.new(1, 0, 0, 50)
bugs.Position = UDim2.new(0, 0, 0, 40)
bugs.BackgroundTransparency = 1
bugs.Text = "Bugs consertados✅\nÍcone no inventário alterado✅"
bugs.TextColor3 = Color3.fromRGB(180, 255, 180)
bugs.TextSize = 14
bugs.Font = Enum.Font.SourceSansBold
bugs.Parent = frame
local btnOk = Instance.new("TextButton")
btnOk.Size = UDim2.new(0, 100, 0, 35)
btnOk.Position = UDim2.new(0.5, -50, 1, -45)
btnOk.BackgroundColor3 = Color3.fromRGB(0, 150, 255)
btnOk.Text = "OK"
btnOk.TextColor3 = Color3.fromRGB(255, 255, 255)
btnOk.Font = Enum.Font.SourceSansBold
btnOk.TextSize = 16
btnOk.Parent = frame
local btnCorner = Instance.new("UICorner")
btnCorner.CornerRadius = UDim.new(0, 6)
btnCorner.Parent = btnOk
btnOk.MouseButton1Click:Connect(function()
mainGui:Destroy()
verificarELimparPortais()
end)
end
-- Execução do Script
iniciarGUI()No comments yet for this script.



